Struct corundum::stm::Chaperon [−][src]
pub struct Chaperon { /* fields omitted */ }
A third-party observer for multi-pool transactions
It provides an atomic supper transaction (a session
) for manipulating
persistent data in multiple pools, atomically. The involved pools go to a
transient state when they call transaction inside a chaperoned session
.
The finalization functions (e.g. commit
or rollback
) are delayed
until the end of the session
. To keep track of pools’ states, it creates
a chaperon file with necessary information for recovering them, in case of a
crash.
Implementations
impl Chaperon
[src]
pub unsafe fn load(filename: &str) -> Result<&'static mut Self>
[src]
Loads a chaperon file
pub fn filename(&self) -> &str
[src]
Returns the chaperon filename
pub fn session<T, F: FnOnce() -> T>(filename: &str, body: F) -> Result<T> where
F: UnwindSafe,
T: UnwindSafe + TxOutSafe,
[src]
F: UnwindSafe,
T: UnwindSafe + TxOutSafe,
Starts a chaperoned session
It creates a chaperoned session in which multiple pools can start a
transaction
. The transactions won’t be finalized until the session
ends. A chaperon file keeps the necessary information for recovering the
involved pools. If the operation is successful, it returns a value of
type T
.
Safety
- In case of a crash, the involved pools are not individually recoverable on the absence of the chaperon file.
- Chaperoned sessions cannot be nested.
Examples
use corundum::alloc::heap::*; use corundum::stm::{Chaperon, Journal}; use corundum::cell::{PCell, RootObj}; use corundum::boxed::Pbox; corundum::pool!(pool1); corundum::pool!(pool2); type P1 = pool1::BuddyAlloc; type P2 = pool2::BuddyAlloc; struct Root<M: MemPool> { val: Pbox<PCell<i32, M>, M> } impl<M: MemPool> RootObj<M> for Root<M> { fn init(j: &Journal<M>) -> Self { Root { val: Pbox::new(PCell::new(0), j) } } } let root1 = P1::open::<Root<P1>>("pool1.pool", O_CF).unwrap(); let root2 = P2::open::<Root<P2>>("pool2.pool", O_CF).unwrap(); let _=Chaperon::session("chaperon.pool", || { let v = P2::transaction(|j| { let old = root2.val.get(); root2.val.set(old+1, j); // <-- should persist if both transactions commit old // <-- Send out p2's old data }).unwrap(); P1::transaction(|j| { let mut p1 = root1.val.get(); root1.val.set(p1+v, j); }).unwrap(); }).unwrap(); // <-- both transactions commit here let v1 = root1.val.get(); let v2 = root2.val.get(); println!("root1 = {}", v1); println!("root2 = {}", v2); assert_eq!(v1, calc(v2-1)); fn calc(n: i32) -> i32 { if n < 1 { 0 } else { n + calc(n-1) } }
Trait Implementations
impl Debug for Chaperon
[src]
impl Drop for Chaperon
[src]
impl RefUnwindSafe for Chaperon
[src]
impl Send for Chaperon
[src]
impl Sync for Chaperon
[src]
impl TxInSafe for Chaperon
[src]
impl !TxOutSafe for Chaperon
[src]
impl UnwindSafe for Chaperon
[src]
Auto Trait Implementations
impl LooseTxInUnsafe for Chaperon
impl !PSafe for Chaperon
impl PSend for Chaperon
impl Unpin for Chaperon
impl VSafe for Chaperon
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
pub fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
V: MultiLane<T>,