Skip to content

Commit c7635e0

Browse files
committed
feature(fiber::cond): unsafe WeakCond
1 parent 58db7df commit c7635e0

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

tarantool/src/fiber.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use std::cell::UnsafeCell;
1313
use std::ffi::CString;
1414
use std::marker::PhantomData;
15+
use std::mem::ManuallyDrop;
1516
use std::os::raw::c_void;
1617
use std::ptr::NonNull;
1718
use std::time::Duration;
@@ -1343,6 +1344,10 @@ impl Drop for FiberAttr {
13431344
}
13441345
}
13451346

1347+
////////////////////////////////////////////////////////////////////////////////
1348+
/// Cond
1349+
////////////////////////////////////////////////////////////////////////////////
1350+
13461351
/// Conditional variable for cooperative multitasking (fibers).
13471352
///
13481353
/// A cond (short for "condition variable") is a synchronization primitive
@@ -1422,6 +1427,17 @@ impl Cond {
14221427
pub fn wait(&self) -> bool {
14231428
unsafe { ffi::fiber_cond_wait(self.inner) >= 0 }
14241429
}
1430+
1431+
/// Create a non owning reference to the underlying conditional variable.
1432+
///
1433+
/// Accessing the functionality through `WeakCond` is unsafe as there's no
1434+
/// mechanism to check that the owning instance was dropped, so use it at
1435+
/// your own risk.
1436+
pub fn weak(&self) -> WeakCond {
1437+
WeakCond {
1438+
inner: ManuallyDrop::new(Self { inner: self.inner })
1439+
}
1440+
}
14251441
}
14261442

14271443
impl Default for Cond {
@@ -1436,6 +1452,38 @@ impl Drop for Cond {
14361452
}
14371453
}
14381454

1455+
/// A non owning wrapper around a [`Cond`] that doesn't delete the underlying
1456+
/// object when dropped. This type is meant for extreme efficiency and is unsafe
1457+
/// to use, as there's no way of checking if the original `Cond` is dropped, so
1458+
/// only use this if you know what you're doing.
1459+
///
1460+
/// Consider using `&Cond` or `[`Rc`]`<Cond>` instead.
1461+
///
1462+
/// [`Rc`]: std::rc::Rc
1463+
pub struct WeakCond {
1464+
inner: ManuallyDrop<Cond>,
1465+
}
1466+
1467+
impl WeakCond {
1468+
/// Get a reference to the owning `Cond` instance.
1469+
///
1470+
/// # Safety
1471+
/// This is unsafe, because there's no mechanism of checking that the owning
1472+
/// instance wasn't already dropped. Only use this if you're absolutely sure
1473+
/// the main [`Cond`] outlives this reference.
1474+
///
1475+
/// Consider using `&Cond` or `[`Rc`]`<Cond>` instead.
1476+
///
1477+
/// [`Rc`]: std::rc::Rc
1478+
pub unsafe fn get(&self) -> &Cond {
1479+
&self.inner
1480+
}
1481+
}
1482+
1483+
////////////////////////////////////////////////////////////////////////////////
1484+
/// Latch
1485+
////////////////////////////////////////////////////////////////////////////////
1486+
14391487
/// A lock for cooperative multitasking environment
14401488
#[derive(Debug)]
14411489
pub struct Latch {

0 commit comments

Comments
 (0)