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]
|
[features]
|
||||||
default = ["alloc"]
|
default = ["alloc"]
|
||||||
alloc = []
|
alloc = []
|
||||||
std = []
|
std = ["alloc"]
|
||||||
nightly = []
|
nightly = []
|
||||||
|
|
||||||
[dependencies]
|
[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.
|
/// A guard that runs a closure when it is dropped.
|
||||||
pub struct DropGuard<F: FnOnce()>(UnsafeCell<ManuallyDrop<F>>);
|
pub struct DropGuard<F: FnOnce()>(UnsafeCell<ManuallyDrop<F>>);
|
||||||
|
@ -10,6 +14,10 @@ where
|
||||||
pub fn new(f: F) -> DropGuard<F> {
|
pub fn new(f: F) -> DropGuard<F> {
|
||||||
Self(UnsafeCell::new(ManuallyDrop::new(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>
|
impl<F> Drop for DropGuard<F>
|
||||||
|
@ -32,3 +40,45 @@ where
|
||||||
DropGuard::new(f)
|
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) {
|
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);
|
self.inner.fetch_and(!LOCKED_BIT, Ordering::Release);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +117,16 @@ impl Lock {
|
||||||
state = self.inner.load(Ordering::Relaxed);
|
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 {
|
pub struct SpinWait {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[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> {}
|
unsafe impl<T> core::marker::Send for Send<T> {}
|
||||||
|
|
||||||
|
@ -22,6 +23,9 @@ impl<T> Send<T> {
|
||||||
pub unsafe fn new(value: T) -> Self {
|
pub unsafe fn new(value: T) -> Self {
|
||||||
Self(value)
|
Self(value)
|
||||||
}
|
}
|
||||||
|
pub fn into_inner(self) -> T {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// returns the number of available hardware threads, or 1 if it cannot be determined.
|
/// returns the number of available hardware threads, or 1 if it cannot be determined.
|
||||||
|
|
Loading…
Reference in a new issue