From: Ian Jackson Date: Sun, 27 Sep 2020 11:29:06 +0000 (+0100) Subject: try rental for lib load guard, nice X-Git-Tag: otter-0.2.0~862 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=7261c3faf0a6607a887b4b5e2d8b2758f8d37ffb;p=otter.git try rental for lib load guard, nice Signed-off-by: Ian Jackson --- diff --git a/src/global.rs b/src/global.rs index 341008d6..cee4af1f 100644 --- a/src/global.rs +++ b/src/global.rs @@ -178,7 +178,7 @@ pub struct Global { config : RwLock>, dirty : Mutex>, save_area_lock : Mutex>, - pub shapelibs : RwLock>, + pub shapelibs : RwLock, } #[derive(Debug)] diff --git a/src/imports.rs b/src/imports.rs index 943632e5..f70e8fed 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -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}; diff --git a/src/shapelib.rs b/src/shapelib.rs index 0d9dd164..73ad3c7b 100644 --- a/src/shapelib.rs +++ b/src/shapelib.rs @@ -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; + #[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, Contents> { + let libs = GLOBAL.shapelibs.read().unwrap(); + RentRef::try_new(libs,|libs|Ok({ + libs.get(libname).ok_or(SE::LibraryNotFound)? + })).map_err::(|e:rental::RentalError<_,_>|e.0)? +} + impl ItemSpec { #[throws(SpecError)] pub fn load(&self) -> Box { - 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)? }