Skip to content

Commit

Permalink
feature(fiber::cond): unsafe WeakCond
Browse files Browse the repository at this point in the history
  • Loading branch information
gmoshkin committed Apr 8, 2022
1 parent 58db7df commit c7635e0
Showing 1 changed file with 48 additions and 0 deletions.
48 changes: 48 additions & 0 deletions tarantool/src/fiber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use std::cell::UnsafeCell;
use std::ffi::CString;
use std::marker::PhantomData;
use std::mem::ManuallyDrop;
use std::os::raw::c_void;
use std::ptr::NonNull;
use std::time::Duration;
Expand Down Expand Up @@ -1343,6 +1344,10 @@ impl Drop for FiberAttr {
}
}

////////////////////////////////////////////////////////////////////////////////
/// Cond
////////////////////////////////////////////////////////////////////////////////

/// Conditional variable for cooperative multitasking (fibers).
///
/// A cond (short for "condition variable") is a synchronization primitive
Expand Down Expand Up @@ -1422,6 +1427,17 @@ impl Cond {
pub fn wait(&self) -> bool {
unsafe { ffi::fiber_cond_wait(self.inner) >= 0 }
}

/// Create a non owning reference to the underlying conditional variable.
///
/// Accessing the functionality through `WeakCond` is unsafe as there's no
/// mechanism to check that the owning instance was dropped, so use it at
/// your own risk.
pub fn weak(&self) -> WeakCond {
WeakCond {
inner: ManuallyDrop::new(Self { inner: self.inner })
}
}
}

impl Default for Cond {
Expand All @@ -1436,6 +1452,38 @@ impl Drop for Cond {
}
}

/// A non owning wrapper around a [`Cond`] that doesn't delete the underlying
/// object when dropped. This type is meant for extreme efficiency and is unsafe
/// to use, as there's no way of checking if the original `Cond` is dropped, so
/// only use this if you know what you're doing.
///
/// Consider using `&Cond` or `[`Rc`]`<Cond>` instead.
///
/// [`Rc`]: std::rc::Rc
pub struct WeakCond {
inner: ManuallyDrop<Cond>,
}

impl WeakCond {
/// Get a reference to the owning `Cond` instance.
///
/// # Safety
/// This is unsafe, because there's no mechanism of checking that the owning
/// instance wasn't already dropped. Only use this if you're absolutely sure
/// the main [`Cond`] outlives this reference.
///
/// Consider using `&Cond` or `[`Rc`]`<Cond>` instead.
///
/// [`Rc`]: std::rc::Rc
pub unsafe fn get(&self) -> &Cond {
&self.inner
}
}

////////////////////////////////////////////////////////////////////////////////
/// Latch
////////////////////////////////////////////////////////////////////////////////

/// A lock for cooperative multitasking environment
#[derive(Debug)]
pub struct Latch {
Expand Down

0 comments on commit c7635e0

Please sign in to comment.