From: Ian Jackson Date: Sat, 31 Oct 2020 13:09:51 +0000 (+0000) Subject: destroy game X-Git-Tag: otter-0.2.0~576 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=352ba5ca3a711d4afb0b36db31e483333d3305b6;p=otter.git destroy game Signed-off-by: Ian Jackson --- diff --git a/src/cmdlistener.rs b/src/cmdlistener.rs index 8480d0ed..ca5d23f4 100644 --- a/src/cmdlistener.rs +++ b/src/cmdlistener.rs @@ -140,7 +140,7 @@ fn execute(cs: &mut CommandStream, cmd: MgmtCommand) -> MgmtResponse { CreateGame { game, insns } => { let ag = AccountsGuard::lock(); - let authorised = authorise_by_account(cs, &ag, &game)?; + let auth = authorise_by_account(cs, &ag, &game)?; let gs = crate::gamestate::GameState { table_size : DEFAULT_TABLE_SIZE, @@ -152,14 +152,15 @@ fn execute(cs: &mut CommandStream, cmd: MgmtCommand) -> MgmtResponse { }; let acl = default(); - let gref = Instance::new(game, gs, acl, authorised)?; + let gref = Instance::new(game, gs, acl, auth)?; let ig = gref.lock()?; execute_for_game(cs, &ag, &mut Unauthorised::of(ig), insns, MgmtGameUpdateMode::Bulk) .map_err(|e|{ let name = ig.name.clone(); - Instance::destroy_game(ig, authorised) + let InstanceGuard { c, .. } = ig; + Instance::destroy_game(c, auth) .unwrap_or_else(|e| warn!( "failed to tidy up failecd creation of {:?}: {:?}", &name, &e @@ -192,6 +193,15 @@ fn execute(cs: &mut CommandStream, cmd: MgmtCommand) -> MgmtResponse { execute_for_game(cs, &ag, &mut g, insns, how)? }, + DestroyGame { game } => { + let ag = AccountsGuard::lock(); + let auth = authorise_by_account(cs, &ag, &game)?; + let gref = Instance::lookup_by_name(&game, auth)?; + let ig = gref.lock_even_poisoned(); + Instance::destroy_game(ig, auth)?; + Fine + } + LibraryListByGlob { glob: spec } => { let lib = shapelib::libs_lookup(&spec.lib)?; let results = lib.list_glob(&spec.item)?; diff --git a/src/global.rs b/src/global.rs index 63abd475..6ff438c9 100644 --- a/src/global.rs +++ b/src/global.rs @@ -263,7 +263,7 @@ impl InstanceRef { InstanceGuard { c, gref: self.clone() } } - fn lock_even_poisoned(&self) -> MutexGuard { + pub fn lock_even_poisoned(&self) -> MutexGuard { match self.0.lock() { Ok(g) => g, Err(poison) => poison.into_inner(), @@ -349,19 +349,20 @@ impl Instance { } #[throws(InternalError)] - pub fn destroy_game(mut g: InstanceGuard, _: Authorisation) { - let a_savefile = savefilename(&g.name, "a-", ""); + pub fn destroy_game(mut g: MutexGuard, + _: Authorisation) { + let a_savefile = savefilename(&g.g.name, "a-", ""); let mut gw = GLOBAL.games.write().unwrap(); // xxx lock order wrong, this function should unlock and then relock - let g_file = savefilename(&g.name, "g-", ""); + let g_file = savefilename(&g.g.name, "g-", ""); fs::remove_file(&g_file).context("remove").context(g_file)?; (||{ // Infallible: - g.c.live = false; - gw.remove(&g.name); - InstanceGuard::forget_all_tokens(&mut g.tokens_clients); - InstanceGuard::forget_all_tokens(&mut g.tokens_players); + g.live = false; + gw.remove(&g.g.name); + InstanceGuard::forget_all_tokens(&mut g.g.tokens_clients); + InstanceGuard::forget_all_tokens(&mut g.g.tokens_players); })(); // <- No ?, ensures that IEFE is infallible (barring panics) (||{ // Best effort: