Loading crates/arti-client/src/client.rs +8 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ use std::sync::{Arc, Mutex, Weak}; use std::time::Duration; use crate::err::ErrorDetail; use crate::{status, TorClientBuilder}; use crate::{status, util, TorClientBuilder}; #[cfg(feature = "async-std")] use tor_rtcompat::async_std::PreferredRuntime as PreferredAsyncStdRuntime; #[cfg(feature = "tokio")] Loading Loading @@ -472,11 +472,18 @@ impl<R: Runtime> TorClient<R> { ); } // If we fail to bootstrap (i.e. we return before the disarm() point below), attempt to // unlock the state files. let unlock_guard = util::StateMgrUnlockGuard::new(&self.statemgr); self.dirmgr.bootstrap().await?; self.circmgr .update_network_parameters(self.dirmgr.netdir()?.params()); // Since we succeeded, disarm the unlock guard. unlock_guard.disarm(); Ok(()) } Loading crates/arti-client/src/lib.rs +1 −0 Original line number Diff line number Diff line Loading @@ -192,6 +192,7 @@ mod address; mod builder; mod client; mod util; pub mod config; pub mod status; Loading crates/arti-client/src/util.rs 0 → 100644 +29 −0 Original line number Diff line number Diff line //! Utility functions for the rest of the crate. use tor_persist::StateMgr; use tracing::error; /// A RAII guard that calls `<T as StateMgr>::unlock` on drop. pub(crate) struct StateMgrUnlockGuard<'a, T: StateMgr + 'a> { /// The inner manager. mgr: &'a T, } impl<'a, T: StateMgr + 'a> Drop for StateMgrUnlockGuard<'a, T> { fn drop(&mut self) { if let Err(e) = self.mgr.unlock() { error!("Failed to unlock state manager: {}", e); } } } impl<'a, T: StateMgr + 'a> StateMgrUnlockGuard<'a, T> { /// Create an unlock guard. pub(crate) fn new(mgr: &'a T) -> Self { Self { mgr } } /// Consume the unlock guard without unlocking the state manager. pub(crate) fn disarm(self) { std::mem::forget(self); } } crates/tor-persist/src/fs.rs +11 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,17 @@ impl StateMgr for FsStateMgr { Ok(LockStatus::NoLock) } } fn unlock(&self) -> Result<()> { let mut lockfile = self .inner .lockfile .lock() .expect("Poisoned lock on state lockfile"); if lockfile.owns_lock() { lockfile.unlock()?; } Ok(()) } fn load<D>(&self, key: &str) -> Result<Option<D>> where D: DeserializeOwned, Loading crates/tor-persist/src/lib.rs +4 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,10 @@ pub trait StateMgr: Clone { /// `[StateMgr::can_store()`] to see if the lock is held. fn try_lock(&self) -> Result<LockStatus>; /// Release any locks held and become a read-only state manager /// again. If no locks were held, do nothing. fn unlock(&self) -> Result<()>; /// Make a new [`StorageHandle`] to store values of particular type /// at a particular key. fn create_handle<T>(self, key: impl Into<String>) -> DynStorageHandle<T> Loading Loading
crates/arti-client/src/client.rs +8 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ use std::sync::{Arc, Mutex, Weak}; use std::time::Duration; use crate::err::ErrorDetail; use crate::{status, TorClientBuilder}; use crate::{status, util, TorClientBuilder}; #[cfg(feature = "async-std")] use tor_rtcompat::async_std::PreferredRuntime as PreferredAsyncStdRuntime; #[cfg(feature = "tokio")] Loading Loading @@ -472,11 +472,18 @@ impl<R: Runtime> TorClient<R> { ); } // If we fail to bootstrap (i.e. we return before the disarm() point below), attempt to // unlock the state files. let unlock_guard = util::StateMgrUnlockGuard::new(&self.statemgr); self.dirmgr.bootstrap().await?; self.circmgr .update_network_parameters(self.dirmgr.netdir()?.params()); // Since we succeeded, disarm the unlock guard. unlock_guard.disarm(); Ok(()) } Loading
crates/arti-client/src/lib.rs +1 −0 Original line number Diff line number Diff line Loading @@ -192,6 +192,7 @@ mod address; mod builder; mod client; mod util; pub mod config; pub mod status; Loading
crates/arti-client/src/util.rs 0 → 100644 +29 −0 Original line number Diff line number Diff line //! Utility functions for the rest of the crate. use tor_persist::StateMgr; use tracing::error; /// A RAII guard that calls `<T as StateMgr>::unlock` on drop. pub(crate) struct StateMgrUnlockGuard<'a, T: StateMgr + 'a> { /// The inner manager. mgr: &'a T, } impl<'a, T: StateMgr + 'a> Drop for StateMgrUnlockGuard<'a, T> { fn drop(&mut self) { if let Err(e) = self.mgr.unlock() { error!("Failed to unlock state manager: {}", e); } } } impl<'a, T: StateMgr + 'a> StateMgrUnlockGuard<'a, T> { /// Create an unlock guard. pub(crate) fn new(mgr: &'a T) -> Self { Self { mgr } } /// Consume the unlock guard without unlocking the state manager. pub(crate) fn disarm(self) { std::mem::forget(self); } }
crates/tor-persist/src/fs.rs +11 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,17 @@ impl StateMgr for FsStateMgr { Ok(LockStatus::NoLock) } } fn unlock(&self) -> Result<()> { let mut lockfile = self .inner .lockfile .lock() .expect("Poisoned lock on state lockfile"); if lockfile.owns_lock() { lockfile.unlock()?; } Ok(()) } fn load<D>(&self, key: &str) -> Result<Option<D>> where D: DeserializeOwned, Loading
crates/tor-persist/src/lib.rs +4 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,10 @@ pub trait StateMgr: Clone { /// `[StateMgr::can_store()`] to see if the lock is held. fn try_lock(&self) -> Result<LockStatus>; /// Release any locks held and become a read-only state manager /// again. If no locks were held, do nothing. fn unlock(&self) -> Result<()>; /// Make a new [`StorageHandle`] to store values of particular type /// at a particular key. fn create_handle<T>(self, key: impl Into<String>) -> DynStorageHandle<T> Loading