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
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! # selectables
//!
//! Lock-free channels with a unified recv-arm selection model.
//!
//! The crate provides multiple channel flavors that can be selected with the same
//! `recv`-based protocol, including non-blocking and timed fallback behavior.
//!
//! ## Channel modules
//! - [unbounded_mpmc] lock-free unbounded multi-producer, multi-consumer channel.
//! - [bounded_mpmc] lock-free bounded multi-producer, multi-consumer channel.
//! - [bounded_mpsc] lock-free bounded multi-producer, single-consumer channel.
//! - [unbounded_mpsc] lock-free unbounded multi-producer, single-consumer channel.
//! - [bounded_broadcast] bounded multi-producer, multi-receiver broadcast channel with per-receiver
//! lag detection and independent cursors.
//! - [oneshot] single-send/single-delivery channel compatible with recv select arms.
//! - [watch] latest-value broadcast channel with versioned change notifications.
//! - [rendezvous] zero-buffer synchronous handoff channel.
//!
//! ## Selection model
//! - [select!] supports `recv(rx) -> msg => { ... }` and `send(tx, val) -> res => { ... }` arms.
//! - Non-blocking fallback: `default => { ... }`.
//! - Timed fallback: `default(duration) => { ... }`.
//! - Low-level builder API is provided by [Select] and [SelectedOperation].
//!
//! ## Timers
//! - [interval::interval] and [interval::interval_at] create repeating timer receivers.
//!
//! ## Error model
//! - [RecvError] for blocking receive/completion failures. Includes `Lagged { skipped }` for
//! bounded broadcast channels when a receiver falls behind senders.
//! - [error::TryRecvError] for non-blocking receive attempts.
//! - [SendError] for failed sends that return ownership of the message.
//!
//! ## Lag handling (broadcast channels only)
//! When using [bounded_broadcast], receivers may encounter `Lagged { skipped }` if they fall
//! behind the senders. This is normal and indicates the ring buffer wrapped around before the
//! receiver caught up. Recommended handling:
//!
//! ```rust,ignore
//! match rx.recv() {
//! Ok(msg) => process(msg),
//! Err(RecvError::Lagged { skipped }) => {
//! log::warn!("Receiver lagged by {} messages; recovered", skipped);
//! // Receiver cursor was automatically advanced; next recv will get oldest available
//! }
//! Err(RecvError::Disconnected) => {
//! log::info!("All senders disconnected");
//! break;
//! }
//! }
//! ```
//!
//! See [bounded_broadcast] module docs for detailed lag recovery patterns.
//!
//! ## Quick example
//! ```
//! use std::time::Duration;
//! use selectables::{bounded_mpmc, select};
//!
//! let (tx, rx) = bounded_mpmc::channel::<i32>(1);
//! tx.send(7).unwrap();
//!
//! select! {
//! recv(rx) -> msg => assert_eq!(msg, Ok(7)),
//! default(Duration::from_millis(10)) => panic!("unexpected timeout"),
//! }
//! ```
use Arc;
use AtomicUsize;
pub use ;
pub use ;
/// Trait for receivers that can participate in `recv` arms of [`select!`].
///
/// The select protocol is a four-phase algorithm: **try → register → park → complete**.
/// Each phase is represented by one or more methods on this trait.
/// Trait for senders that can participate in `send` arms of `select!`.
///
/// `is_ready` returns `true` when a send can complete without blocking (buffer
/// has space or the channel is disconnected). The select protocol uses the same
/// four-phase algorithm as for receivers: try → register → park → complete.
///
/// Implementors must also implement [`Clone`] because the `select!` macro clones
/// the sender handle before handing it to the low-level [`Select`] builder.