small fixes, std implies alloc, dropguarded wrapper with dropguard
This commit is contained in:
parent
f23f815708
commit
4f1e4b1672
|
@ -6,7 +6,7 @@ edition = "2024"
|
|||
[features]
|
||||
default = ["alloc"]
|
||||
alloc = []
|
||||
std = []
|
||||
std = ["alloc"]
|
||||
nightly = []
|
||||
|
||||
[dependencies]
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
use core::{cell::UnsafeCell, mem::ManuallyDrop};
|
||||
use core::{
|
||||
cell::UnsafeCell,
|
||||
mem::ManuallyDrop,
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
|
||||
/// A guard that runs a closure when it is dropped.
|
||||
pub struct DropGuard<F: FnOnce()>(UnsafeCell<ManuallyDrop<F>>);
|
||||
|
@ -10,6 +14,10 @@ where
|
|||
pub fn new(f: F) -> DropGuard<F> {
|
||||
Self(UnsafeCell::new(ManuallyDrop::new(f)))
|
||||
}
|
||||
|
||||
pub fn guard<T>(self, t: T) -> DropGuarded<T, F> {
|
||||
DropGuarded(t, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F> Drop for DropGuard<F>
|
||||
|
@ -32,3 +40,45 @@ where
|
|||
DropGuard::new(f)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DropGuarded<T, F: FnOnce()>(T, DropGuard<F>);
|
||||
|
||||
impl<T, F> DropGuarded<T, F>
|
||||
where
|
||||
F: FnOnce(),
|
||||
{
|
||||
pub fn new(value: T, f: F) -> Self {
|
||||
Self(value, DropGuard::new(f))
|
||||
}
|
||||
|
||||
pub fn into_inner(self) -> T {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn map<U, G>(self, f: G) -> DropGuarded<U, F>
|
||||
where
|
||||
G: FnOnce(T) -> U,
|
||||
{
|
||||
DropGuarded(f(self.0), self.1)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, F> Deref for DropGuarded<T, F>
|
||||
where
|
||||
F: FnOnce(),
|
||||
{
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, F> DerefMut for DropGuarded<T, F>
|
||||
where
|
||||
F: FnOnce(),
|
||||
{
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
|
12
src/sync.rs
12
src/sync.rs
|
@ -46,6 +46,8 @@ impl Lock {
|
|||
}
|
||||
|
||||
pub fn unlock(&self) {
|
||||
// use release semantics to ensure that all previous writes are
|
||||
// available to other threads.
|
||||
self.inner.fetch_and(!LOCKED_BIT, Ordering::Release);
|
||||
}
|
||||
|
||||
|
@ -115,6 +117,16 @@ impl Lock {
|
|||
state = self.inner.load(Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wait(&self) {
|
||||
let state = self.inner.load(Ordering::Acquire);
|
||||
atomic_wait::wait(&self.inner, state);
|
||||
}
|
||||
|
||||
pub fn wake_one(&self) {
|
||||
// Notify one thread waiting on this lock.
|
||||
atomic_wait::wake_one(&self.inner);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SpinWait {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use core::ops::{Deref, DerefMut};
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Send<T>(pub(self) T);
|
||||
#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, Copy)]
|
||||
pub struct Send<T>(pub T);
|
||||
|
||||
unsafe impl<T> core::marker::Send for Send<T> {}
|
||||
|
||||
|
@ -22,6 +23,9 @@ impl<T> Send<T> {
|
|||
pub unsafe fn new(value: T) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
pub fn into_inner(self) -> T {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// returns the number of available hardware threads, or 1 if it cannot be determined.
|
||||
|
|
Loading…
Reference in a new issue