chiark / gitweb /
try rental for lib load guard, nice
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 27 Sep 2020 11:29:06 +0000 (12:29 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 27 Sep 2020 11:29:06 +0000 (12:29 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/global.rs
src/imports.rs
src/shapelib.rs

index 341008d6d0219d3a8963c7655bc641dcb51b287e..cee4af1f24374be643c642dbf1df07e35c793e2d 100644 (file)
@@ -178,7 +178,7 @@ pub struct Global {
   config  : RwLock<Arc<ServerConfig>>,
   dirty   : Mutex<VecDeque<InstanceRef>>,
   save_area_lock : Mutex<Option<File>>,
-  pub shapelibs : RwLock<HashMap<String,shapelib::Contents>>,
+  pub shapelibs : RwLock<shapelib::Registry>,
 }
 
 #[derive(Debug)]
index 943632e53829ab468041c70ed17f7a7fcb7b6f0d..f70e8fed693c31f18584953e7308190295e72639 100644 (file)
@@ -10,7 +10,7 @@ pub use std::fmt::Formatter;
 pub use std::fmt::{self,Display,Debug};
 pub use std::thread;
 pub use std::time::Duration;
-pub use std::sync::{Arc,Mutex,MutexGuard,RwLock,Condvar};
+pub use std::sync::{Arc,Mutex,MutexGuard,RwLock,RwLockReadGuard,Condvar};
 pub use std::collections::{HashMap,hash_map,HashSet};
 pub use std::borrow::Borrow;
 pub use std::convert::{TryFrom,TryInto};
index 0d9dd1640f2d2fa30fbce237497bfa258633eae6..73ad3c7b3668df6bb0e5d2016236983cfc4dcec8 100644 (file)
@@ -11,6 +11,8 @@ pub use crate::imports::*;
 //  Item           } once loaded and part of a game,
 //  Outline        }  no Arc's as we serialise/deserialize during save/load
 
+pub type Registry = HashMap<String,shapelib::Contents>;
+
 #[derive(Debug)]
 pub struct Contents {
   libname: String,
@@ -184,11 +186,20 @@ impl Piece for Item {
   fn itemname(&self) -> &str { &self.itemname }
 }
 
+use rental::common::RentRef;
+
+#[throws(SpecError)]
+pub fn libs_lookup(libname: &str) -> RentRef<RwLockReadGuard<'static, Registry>, Contents> {
+  let libs = GLOBAL.shapelibs.read().unwrap();
+  RentRef::try_new(libs,|libs|Ok({
+    libs.get(libname).ok_or(SE::LibraryNotFound)?
+  })).map_err::<SpecError,_>(|e:rental::RentalError<_,_>|e.0)?
+}
+
 impl ItemSpec {
   #[throws(SpecError)]
   pub fn load(&self) -> Box<dyn Piece> {
-    let libs = GLOBAL.shapelibs.read().unwrap(); 
-    let lib = libs.get(&self.lib).ok_or(SE::LibraryNotFound)?;
+    let lib = libs_lookup(&self.lib)?;
     let idata = lib.items.get(&self.item).ok_or(SE::LibraryItemNotFound)?;
     lib.load1(idata, &self.item)?
   }