swctx

Check-in Differences
Login

Check-in Differences

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Difference From swctx-0.2.1 To swctx-0.2.2

2024-01-14
10:24
Update changelog. check-in: fa1ba701e6 user: jan tags: trunk
10:15
Separators in changelog. check-in: b1ba094b8a user: jan tags: swctx-0.2.2, trunk
10:13
Remove dev-docs feature. check-in: 82c7000574 user: jan tags: trunk
2023-08-24
21:23
Export WaitFuture and implement Future for WaitCtx. check-in: 32cef01be1 user: jan tags: trunk
2023-08-14
21:33
Release maintenance. check-in: ca475da22a user: jan tags: swctx-0.2.1, trunk
21:30
Add --generate-link-to-definition to rustdoc. check-in: fb0d7a6b05 user: jan tags: trunk

Changes to Cargo.toml.

1
2
3

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
1
2

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18



19
20
21
22

23
24
25
26
27


-
+















-
-
-




-
+




[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"
description = "One-shot channel with some special semantics."
rust-version = "1.56"
exclude = [
  ".fossil-settings",
  ".efiles",
  ".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"]

Changes to src/lib.rs.

30
31
32
33
34
35
36
37

38
39
40
41
42
43
44

45
46
47
48
49
50
51
30
31
32
33
34
35
36

37
38
39
40
41
42
43

44
45
46
47
48
49
50
51







-
+






-
+







//!
//! The `SetCtx` can also signal a failure by calling [`SetCtx::fail()`] and
//! 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<T, S, E> {
  /// Waiting for a delivery.
  Waiting,

Changes to src/sctx.rs.

42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59
60
61
62










63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
42
43
44
45
46
47
48

49













50
51
52
53
54
55
56
57
58
59



60
61
62
63
64
65
66







67
68
69
70
71
72
73
74
75







-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-







-
-
-
-
-
-
-

+







  /// ```
  pub fn set_state(&self, s: S) {
    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(
  pub fn set(self, data: T) {
    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.
    // - 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) {
    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);
  }
}

impl<T, S, E> Drop for SetCtx<T, S, E>

Changes to src/wctx.rs.

68
69
70
71
72
73
74









75









76
77
78
79
80
81
82
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99







+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+







  /// This function will panic if called again after it has resolved to either
  /// data or error.
  pub fn wait_async(&self) -> WaitFuture<T, S, E> {
    WaitFuture(Arc::clone(&self.0))
  }
}

impl<T, S, E> Future for WaitCtx<T, S, E> {
  type Output = Result<T, Error<S, E>>;
  fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
    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<T, S, E>(Arc<Shared<T, S, E>>);

impl<T, S, E> Future for WaitFuture<T, S, E> {
  type Output = Result<T, Error<S, E>>;
  fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
    let mut inner = self.0.inner.lock();

Changes to www/changelog.md.

1
2
3
4


5
6
7
8



9
10

11


12


13
14
15
16
17
18

19
20


21
22
23
24
25

26
27


28
29
30
31
32

33
34
35
36
37
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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.