m: Remove futures-lite dependency (#36)

This commit is contained in:
John Nunley 2023-01-26 14:13:16 -08:00 committed by GitHub
parent 15049aa1c9
commit 350cda03d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 42 additions and 34 deletions

View File

@ -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

View File

@ -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"

View File

@ -1,5 +1,4 @@
use event_listener::{Event, EventListener};
use futures_lite::ready;
use std::fmt;
use std::future::Future;

View File

@ -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;

View File

@ -18,7 +18,6 @@ use std::time::{Duration, Instant};
use std::usize;
use event_listener::{Event, EventListener};
use futures_lite::ready;
/// An async mutex.
///

View File

@ -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
}
}

View File

@ -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};

View File

@ -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)]