chiark / gitweb /
destroy game
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 31 Oct 2020 13:09:51 +0000 (13:09 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 31 Oct 2020 13:09:51 +0000 (13:09 +0000)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/cmdlistener.rs
src/global.rs

index 8480d0edbdef6afa8049d4e2140207a7702e4101..ca5d23f46724ce7f83b32397e11e6c7c9f8a3e7a 100644 (file)
@@ -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)?;
index 63abd4751fa0f1aaff3d2ff31c84f9d63783575f..6ff438c944191c460087446860429feae859fbb2 100644 (file)
@@ -263,7 +263,7 @@ impl InstanceRef {
     InstanceGuard { c, gref: self.clone() }
   }
 
-  fn lock_even_poisoned(&self) -> MutexGuard<InstanceContainer> {
+  pub fn lock_even_poisoned(&self) -> MutexGuard<InstanceContainer> {
     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<InstanceName>) {
-    let a_savefile = savefilename(&g.name, "a-", "");
+  pub fn destroy_game(mut g: MutexGuard<InstanceContainer>,
+                      _: Authorisation<InstanceName>) {
+    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: