wait-list

This crate has been deprecated in favour of pin-list! If you want to get the crate name for something else, please do not hesitate to [contact me] or email help@crates.io.

Original readme below:

This crate provides WaitList, the most fundamental type for async synchronization. WaitList is implemented as an intrusive linked list of futures.

Feature flags

Example

A thread-safe unfair async mutex.

```rust use pinprojectlite::pinproject; use std::cell::UnsafeCell; use std::future::Future; use std::ops::Deref; use std::ops::DerefMut; use std::pin::Pin; use std::task; use std::task::Poll; use waitlist::WaitList;

pub struct Mutex { data: UnsafeCell, waiters: WaitList, (), ()>, }

unsafe impl Sync for Mutex {}

impl Mutex { pub fn new(data: T) -> Self { Self { data: UnsafeCell::new(data), waiters: WaitList::new(std::sync::Mutex::new(false)), } } pub fn lock(&self) -> Lock<', T> { Lock { mutex: self, inner: waitlist::Wait::new(), } } }

pinproject! { pub struct Lock<'mutex, T> { mutex: &'mutex Mutex, #[pin] inner: waitlist::Wait<'mutex, std::sync::Mutex, (), (), TryForward>, } }

impl<'mutex, T> Future for Lock<'mutex, T> { type Output = Guard<'mutex, T>; fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll { let mut this = self.project();

    let mut waiters = if this.inner.as_ref().is_completed() {
        // If we haven't initialized the future yet, lock the mutex for the first time
        this.mutex.waiters.lock_exclusive()
    } else {
        // Otherwise, wait for us to be woken
        match this.inner.as_mut().poll(cx) {
            Poll::Ready((waiters, ())) => waiters,
            Poll::Pending => return Poll::Pending,
        }
    };

    // If the mutex is unlocked, mark it as locked and return the guard
    if !*waiters.guard {
        *waiters.guard = true;
        return Poll::Ready(Guard { mutex: this.mutex });
    }

    // Otherwise, re-register ourselves to be woken when the mutex is unlocked again
    this.inner.init(cx.waker().clone(), &mut waiters, (), TryForward);
    Poll::Pending
}

}

/// When the future is cancelled before the mutex guard can be taken, wake up the next waiter. struct TryForward; impl<'waitlist> waitlist::CancelCallback<'waitlist, std::sync::Mutex, (), ()> for TryForward { fn oncancel( self, mut list: waitlist::LockedExclusive<'waitlist, std::sync::Mutex, (), ()>, output: (), ) { let _ = list.wake_one(()); } }

pub struct Guard<'mutex, T> { mutex: &'mutex Mutex, }

impl Deref for Guard<', T> { type Target = T; fn deref(&self) -> &Self::Target { unsafe { &*self.mutex.data.get() } } } impl DerefMut for Guard<', T> { fn deref_mut(&mut self) -> &mut Self::Target { unsafe { &mut *self.mutex.data.get() } } }

impl Drop for Guard<', T> { fn drop(&mut self) { let mut waiters = self.mutex.waiters.lockexclusive(); *waiters.guard = false; let _ = waiters.wake_one(()); } } # ```

License: MIT