chiark / gitweb /
fixes
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 23 Aug 2020 00:06:57 +0000 (01:06 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 23 Aug 2020 00:07:07 +0000 (01:07 +0100)
.gitignore
src/global.rs
src/imports.rs

index b1df170dfa9476a09b88fbb0107819671450d0a8..81a69249808705bc00e651b6613496169b92025c 100644 (file)
@@ -1 +1,2 @@
 templates/script.js
+save/lock
index ac40901af3b4ee467b1f2f27517628fe5299288e..9bbcf90a9536ca5bf3e78693f7c844b8d7d4e14d 100644 (file)
@@ -143,6 +143,7 @@ struct Global {
   players : RwLock<TokenTable<PlayerId>>,
   clients : RwLock<TokenTable<ClientId>>,
   config  : RwLock<Arc<ServerConfig>>,
+  save_area_lock : Mutex<Option<File>>,
   // xxx delete clients at some point!
 }
 
@@ -606,9 +607,20 @@ impl InstanceGuard<'_> {
     rmp_serde::decode::from_read(&mut f)?
   }
 
-  #[throws(OE)]
+  #[throws(StartupError)]
   pub fn load(name: InstanceName) -> InstanceRef {
-    // xxx should take a file lock on save area
+    {
+      let mut st = GLOBAL.save_area_lock.lock().unwrap();
+      let st = &mut *st;
+      if st.is_none() {
+        let lockfile = format!("{}/lock", config().save_directory);
+        *st = Some((||{
+          let file = File::create(&lockfile).context("open")?;
+          file.try_lock_exclusive().context("lock")?;
+          Ok::<_,AE>(file)
+        })().context(lockfile).context("lock global save area")?);
+      }
+    }
     // xxx check for deleted players, throw their tokens away
     let gs = {
       let mut gs : GameState = Self::load_something(&name, "g-")?;
index c1959f717168ca8faa5a648f208aaec72bf4115e..5700f367f92d2aa3c4b7647b458bbb9849f216ac 100644 (file)
@@ -61,6 +61,8 @@ pub use index_vec::{define_index_type,index_vec,IndexVec,IndexSlice};
 
 pub use vecdeque_stableix::StableIndexVecDeque;
 
+pub use fs2::FileExt;
+
 pub use crate::global::*;
 pub use crate::gamestate::*;
 pub use crate::pieces::*;