Index: Cargo.toml ================================================================== --- Cargo.toml +++ Cargo.toml @@ -1,8 +1,8 @@ [package] name = "swctx" -version = "0.2.1" +version = "0.2.2" edition = "2021" license = "0BSD" categories = [ "concurrency", "asynchronous" ] keywords = [ "channel", "threads", "sync", "message-passing" ] repository = "https://repos.qrnch.tech/pub/swctx" @@ -14,17 +14,14 @@ ".fslckout", "www", "rustfmt.toml" ] -[features] -dev-docs = [] - [dependencies] parking_lot = { version = "0.12.1" } [dev-dependencies] -tokio = { version = "1.31.0", features = ["rt-multi-thread"] } +tokio = { version = "1.35.1", features = ["rt-multi-thread"] } [package.metadata.docs.rs] rustdoc-args = ["--generate-link-to-definition"] Index: src/lib.rs ================================================================== --- src/lib.rs +++ src/lib.rs @@ -32,18 +32,18 @@ //! pass along an application-specific error code. This will cause the //! `WaitCtx` to unblock and return [`Error::App`]. mod err; mod sctx; -mod wctx; +pub(crate) mod wctx; use std::{sync::Arc, task::Waker}; use parking_lot::{Condvar, Mutex}; pub use sctx::SetCtx; -pub use wctx::WaitCtx; +pub use wctx::{WaitCtx, WaitFuture}; pub use err::Error; enum State { /// Waiting for a delivery. Index: src/sctx.rs ================================================================== --- src/sctx.rs +++ src/sctx.rs @@ -44,42 +44,30 @@ let mut inner = self.0.inner.lock(); inner.sctx_state = s; } /// Consume the `SetCtx` and store a value for the wait context to return. - #[cfg_attr( - feature = "dev-docs", - doc = r#" -# Internals -- This and `fail()` consume `self`. -- The wait context does not modify the state. -- The only other method is `set_state()` and it only touches `sctx_state` and - not `state`. - -These facts allow us to safely assume that the state does not need to be -checked here -- it can only be `Waiting`. - -The only "weird" state that can happen is that the wait context has been -dropped, but we silently ignore this case. -"# - )] pub fn set(self, data: T) { + // - This and `fail()` consume `self`. + // - The wait context does not modify the state. + // - The only other method is `set_state()` and it only touches + // `sctx_state` and not `state`. + // + // These facts allow us to safely assume that the state does not need to be + // checked here -- it can only be `Waiting`. + // + // The only "weird" state that can happen is that the wait context has been + // dropped, but we silently ignore this case. let mut inner = self.0.inner.lock(); inner.state = State::Data(data); self.0.notify_waiter(&mut inner); } /// Consume the `SetCtx` and store an error value for the wait context to /// return. - #[cfg_attr( - feature = "dev-docs", - doc = r#" -# Internals -See the _Internals_ section of [`SetCtx::set()`] for implementation details. -"# - )] pub fn fail(self, error: E) { + // See comments in SetCtx::set() for implementation details. let mut inner = self.0.inner.lock(); inner.state = State::Err(Error::App(error)); self.0.notify_waiter(&mut inner); } } Index: src/wctx.rs ================================================================== --- src/wctx.rs +++ src/wctx.rs @@ -70,11 +70,28 @@ pub fn wait_async(&self) -> WaitFuture { WaitFuture(Arc::clone(&self.0)) } } +impl Future for WaitCtx { + type Output = Result>; + fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll { + let mut inner = self.0.inner.lock(); + match inner.try_get() { + Ok(Some(v)) => Poll::Ready(Ok(v)), + Ok(None) => { + inner.waker = Some(ctx.waker().clone()); + Poll::Pending + } + Err(e) => Poll::Ready(Err(e)) + } + } +} + +/// Used to wait for the paired [`SetCtx`](super::SetCtx) to set a value in an +/// `async` context. #[repr(transparent)] pub struct WaitFuture(Arc>); impl Future for WaitFuture { type Output = Result>; Index: www/changelog.md ================================================================== --- www/changelog.md +++ www/changelog.md @@ -1,37 +1,54 @@ # Change Log ## [Unreleased] +[Details](/vdiff?from=swctx-0.2.1&to=trunk) + ### Added ### Changed +- Export `WaitFuture`. +- Implement `Future` on `WaitCtx`. + ### Removed +- Remove `dev-docs` feature. + +--- ## [0.2.1] - 2023-08-14 + +[Details](/vdiff?from=swctx-0.2.0&to=swctx-0.2.1) ### Changed - Add `--generate-link-to-definition` to `rustdoc-args` in `Cargo.toml`. - Update dev-dependency `tokio` to `1.31.0`. +--- ## [0.2.0] - 2023-08-10 + +[Details](/vdiff?from=swctx-0.1.1&to=swctx-0.2.0) ### Changed - Generalize `SetCtx` state. +--- ## [0.1.1] - 2023-08-08 + +[Details](/vdiff?from=swctx-0.1.0&to=swctx-0.1.1) ### Added - Add a `try_get()` as a non-blocking alternative to `wait()`. +--- ## [0.1.0] - 2023-07-30 - First release.