mirror of https://github.com/smol-rs/async-lock
m: Remove futures-lite dependency (#36)
This commit is contained in:
parent
15049aa1c9
commit
350cda03d9
|
@ -55,7 +55,7 @@ jobs:
|
|||
matrix:
|
||||
# When updating this, the reminder to update the minimum supported
|
||||
# Rust version in Cargo.toml.
|
||||
rust: ['1.43']
|
||||
rust: ['1.48']
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install Rust
|
||||
|
|
|
@ -6,7 +6,7 @@ name = "async-lock"
|
|||
version = "2.6.0"
|
||||
authors = ["Stjepan Glavina <stjepang@gmail.com>"]
|
||||
edition = "2018"
|
||||
rust-version = "1.43"
|
||||
rust-version = "1.48"
|
||||
description = "Async synchronization primitives"
|
||||
license = "Apache-2.0 OR MIT"
|
||||
repository = "https://github.com/smol-rs/async-lock"
|
||||
|
@ -15,12 +15,12 @@ categories = ["asynchronous", "concurrency"]
|
|||
exclude = ["/.*"]
|
||||
|
||||
[dependencies]
|
||||
futures-lite = "1.11.0"
|
||||
event-listener = "2.5.1"
|
||||
|
||||
[dev-dependencies]
|
||||
async-channel = "1.5.0"
|
||||
fastrand = "1.4.0"
|
||||
futures-lite = "1.12.0"
|
||||
|
||||
[target.'cfg(any(target_arch = "wasm32", target_arch = "wasm64"))'.dev-dependencies]
|
||||
wasm-bindgen-test = "0.3"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use event_listener::{Event, EventListener};
|
||||
use futures_lite::ready;
|
||||
|
||||
use std::fmt;
|
||||
use std::future::Future;
|
||||
|
|
14
src/lib.rs
14
src/lib.rs
|
@ -9,6 +9,20 @@
|
|||
|
||||
#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
|
||||
|
||||
/// Simple macro to extract the value of `Poll` or return `Pending`.
|
||||
///
|
||||
/// TODO: Drop in favor of `core::task::ready`, once MSRV is bumped to 1.64.
|
||||
macro_rules! ready {
|
||||
($e:expr) => {{
|
||||
use ::core::task::Poll;
|
||||
|
||||
match $e {
|
||||
Poll::Ready(v) => v,
|
||||
Poll::Pending => return Poll::Pending,
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
mod barrier;
|
||||
mod mutex;
|
||||
mod once_cell;
|
||||
|
|
|
@ -18,7 +18,6 @@ use std::time::{Duration, Instant};
|
|||
use std::usize;
|
||||
|
||||
use event_listener::{Event, EventListener};
|
||||
use futures_lite::ready;
|
||||
|
||||
/// An async mutex.
|
||||
///
|
||||
|
|
|
@ -9,7 +9,6 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
|||
use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
|
||||
|
||||
use event_listener::{Event, EventListener};
|
||||
use futures_lite::future;
|
||||
|
||||
/// The current state of the `OnceCell`.
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
|
@ -427,7 +426,9 @@ impl<T> OnceCell<T> {
|
|||
|
||||
// Slow path: initialize the value.
|
||||
// The futures provided should never block, so we can use `now_or_never`.
|
||||
now_or_never(self.initialize_or_wait(move || future::ready(closure()), &mut Blocking))?;
|
||||
now_or_never(
|
||||
self.initialize_or_wait(move || std::future::ready(closure()), &mut Blocking),
|
||||
)?;
|
||||
debug_assert!(self.is_initialized());
|
||||
|
||||
// SAFETY: We know that the value is initialized, so it is safe to
|
||||
|
@ -594,22 +595,13 @@ impl<T> OnceCell<T> {
|
|||
// but we do not have the ability to initialize it.
|
||||
//
|
||||
// We need to wait the initialization to complete.
|
||||
future::poll_fn(|cx| {
|
||||
match event_listener.take() {
|
||||
None => {
|
||||
event_listener = Some(self.active_initializers.listen());
|
||||
}
|
||||
Some(evl) => {
|
||||
if let Err(evl) = strategy.poll(evl, cx) {
|
||||
event_listener = Some(evl);
|
||||
return Poll::Pending;
|
||||
}
|
||||
}
|
||||
match event_listener.take() {
|
||||
None => {
|
||||
event_listener = Some(self.active_initializers.listen());
|
||||
}
|
||||
|
||||
Poll::Ready(())
|
||||
})
|
||||
.await;
|
||||
Some(evl) => strategy.poll(evl).await,
|
||||
}
|
||||
}
|
||||
State::Uninitialized => {
|
||||
// Try to move the cell into the initializing state.
|
||||
|
@ -758,7 +750,7 @@ impl<T> Drop for OnceCell<T> {
|
|||
}
|
||||
|
||||
/// Either return the result of a future now, or panic.
|
||||
fn now_or_never<T>(f: impl Future<Output = T>) -> T {
|
||||
fn now_or_never<T>(mut f: impl Future<Output = T>) -> T {
|
||||
const NOOP_WAKER: RawWakerVTable = RawWakerVTable::new(clone, wake, wake_by_ref, drop);
|
||||
|
||||
unsafe fn wake(_: *const ()) {}
|
||||
|
@ -768,13 +760,15 @@ fn now_or_never<T>(f: impl Future<Output = T>) -> T {
|
|||
}
|
||||
unsafe fn drop(_: *const ()) {}
|
||||
|
||||
futures_lite::pin!(f);
|
||||
// SAFETY: We don't move the future after we pin it here.
|
||||
let future = unsafe { Pin::new_unchecked(&mut f) };
|
||||
|
||||
let waker = unsafe { Waker::from_raw(RawWaker::new(ptr::null(), &NOOP_WAKER)) };
|
||||
|
||||
// Poll the future exactly once.
|
||||
let mut cx = Context::from_waker(&waker);
|
||||
|
||||
match f.poll(&mut cx) {
|
||||
match future.poll(&mut cx) {
|
||||
Poll::Ready(value) => value,
|
||||
Poll::Pending => unreachable!("future not ready"),
|
||||
}
|
||||
|
@ -782,17 +776,22 @@ fn now_or_never<T>(f: impl Future<Output = T>) -> T {
|
|||
|
||||
/// The strategy for polling an `event_listener::EventListener`.
|
||||
trait Strategy {
|
||||
/// The future that can be polled to wait on the listener.
|
||||
type Fut: Future<Output = ()>;
|
||||
|
||||
/// Poll the event listener.
|
||||
fn poll(&mut self, evl: EventListener, ctx: &mut Context<'_>) -> Result<(), EventListener>;
|
||||
fn poll(&mut self, evl: EventListener) -> Self::Fut;
|
||||
}
|
||||
|
||||
/// The strategy for blocking the current thread on an `EventListener`.
|
||||
struct Blocking;
|
||||
|
||||
impl Strategy for Blocking {
|
||||
fn poll(&mut self, evl: EventListener, _: &mut Context<'_>) -> Result<(), EventListener> {
|
||||
type Fut = std::future::Ready<()>;
|
||||
|
||||
fn poll(&mut self, evl: EventListener) -> Self::Fut {
|
||||
evl.wait();
|
||||
Ok(())
|
||||
std::future::ready(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -800,10 +799,9 @@ impl Strategy for Blocking {
|
|||
struct NonBlocking;
|
||||
|
||||
impl Strategy for NonBlocking {
|
||||
fn poll(&mut self, mut evl: EventListener, ctx: &mut Context<'_>) -> Result<(), EventListener> {
|
||||
match Pin::new(&mut evl).poll(ctx) {
|
||||
Poll::Pending => Err(evl),
|
||||
Poll::Ready(()) => Ok(()),
|
||||
}
|
||||
type Fut = EventListener;
|
||||
|
||||
fn poll(&mut self, evl: EventListener) -> Self::Fut {
|
||||
evl
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
|||
use std::task::{Context, Poll};
|
||||
|
||||
use event_listener::{Event, EventListener};
|
||||
use futures_lite::ready;
|
||||
|
||||
use crate::futures::Lock;
|
||||
use crate::{Mutex, MutexGuard};
|
||||
|
|
|
@ -6,7 +6,6 @@ use std::sync::Arc;
|
|||
use std::task::{Context, Poll};
|
||||
|
||||
use event_listener::{Event, EventListener};
|
||||
use futures_lite::ready;
|
||||
|
||||
/// A counter for limiting the number of concurrent operations.
|
||||
#[derive(Debug)]
|
||||
|
|
Loading…
Reference in New Issue