Skip to main content

secc/
lib.rs

1//! # Skip Enabled Concurrent Channel for Rust (SECC)
2//!
3//! [![Latest version](https://img.shields.io/crates/v/secc.svg)](https://crates.io/crates/secc)
4//! [![Build Status](https://api.travis-ci.org/rsimmonsjr/secc.svg?branch=master)](https://travis-ci.org/rsimmonsjr/secc)
5//! [![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/rsimmonsjr/secc.svg)](https://isitmaintained.com/project/rsimmonsjr/secc)
6//! [![License](https://img.shields.io/crates/l/secc.svg)](https://github.com/rsimmonsjr/secc#license)
7//!
8//! # Description
9//!
10//! An Skip Enabled Concurrent Channel (SECC) is a bounded capacity channel that supports multiple
11//! senders and multiple recievers and allows the receiver to temporarily skip receiving messages
12//! if they desire.
13//!
14//! Messages in the channel need to be clonable to implement the [`peek`] functionality (which
15//! returns a clone of the message). For this reason it is advisable that the user chose a type
16//! that is efficiently clonable, such as an [`Arc`] to enclose a message that cannot be
17//! efficiently cloned.
18//!
19//! The channel is a FIFO structure unless the user intends to skip one or more messages
20//! in which case a message could be read in a different order. The channel does, however,
21//! guarantee that the messages will remain in the same order as sent and, unless skipped, will
22//! be received in order.
23//!
24//! SECC is implemented using two linked lists where one list acts as a pool of nodes and the
25//! other list acts as the queue holding the messages. This allows us to move nodes in and out
26//! of the list and even skip a message with O(1) efficiency. If there are 1000 messages and
27//! the user desires to skip one in the middle they will incur virtually the exact same
28//! performance cost as a normal read operation. There are only a couple of additional pointer
29//! operations necessary to remove a node out of the middle of the linked list that implements
30//! the queue.  When a message is received from the channel the node holding the message is
31//! removed from the queue and appended to the tail of the pool. Conversely, when a  message is
32//! sent to the channel the node moves from the head of the pool to the tail of the queue. In
33//! this manner nodes are constantly cycled in and out of the queue so we only need to allocate
34//! them once when the channel is created.
35//!
36//! # Examples
37//! ```rust
38//! use secc::*;
39//! use std::time::Duration;
40//!
41//! let channel = create::<u8>(5, Duration::from_millis(10));
42//! let (sender, receiver) = channel;
43//! assert_eq!(Ok(()), sender.send(17));
44//! assert_eq!(Ok(()), sender.send(19));
45//! assert_eq!(Ok(()), sender.send(23));
46//! assert_eq!(Ok(()), sender.send(29));
47//! assert_eq!(Ok(17), receiver.receive());
48//! assert_eq!(Ok(()), receiver.skip());
49//! assert_eq!(Ok(23), receiver.receive());
50//! assert_eq!(Ok(()), receiver.reset_skip());
51//! assert_eq!(Ok(19), receiver.receive());
52//! ```
53//!
54//! This code creates the channel and then sends it a series of messages. The first is received
55//! normally but then the user wants to skip the next message. The user can then receive in
56//! the middle of the channel, reset the skip and resume receiving normally.
57//!
58//! ### What's New
59//!
60//! * 2019-09-13: 0.0.10
61//!   * Issue #13: A Deadlock would occur if the timeout occurred while waiting for space or data.
62//!   * BREAKING CHANGE Timeouts are in `Duration` objects now rather than milliseconds.
63//! * 2019-08-18: 0.0.9
64//!   * Most `unsafe` code has been eliminated, enhancing stability.
65//!
66//! [Release Notes for All Versions](https://github.com/rsimmonsjr/secc/blob/master/RELEASE_NOTES.md)
67//!
68//! ### Design Principals
69//!
70//! SECC was driven by the need for a multi-sender, multi-consumer channel that would have the
71//! ability to skip processing messages. There are many situation in which this is needed by a
72//! consumer such as the use case with Axiom where actors implement a finite state machine. That
73//! led me to go through many iterations of different designs until it became clear that a linked
74//! list was the only legitimate approach. The problem with a linked lists is that they typically
75//! burn a lot of CPU time in allocating new nodes on each enqueue. The solution was to use two
76//! linked lists, allocate all nodes up front and just logically move nodes around. The actual
77//! pointers to the next node or the various heads and tails are the indexes in the statically
78//! allocated slice of nodes. When send and receive operations happen, nodes are merely moved
79//! around logically but not physically.
80//!
81
82use std::cell::UnsafeCell;
83use std::fmt;
84use std::sync::atomic::{AtomicUsize, Ordering};
85use std::sync::{Arc, Condvar, Mutex, MutexGuard};
86use std::time::Duration;
87
88/// A message that is used to indicate that a position index points to no other node. Note that
89/// this value is something beyond the capability of any user to allocate for the channel size.
90const NIL: usize = 1 << 16 as usize;
91
92/// Errors potentially returned from channel operations.
93#[derive(Eq, PartialEq)]
94pub enum SeccErrors<T: Sync + Send + Clone> {
95    /// Channel is full, no more messages can be sent, the enclosed message contains the last
96    /// message attempted to be sent.
97    Full(T),
98
99    /// Channel is empty so no more messages can be received. This can also be returned if there
100    /// is an active cursor and there are no messages to receive after the cursor even though
101    /// there are skipped messages.
102    Empty,
103}
104
105impl<T: Sync + Send + Clone> fmt::Debug for SeccErrors<T> {
106    fn fmt(&self, formatter: &'_ mut fmt::Formatter) -> fmt::Result {
107        match self {
108            SeccErrors::Full(_) => write!(formatter, "SeccErrors::Full"),
109            SeccErrors::Empty => write!(formatter, "SeccErrors::Empty"),
110        }
111    }
112}
113
114impl<T: Sync + Send + Clone> fmt::Display for SeccErrors<T> {
115    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116        write!(f, "{:?}", self)
117    }
118}
119
120impl<T: Sync + Send + Clone> std::error::Error for SeccErrors<T> {
121    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
122        None
123    }
124}
125
126/// A single node in the channel's buffer.
127struct SeccNode<T: Sync + Send + Clone> {
128    /// Contains a message in a `Some` or contains `None` if the node is empty. Note that this is
129    /// an [`UnsafeCell`] in order to get around Rust mutability locks so that this data structure
130    /// can be passed around immutably but also still be able to send and receive.
131    cell: UnsafeCell<Option<T>>,
132    /// The pointer to the next node in the channel.
133    next: AtomicUsize,
134    // FIXME (Issue #12) Add tracking of time in channel by milliseconds.
135}
136
137impl<T: Sync + Send + Clone> SeccNode<T> {
138    /// Creates a new node where the next index is set to `NIL`.
139    fn new() -> SeccNode<T> {
140        SeccNode {
141            cell: UnsafeCell::new(None),
142            next: AtomicUsize::new(NIL),
143        }
144    }
145
146    /// Creates a new node where the next index is set to point at the provided index in
147    /// the slice of allocated nodes.
148    fn with_next(next: usize) -> SeccNode<T> {
149        SeccNode {
150            cell: UnsafeCell::new(None),
151            next: AtomicUsize::new(next),
152        }
153    }
154}
155
156pub trait SeccCoreOps<T: Sync + Send + Clone> {
157    /// Fetch the core of the channel.
158    fn core(&self) -> &SeccCore<T>;
159
160    /// Returns the capacity of the channel.
161    fn capacity(&self) -> usize {
162        self.core().capacity
163    }
164
165    /// Count of the number of times receivers of this channel waited for messages.
166    fn awaited_messages(&self) -> usize {
167        self.core().awaited_messages.load(Ordering::Relaxed)
168    }
169
170    /// Count of the number of times senders to the channel waited for capacity.
171    fn awaited_capacity(&self) -> usize {
172        self.core().awaited_capacity.load(Ordering::Relaxed)
173    }
174
175    /// Returns the number of items are in the channel currently without regard to cursors.
176    fn pending(&self) -> usize {
177        self.core().pending.load(Ordering::Relaxed)
178    }
179
180    /// Number of messages in the channel that are available to be received. This will normally be
181    /// the same as `pending` unless there is a skip cursor active; in which case it may be
182    /// smaller than pending or even 0.
183    fn receivable(&self) -> usize {
184        self.core().receivable.load(Ordering::Relaxed)
185    }
186
187    /// Returns the total number of messages that have been sent to the channel.
188    fn sent(&self) -> usize {
189        self.core().sent.load(Ordering::Relaxed)
190    }
191
192    /// Returns the total number of messages that have been received from the channel.
193    fn received(&self) -> usize {
194        self.core().received.load(Ordering::Relaxed)
195    }
196}
197
198/// A structure containing the pointers used when sending items to the channel.
199#[derive(Debug)]
200struct SeccSendPtrs {
201    /// The tail of the queue which holds messages currently in the channel.
202    queue_tail: usize,
203    /// The head of the pool of available nodes to be used when sending messages to the channel.  
204    /// Note that if there is only one node in the pool then the channel is full as neither the
205    /// pool nor queue may be empty.
206    pool_head: usize,
207}
208
209/// A structure containing pointers used when receiving messages from the channel.
210#[derive(Debug)]
211struct SeccReceivePtrs {
212    /// The head of the queue which holds messages currently in the channel.  Note that if there
213    /// is only one node in the queue then the channel is empty as neither the pool nor queue
214    /// may be empty.
215    queue_head: usize,
216    /// The tail of the pool of available nodes to be used when sending messages to the channel.
217    pool_tail: usize,
218    /// Either `NIL`, when there is no current skip cursor, or a pointer to the last
219    /// element skipped.
220    skipped: usize,
221    /// Either `NIL`, when there is no current skip cursor, or a pointer to the next
222    /// element that can be received from the channel.
223    cursor: usize,
224}
225
226/// Data structure that contains the core of the channel including tracking of statistics and
227/// node storage.
228pub struct SeccCore<T: Sync + Send + Clone> {
229    /// Capacity of the channel, which is the total number of items that can be stored. Note that
230    /// there will be 2 additional nodes allocated because neither the queue nor pool may ever
231    /// be empty.
232    capacity: usize,
233    /// The timeout used for polling the channel when waiting forever to send or recieve.
234    poll_timeout: Duration,
235    /// Storage of the nodes.
236    nodes: Box<[SeccNode<T>]>,
237    /// Indexes in the `nodes` used for sending elements to the channel.  These pointers are
238    /// paired together with a [`std::sync::Condvar`] that allows receivers awaiting messages
239    /// to be notified that messages are available but this mutex should only be used by receivers
240    /// with a [`std::sync::Condvar`] to prevent deadlocking the channel.
241    send_ptrs: Arc<(Mutex<SeccSendPtrs>, Condvar)>,
242    /// Indexes in the `nodes` used for receiving elements from the channel. These pointers
243    /// are combined with a [`std::sync::Condvar`] that can be used by senders awaiting capacity
244    /// but the mutex should only be used by the senders with a [`std::sync::Condvar`] to avoid
245    /// deadlocking the channel.
246    receive_ptrs: Arc<(Mutex<SeccReceivePtrs>, Condvar)>,
247    /// Count of the number of times receivers of this channel waited for messages.
248    awaited_messages: AtomicUsize,
249    /// Count of the number of times senders to the channel waited for capacity.
250    awaited_capacity: AtomicUsize,
251    /// Number of messages currently in the channel.
252    pending: AtomicUsize,
253    /// Number of messages in the channel that are available to be received. This will normally be
254    /// the same as `pending` unless there is a skip cursor active; in which case it may be
255    /// smaller than pending or even 0.
256    receivable: AtomicUsize,
257    /// Total number of messages that have been sent to the channel.
258    sent: AtomicUsize,
259    /// Total number of messages that have been received from the channel.
260    received: AtomicUsize,
261}
262
263/// Sender side of the channel.
264pub struct SeccSender<T: Sync + Send + Clone> {
265    /// The core of the channel.
266    core: Arc<SeccCore<T>>,
267}
268
269// Manual implementation necessary because of the following issue.
270// https://github.com/rust-lang/rust/issues/26925
271impl<T: Sync + Send + Clone> Clone for SeccSender<T> {
272    fn clone(&self) -> Self {
273        SeccSender {
274            core: self.core.clone(),
275        }
276    }
277}
278
279impl<T: Sync + Send + Clone> SeccSender<T> {
280    /// Creates a debug string for diagnosing problems with the send side of the channel. Note
281    /// that this requires the user to pass the mutex lock because Rust mutex locks are not
282    /// re-entrant so this cannot be done with a derive Debug.
283    fn debug_locked(&self, send_ptrs: &MutexGuard<SeccSendPtrs>) -> String {
284        let mut pool = Vec::with_capacity(self.core.capacity);
285        pool.push(send_ptrs.pool_head);
286        let mut next_ptr = self.core.nodes[send_ptrs.pool_head]
287            .next
288            .load(Ordering::SeqCst);
289        let mut count = 1;
290        while next_ptr != NIL {
291            count += 1;
292            pool.push(next_ptr);
293            next_ptr = self.core.nodes[next_ptr].next.load(Ordering::SeqCst);
294        }
295
296        format!(
297            "send_ptrs: {:?}, pool_size: {}, pool: {:?}",
298            send_ptrs, count, pool
299        )
300    }
301
302    /// Sends a message, which will be moved into the channel. This function will either return
303    /// an empty [`std::Result::Ok`] or an [`std::Result::Err`] containing the last message
304    /// sent if something went wrong.
305    pub fn send(&self, message: T) -> Result<(), SeccErrors<T>> {
306        // Retrieve send pointers and the encoded indexes inside them and their Condvar.
307        let (ref mutex, ref condvar) = &*self.core.send_ptrs;
308        let mut send_ptrs = mutex.lock().unwrap();
309
310        // Get a pointer to the current pool_head and see if we have space to send.
311        let pool_head_ptr = &self.core.nodes[send_ptrs.pool_head];
312        let next_pool_head = pool_head_ptr.next.load(Ordering::SeqCst);
313        if NIL == next_pool_head {
314            Err(SeccErrors::Full(message))
315        } else {
316            // We get the queue tail because the node from the pool will move here.
317            let queue_tail_ptr = &self.core.nodes[send_ptrs.queue_tail];
318
319            // Add the message to the node, transferring ownership.
320            unsafe {
321                *queue_tail_ptr.cell.get() = Some(message);
322            }
323
324            // Update the pointers in the mutex.
325            let old_pool_head = send_ptrs.pool_head;
326            send_ptrs.queue_tail = send_ptrs.pool_head;
327            send_ptrs.pool_head = next_pool_head;
328
329            // Adjust the channel metrics.
330            self.core.sent.fetch_add(1, Ordering::SeqCst);
331            self.core.receivable.fetch_add(1, Ordering::SeqCst);
332            self.core.pending.fetch_add(1, Ordering::SeqCst);
333
334            // The now filled node will get moved to the queue.
335            pool_head_ptr.next.store(NIL, Ordering::SeqCst);
336
337            // We MUST set this LAST or we will get into a race with the receiver that would
338            // think this node is ready for receiving when it isn't until just now.
339            queue_tail_ptr.next.store(old_pool_head, Ordering::SeqCst);
340
341            // Notify anyone that was waiting on the Condvar and we are done.
342            condvar.notify_all();
343            Ok(())
344        }
345    }
346
347    /// Send to the channel, awaiting capacity if necessary up to a given timeout. This
348    /// function is semantically identical to [`SeccSender::send`] but simply waits
349    /// for there to be space in the channel before sending.
350    pub fn send_await_timeout(
351        &self,
352        mut message: T,
353        timeout: Duration,
354    ) -> Result<(), SeccErrors<T>> {
355        loop {
356            match self.send(message) {
357                Err(SeccErrors::Full(v)) => {
358                    message = v;
359                    // We will put a Condvar on the mutex to be notified if space opens up.
360                    let (ref mutex, ref condvar) = &*self.core.receive_ptrs;
361                    let receive_ptrs = mutex.lock().unwrap();
362                    // Important that we drop the Condvar's guard to not deadlock channel.
363                    let (_, result) = condvar.wait_timeout(receive_ptrs, timeout).unwrap();
364                    self.core.awaited_capacity.fetch_add(1, Ordering::SeqCst);
365                    if result.timed_out() {
366                        // Try one more time to send in case we missed a Condvar notification.
367                        return self.send(message);
368                    }
369                }
370                v => return v,
371            }
372        }
373    }
374
375    // Waits basically forever to send to the channel rechecking for capacity periodically. The
376    // interval between checks is determined by the polling `Duration` passed to channel creation.
377    pub fn send_await(&self, mut message: T) -> Result<(), SeccErrors<T>> {
378        loop {
379            match self.send_await_timeout(message, self.core.poll_timeout) {
380                Err(SeccErrors::Full(v)) => {
381                    message = v;
382                }
383                other => return other,
384            }
385        }
386    }
387}
388
389impl<T: Sync + Send + Clone> SeccCoreOps<T> for SeccSender<T> {
390    fn core(&self) -> &SeccCore<T> {
391        &self.core
392    }
393}
394
395/// This function will write a debug string for the `SeccSender` but be warned that it will
396/// acquire the mutex lock to the `send_ptrs` to accomplish this so a deadlock could ensue if
397/// you have two threads asking for debug on both `SeccSender` and `SeccReceiver`, especially
398/// if they are doing so in a different order.
399impl<T: Sync + Send + Clone> fmt::Debug for SeccSender<T> {
400    fn fmt(&self, formatter: &'_ mut fmt::Formatter) -> fmt::Result {
401        let (ref mutex, _) = &*self.core.send_ptrs;
402        let send_ptrs = mutex.lock().unwrap();
403        write!(formatter, "{}", self.debug_locked(&send_ptrs))
404    }
405}
406
407unsafe impl<T: Send + Sync + Clone> Send for SeccSender<T> {}
408
409unsafe impl<T: Send + Sync + Clone> Sync for SeccSender<T> {}
410
411/// Receiver side of the channel.
412pub struct SeccReceiver<T: Sync + Send + Clone> {
413    /// The core of the channel.
414    core: Arc<SeccCore<T>>,
415}
416
417// Manual implementation necessary because of the following issue.
418// https://github.com/rust-lang/rust/issues/26925
419impl<T: Sync + Send + Clone> Clone for SeccReceiver<T> {
420    fn clone(&self) -> Self {
421        SeccReceiver {
422            core: self.core.clone(),
423        }
424    }
425}
426
427impl<T: Sync + Send + Clone> SeccReceiver<T> {
428    /// Creates a debug string for diagnosing problems with the receive side of the channel.
429    /// This requires the user to pass the `MutexGuard` for the lock of the receive side of the
430    /// channel because Rust `Mutex` locks are not re-entrant.
431    fn debug_locked(&self, receive_ptrs: &MutexGuard<SeccReceivePtrs>) -> String {
432        let mut queue = Vec::with_capacity(self.core.capacity);
433        let mut next_ptr = self.core.nodes[receive_ptrs.queue_head]
434            .next
435            .load(Ordering::SeqCst);
436        queue.push(receive_ptrs.queue_head);
437        let mut count = 1;
438        while next_ptr != NIL {
439            count += 1;
440            queue.push(next_ptr);
441            next_ptr = self.core.nodes[next_ptr].next.load(Ordering::SeqCst);
442        }
443
444        format!(
445            "receive_ptrs: {:?}, queue_size: {}, queue: {:?}",
446            receive_ptrs, count, queue
447        )
448    }
449
450    /// Peeks at the next receivable message in the channel and returns a `Clone` of the message.
451    /// Note that the message isn't guaranteed to stay in the channel as a thread could pop the
452    /// message off while another thread is looking at the value but the value shouldn't change
453    /// under the peeking thread.
454    pub fn peek(&self) -> Result<T, SeccErrors<T>> {
455        // Retrieve receive pointers and the encoded indexes inside them.
456        let (ref mutex, _) = &*self.core.receive_ptrs;
457        let receive_ptrs = mutex.lock().unwrap();
458
459        // Get a pointer to the queue_head or cursor and see check for anything receivable.
460        let read_ptr = if receive_ptrs.cursor == NIL {
461            &self.core.nodes[receive_ptrs.queue_head]
462        } else {
463            &self.core.nodes[receive_ptrs.cursor]
464        };
465        let next_read_pos = (*read_ptr).next.load(Ordering::SeqCst);
466        if NIL == next_read_pos {
467            return Err(SeccErrors::Empty);
468        }
469
470        // Extract the message and return a reference to it. If this panics then there
471        // was somehow a receivable node with no message in it which should never happen.
472        let message: T = unsafe {
473            (*((*read_ptr).cell).get())
474                .clone()
475                .expect("secc::peek(): empty receivable node")
476        };
477        Ok(message)
478    }
479
480    /// Receives the next message that is receivable. This will either receive the message at
481    /// the head of the channel or, in the case that there is a skip cursor active, the next
482    /// receivable message will be in the node pointed to by the skip cursor. This means that it
483    /// is possible that receive could return an [`SeccErrors::Empty`] when there are actually
484    /// messages in the channel because there will be none readable until the skip is reset.
485    pub fn receive(&self) -> Result<T, SeccErrors<T>> {
486        // Retrieve receive pointers and the encoded indexes inside them.
487        let (ref mutex, ref condvar) = &*self.core.receive_ptrs;
488        let mut receive_ptrs = mutex.lock().unwrap();
489
490        // Get a pointer to the queue_head or cursor and see check for anything receivable.
491        let read_ptr = if receive_ptrs.cursor == NIL {
492            &self.core.nodes[receive_ptrs.queue_head]
493        } else {
494            &self.core.nodes[receive_ptrs.cursor]
495        };
496        let next_read_pos = (*read_ptr).next.load(Ordering::SeqCst);
497        if NIL == next_read_pos {
498            Err(SeccErrors::Empty)
499        } else {
500            // We can read something so we will pull the item out of the read pointer.
501            let message: T = unsafe { (*(*read_ptr).cell.get()).take().unwrap() };
502
503            // Now we have to manage either pulling a node out of the middle if there was a
504            // cursor, or from the queue head if there was no cursor. Then we have to place
505            // the released node on the pool tail.
506            let pool_tail_ptr = &self.core.nodes[receive_ptrs.pool_tail];
507            (*read_ptr).next.store(NIL, Ordering::SeqCst);
508
509            let new_pool_tail = if receive_ptrs.cursor == NIL {
510                // If we aren't using a cursor then the queue_head becomes the pool tail
511                receive_ptrs.pool_tail = receive_ptrs.queue_head;
512                let old_queue_head = receive_ptrs.queue_head;
513                receive_ptrs.queue_head = next_read_pos;
514                old_queue_head
515            } else {
516                // If the cursor is set we have to dequeue in the middle of the list and fix the
517                // node chain and then move the node that the cursor was pointing at to the pool
518                // tail. Note that the `skipped` pointer will never be `NIL` when the cursor is
519                // not `NIL`. The `skipped` pointer is only ever set to a skipped node that
520                // could be read and lags beind `cursor` by one node in the queue.
521                let skipped_ptr = &self.core.nodes[receive_ptrs.skipped];
522                ((*skipped_ptr).next).store(next_read_pos, Ordering::SeqCst);
523                (*read_ptr).next.store(NIL, Ordering::SeqCst);
524                receive_ptrs.pool_tail = receive_ptrs.cursor;
525                let old_cursor = receive_ptrs.cursor;
526                receive_ptrs.cursor = next_read_pos;
527                old_cursor
528            };
529
530            // Update the channel metrics.
531            self.core.received.fetch_add(1, Ordering::SeqCst);
532            self.core.receivable.fetch_sub(1, Ordering::SeqCst);
533            self.core.pending.fetch_sub(1, Ordering::SeqCst);
534
535            // Finally add the new pool tail to the previous pool tail. We MUST set this
536            // LAST or we get into a race with the sender which would think that the node
537            // is available for sending when it actually isn't until just now.
538            (*pool_tail_ptr).next.store(new_pool_tail, Ordering::SeqCst);
539
540            // Notify anyone waiting on messages to be available.
541            condvar.notify_all();
542
543            // Return the message retreived earlier.
544            Ok(message)
545        }
546    }
547
548    /// Removes the next receivable message in the channel and abandons it or returns an error
549    /// if the channel was empty.
550    pub fn pop(&self) -> Result<(), SeccErrors<T>> {
551        self.receive()?;
552        Ok(())
553    }
554
555    /// A helper to call [`SeccReceiver::receive`] and await receivable messages until a message
556    /// is aailable or the specified timeout has expired.
557    pub fn receive_await_timeout(&self, timeout: Duration) -> Result<T, SeccErrors<T>> {
558        loop {
559            match self.receive() {
560                Err(SeccErrors::Empty) => {
561                    let (ref mutex, ref condvar) = &*self.core.send_ptrs;
562                    let send_ptrs = mutex.lock().unwrap();
563                    let (_, result) = condvar.wait_timeout(send_ptrs, timeout).unwrap();
564                    self.core.awaited_capacity.fetch_add(1, Ordering::SeqCst);
565                    if result.timed_out() {
566                        // Try one more time in case we missed a Condvar notification.
567                        return self.receive();
568                    }
569                }
570                v => return v,
571            }
572        }
573    }
574
575    // Waits basically forever to receive from the channel rechecking for data periodically. The
576    // interval between checks is determined by the polling `Duration` passed to channel creation.
577    pub fn receive_await(&self) -> Result<T, SeccErrors<T>> {
578        loop {
579            match self.receive_await_timeout(self.core.poll_timeout) {
580                Err(SeccErrors::Empty) => (),
581                other => return other,
582            }
583        }
584    }
585
586    /// Skips the next message to be received from the channel. If the skip succeeds than the
587    /// number of receivable messages will drop by one. Calling this function will either set up
588    /// a skip `cursor` in the channel or move an existing skip `cursor`. To receive skipped
589    /// messages the user will need to clear the skip cursor by calling the function `reset_skip`
590    /// prior to calling `receive`.
591    pub fn skip(&self) -> Result<(), SeccErrors<T>> {
592        // Retrieve receive pointers and the encoded indexes inside them.
593        let (ref mutex, _) = &*self.core.receive_ptrs;
594        let mut receive_ptrs = mutex.lock().unwrap();
595
596        let read_ptr = if receive_ptrs.cursor == NIL {
597            &self.core.nodes[receive_ptrs.queue_head]
598        } else {
599            &self.core.nodes[receive_ptrs.cursor]
600        };
601        let next_read_pos = read_ptr.next.load(Ordering::SeqCst);
602
603        // If there is a single node in the queue then there are no messages in the channel
604        // and therefore nothing to skip so we just return an empty error.
605        if NIL == next_read_pos {
606            return Err(SeccErrors::Empty);
607        }
608        if receive_ptrs.cursor == NIL {
609            // There is no current cursor so we need to establish one.
610            receive_ptrs.skipped = receive_ptrs.queue_head;
611            receive_ptrs.cursor = next_read_pos;
612        } else {
613            // There is a cursor already so make sure we increment `cursor` and `skipped`.
614            receive_ptrs.skipped = receive_ptrs.cursor;
615            receive_ptrs.cursor = next_read_pos;
616        }
617        self.core.receivable.fetch_sub(1, Ordering::SeqCst);
618        Ok(())
619    }
620
621    /// Cancels skipping messages in the channel and resets the `skipped` and `cursor` pointers
622    /// to `NIL` allowing previously skipped messages to be received. Note that calling this
623    /// method on a channel with no skip cursor will do nothing.
624    pub fn reset_skip(&self) -> Result<(), SeccErrors<T>> {
625        // Retrieve receive pointers and the encoded indexes inside them.
626        let (ref mutex, ref condvar) = &*self.core.receive_ptrs;
627        let mut receive_ptrs = mutex.lock().unwrap();
628
629        if receive_ptrs.cursor != NIL {
630            // We start from queue head and count to the cursor to get the new number of currently
631            // receivable messages in the channel.
632            let mut count: usize = 1; // Minimum number of skipped nodes.
633            let mut next_ptr = self.core.nodes[receive_ptrs.queue_head]
634                .next
635                .load(Ordering::SeqCst);
636            while next_ptr != receive_ptrs.cursor {
637                count += 1;
638                next_ptr = self.core.nodes[next_ptr].next.load(Ordering::SeqCst);
639            }
640            self.core.receivable.fetch_add(count, Ordering::SeqCst);
641            receive_ptrs.cursor = NIL;
642            receive_ptrs.skipped = NIL;
643        }
644        // Notify anyone waiting for receivable messages to be available.
645        condvar.notify_all();
646        Ok(())
647    }
648
649    /// Receive the message at the current cursor and then resets the skip cursor. If there
650    /// is currently no skip cursor this is the same as calling [`receive`].
651    pub fn receive_and_reset_skip(&self) -> Result<T, SeccErrors<T>> {
652        let result = self.receive()?;
653        self.reset_skip()?;
654        Ok(result)
655    }
656
657    /// Pops the message at the current cursor and then resets the skip cursor. If there is
658    /// currently no skip cursor this is the same as calling [`pop`].
659    pub fn pop_and_reset_skip(&self) -> Result<(), SeccErrors<T>> {
660        self.pop()?;
661        self.reset_skip()
662    }
663}
664
665impl<T: Sync + Send + Clone> SeccCoreOps<T> for SeccReceiver<T> {
666    fn core(&self) -> &SeccCore<T> {
667        &self.core
668    }
669}
670
671/// This function will write a debug string for the `SeccReceiver` but be warned that it will
672/// acquire the mutex lock to the `receive_ptrs` to accomplish this so a deadlock could ensue
673/// if you have two threads asking for debug on both `SeccSender` and `SeccReceiver`, especially
674/// if they are doing so in a different order.
675impl<T: Sync + Send + Clone> fmt::Debug for SeccReceiver<T> {
676    fn fmt(&self, formatter: &'_ mut fmt::Formatter) -> fmt::Result {
677        let (ref mutex, _) = &*self.core.receive_ptrs;
678        let receive_ptrs = mutex.lock().unwrap();
679        write!(formatter, "{}", self.debug_locked(&receive_ptrs))
680    }
681}
682
683unsafe impl<T: Send + Sync + Clone> Send for SeccReceiver<T> {}
684
685unsafe impl<T: Send + Sync + Clone> Sync for SeccReceiver<T> {}
686
687/// Creates the sender and receiver sides of this channel and returns them as a tuple. The user
688/// can pass both a channel `capacity` and a `poll` `Duration` which govern how often operations
689/// that wait on the channel will poll.
690pub fn create<T: Sync + Send + Clone>(
691    capacity: u16,
692    poll_timeout: Duration,
693) -> (SeccSender<T>, SeccReceiver<T>) {
694    if capacity < 1 {
695        panic!("capacity cannot be smaller than 1");
696    }
697
698    // We add two to the allocated capacity to account for the mandatory two placeholder nodes
699    // which guarantees that both queue and pool are never empty.
700    let alloc_capacity = (capacity + 2) as usize;
701    let mut nodes = Vec::<SeccNode<T>>::with_capacity(alloc_capacity);
702
703    // The queue just gets one initial node with and the queue_tail is the same as the queue_head.
704    nodes.push(SeccNode::<T>::new());
705    let queue_head = nodes.len() - 1;
706    let queue_tail = queue_head;
707
708    // Allocate the tail in the pool of nodes that will be added to in order to form the pool.
709    // Note that although this is expensive, it only has to be done once.
710    nodes.push(SeccNode::<T>::new());
711    let mut pool_head = nodes.len() - 1;
712    let pool_tail = pool_head;
713
714    // Allocate the rest of the pool setting the next pointers of each node to the previous node.
715    for _ in 0..capacity {
716        nodes.push(SeccNode::<T>::with_next(pool_head));
717        pool_head = nodes.len() - 1;
718    }
719
720    // Materialize the starting indexes for both send and receive.
721    let send_ptrs = SeccSendPtrs {
722        queue_tail,
723        pool_head,
724    };
725
726    let receive_ptrs = SeccReceivePtrs {
727        queue_head,
728        pool_tail,
729        skipped: NIL,
730        cursor: NIL,
731    };
732
733    // Create the channel structures.
734    let core = Arc::new(SeccCore {
735        capacity: capacity as usize,
736        poll_timeout,
737        nodes: nodes.into_boxed_slice(),
738        send_ptrs: Arc::new((Mutex::new(send_ptrs), Condvar::new())),
739        receive_ptrs: Arc::new((Mutex::new(receive_ptrs), Condvar::new())),
740        awaited_messages: AtomicUsize::new(0),
741        awaited_capacity: AtomicUsize::new(0),
742        pending: AtomicUsize::new(0),
743        receivable: AtomicUsize::new(0),
744        sent: AtomicUsize::new(0),
745        received: AtomicUsize::new(0),
746    });
747
748    // Return the resulting sender and receiver as a tuple.
749    let sender = SeccSender { core: core.clone() };
750    let receiver = SeccReceiver { core };
751
752    (sender, receiver)
753}
754
755// --------------------- Test Cases ---------------------
756
757#[cfg(test)]
758mod tests {
759    use super::*;
760    use std::thread;
761    use std::thread::JoinHandle;
762    use std::time::{Duration, Instant};
763
764    /// A macro to assert that pointers point to the right nodes.
765    macro_rules! assert_pointer_nodes {
766        (
767            $sender:expr,
768            $receiver:expr,
769            $queue_head:expr,
770            $queue_tail:expr,
771            $pool_head:expr,
772            $pool_tail:expr,
773            $skipped:expr,
774            $cursor:expr
775        ) => {{
776            let actual = debug_channel($sender.clone(), $receiver.clone());
777            let (ref mutex, _) = &*$sender.core.send_ptrs;
778            let send_ptrs = mutex.lock().unwrap();
779            let (ref mutex, _) = &*$receiver.core.receive_ptrs;
780            let receive_ptrs = mutex.lock().unwrap();
781
782            assert_eq!(
783                $queue_head, receive_ptrs.queue_head,
784                " <== queue_head mismatch!\n Actual: {}\n",
785                actual
786            );
787            assert_eq!(
788                $queue_tail, send_ptrs.queue_tail,
789                "<== queue_tail mismatch\n Actual: {}\n",
790                actual
791            );
792            assert_eq!(
793                $pool_head, send_ptrs.pool_head,
794                "<== pool_head mismatch\n Actual: {}\n",
795                actual
796            );
797            assert_eq!(
798                $pool_tail, receive_ptrs.pool_tail,
799                " <== pool_tail mismatch\n Actual: {}\n",
800                actual
801            );
802            assert_eq!(
803                $skipped, receive_ptrs.skipped,
804                " <== skipped mismatch\n Actual: {}\n",
805                actual
806            );
807            assert_eq!(
808                $cursor, receive_ptrs.cursor,
809                " <== cursor mismatch\n Actual: {}\n",
810                actual
811            );
812        }};
813    }
814
815    /// Asserts that the given node in the channel has the expected next pointer.
816    macro_rules! assert_node_next {
817        ($pointers:expr, $node:expr, $next:expr) => {
818            assert_eq!($pointers[$node].next.load(Ordering::Relaxed), $next,)
819        };
820    }
821
822    /// Asserts that the given node in the channel has a next pointing to `NIL`.
823    macro_rules! assert_node_next_nil {
824        ($pointers:expr, $node:expr) => {
825            assert_eq!($pointers[$node].next.load(Ordering::Relaxed), NIL,)
826        };
827    }
828
829    /// Creates a debug string for debugging channel problems.
830    pub fn debug_channel<T: Send + Sync + Clone>(
831        sender: SeccSender<T>,
832        receiver: SeccReceiver<T>,
833    ) -> String {
834        format!("{{ Sender: {:?}, Receiver: {:?} }}", sender, receiver)
835    }
836
837    /// Items used as messages by tests.
838    #[derive(Debug, Eq, PartialEq, Clone)]
839    enum Items {
840        A,
841        B,
842        C,
843        D,
844        E,
845        F,
846    }
847
848    /// Tests that if a message is popped after another thread peeks at the message that the
849    /// message will be removed from the channel but wont change underneath the thread that
850    /// peeked at the message.
851    #[test]
852    fn test_pop_after_peek() {
853        use std::num::NonZeroU8;
854
855        let value = NonZeroU8::new(5).unwrap();
856        let (tx, rx) = create::<NonZeroU8>(1, Duration::from_millis(100));
857        tx.send(value).unwrap();
858        let item = rx.peek().unwrap();
859        assert_eq!(value, item);
860        // Popping shouldnt change the value.
861        rx.pop().unwrap();
862        assert_eq!(value, item);
863    }
864
865    /// Tests that the proper errors are returned if `peek` is called on an empty channel.
866    #[test]
867    fn test_peek_empty() {
868        let (sender, receiver) = create::<Items>(5, Duration::from_millis(10));
869        assert_eq!(Err(SeccErrors::Empty), receiver.peek());
870
871        sender.send(Items::A).unwrap();
872        receiver.pop().unwrap();
873        assert_eq!(Err(SeccErrors::Empty), receiver.peek());
874    }
875
876    /// Tests that an error would be generated if another thread popped a message off the
877    /// channel and the peeking thread tried to pop the same message in an empty channel.
878    #[test]
879    fn test_pop_while_peeking() {
880        let (sender, receiver) = create::<Items>(5, Duration::from_millis(10));
881        let peeked = Arc::new((Mutex::new(false), Condvar::new()));
882        let popped = Arc::new((Mutex::new(false), Condvar::new()));
883
884        let peeked_clone = peeked.clone();
885        let popped_clone = popped.clone();
886        let receiver_clone = receiver.clone();
887
888        sender.send(Items::A).unwrap();
889
890        let handle_peek = thread::spawn(move || {
891            let (ref mutex1, ref cvar1) = &*peeked_clone;
892            let mut ready = mutex1.lock().unwrap();
893            *ready = true;
894            let _item = receiver_clone.peek();
895            cvar1.notify_all();
896            drop(ready);
897
898            // Wait for the pop to occur.
899            let (ref mutex2, ref cvar2) = &*popped_clone;
900            let mut done = mutex2.lock().unwrap();
901            while !*done {
902                done = cvar2.wait(done).unwrap();
903            }
904            // Pop after someone already did should be an error.
905            assert_eq!(Err(SeccErrors::Empty), receiver_clone.pop());
906        });
907
908        let handle_pop = thread::spawn(move || {
909            let (ref mutex1, ref cvar1) = &*peeked;
910            let mut ready = mutex1.lock().unwrap();
911            while !*ready {
912                ready = cvar1.wait(ready).unwrap();
913            }
914
915            let (ref mutex2, ref cvar2) = &*popped;
916            let mut done = mutex2.lock().unwrap();
917            *done = true;
918            receiver.pop().unwrap();
919            cvar2.notify_all();
920        });
921
922        handle_pop.join().unwrap();
923        handle_peek.join().unwrap();
924    }
925
926    /// Issue #4 Prevents #[derive(Clone)] from being used because of a rust bug that thinks
927    /// it needs to clone the T type and required manual cloning. If not fixed this test
928    /// wouldn't compile.
929    #[test]
930    fn test_clone_with_unclonable() {
931        struct Unclonable {}
932
933        let (sender, receiver) = create::<Arc<Unclonable>>(5, Duration::from_millis(10));
934        let _s_clone = sender.clone();
935        let _r_clone = receiver.clone();
936    }
937
938    /// This test checks the basic functionality of sending and receiving messages from the
939    /// channel in a single thread. This is used to verify basic functionality.
940    #[test]
941    fn test_send_and_receive() {
942        let channel = create::<Items>(5, Duration::from_millis(10));
943        let (sender, receiver) = channel;
944
945        // Fetch the pointers for easy checking of the nodes.
946        let pointers = &sender.core.nodes;
947
948        assert_eq!(7, pointers.len());
949        assert_eq!(5, sender.core.capacity);
950        assert_eq!(5, sender.capacity());
951        assert_eq!(5, receiver.capacity());
952
953        // Check the initial structure.
954        assert_eq!(0, sender.pending());
955        assert_eq!(0, sender.receivable());
956        assert_eq!(0, sender.sent());
957        assert_eq!(0, sender.received());
958        assert_node_next_nil!(pointers, 0);
959        assert_node_next!(pointers, 6, 5);
960        assert_node_next!(pointers, 5, 4);
961        assert_node_next!(pointers, 4, 3);
962        assert_node_next!(pointers, 3, 2);
963        assert_node_next!(pointers, 2, 1);
964        assert_node_next_nil!(pointers, 1);
965        assert_pointer_nodes!(sender, receiver, 0, 0, 6, 1, NIL, NIL);
966
967        // Check that sending a message to the channel removes pool head and appends to queue
968        // tail and changes nothing else in the node structure.
969        assert_eq!(Ok(()), sender.send(Items::A));
970        assert_eq!(1, sender.pending());
971        assert_eq!(1, sender.receivable());
972        assert_eq!(1, sender.sent());
973        assert_eq!(0, sender.received());
974        assert_node_next!(pointers, 0, 6);
975        assert_node_next_nil!(pointers, 6);
976        assert_node_next!(pointers, 5, 4);
977        assert_node_next!(pointers, 4, 3);
978        assert_node_next!(pointers, 3, 2);
979        assert_node_next!(pointers, 2, 1);
980        assert_node_next_nil!(pointers, 1);
981        assert_pointer_nodes!(sender, receiver, 0, 6, 5, 1, NIL, NIL);
982
983        assert_eq!(Ok(()), sender.send(Items::B));
984        assert_eq!(2, sender.pending());
985        assert_eq!(2, sender.receivable());
986        assert_eq!(2, sender.sent());
987        assert_eq!(0, sender.received());
988        assert_node_next!(pointers, 0, 6);
989        assert_node_next!(pointers, 6, 5);
990        assert_node_next_nil!(pointers, 5);
991        assert_node_next!(pointers, 4, 3);
992        assert_node_next!(pointers, 3, 2);
993        assert_node_next!(pointers, 2, 1);
994        assert_node_next_nil!(pointers, 1);
995        assert_pointer_nodes!(sender, receiver, 0, 5, 4, 1, NIL, NIL);
996
997        assert_eq!(Ok(()), sender.send(Items::C));
998        assert_eq!(3, sender.pending());
999        assert_eq!(3, sender.receivable());
1000        assert_eq!(3, sender.sent());
1001        assert_eq!(0, sender.received());
1002        assert_node_next!(pointers, 0, 6);
1003        assert_node_next!(pointers, 6, 5);
1004        assert_node_next!(pointers, 5, 4);
1005        assert_node_next_nil!(pointers, 4);
1006        assert_node_next!(pointers, 3, 2);
1007        assert_node_next!(pointers, 2, 1);
1008        assert_node_next_nil!(pointers, 1);
1009        assert_pointer_nodes!(sender, receiver, 0, 4, 3, 1, NIL, NIL);
1010
1011        assert_eq!(Ok(()), sender.send(Items::D));
1012        assert_eq!(4, sender.pending());
1013        assert_eq!(4, sender.receivable());
1014        assert_eq!(4, sender.sent());
1015        assert_eq!(0, sender.received());
1016        assert_node_next!(pointers, 0, 6);
1017        assert_node_next!(pointers, 6, 5);
1018        assert_node_next!(pointers, 5, 4);
1019        assert_node_next!(pointers, 4, 3);
1020        assert_node_next_nil!(pointers, 3);
1021        assert_node_next!(pointers, 2, 1);
1022        assert_node_next_nil!(pointers, 1);
1023        assert_pointer_nodes!(sender, receiver, 0, 3, 2, 1, NIL, NIL);
1024
1025        assert_eq!(Ok(()), sender.send(Items::E));
1026        assert_eq!(5, sender.pending());
1027        assert_eq!(5, sender.receivable());
1028        assert_eq!(5, sender.sent());
1029        assert_eq!(0, sender.received());
1030        assert_node_next!(pointers, 0, 6);
1031        assert_node_next!(pointers, 6, 5);
1032        assert_node_next!(pointers, 5, 4);
1033        assert_node_next!(pointers, 4, 3);
1034        assert_node_next!(pointers, 3, 2);
1035        assert_node_next_nil!(pointers, 2);
1036        assert_node_next_nil!(pointers, 1);
1037        assert_pointer_nodes!(sender, receiver, 0, 2, 1, 1, NIL, NIL);
1038
1039        // Validate that we cannot fill the channel past its capacity and attempts do not
1040        // mangle the pointers in the channel.
1041        assert_eq!(Err(SeccErrors::Full(Items::F)), sender.send(Items::F));
1042        assert_eq!(5, sender.pending());
1043        assert_eq!(5, sender.receivable());
1044        assert_eq!(5, sender.sent());
1045        assert_eq!(0, sender.received());
1046
1047        assert_eq!(Err(SeccErrors::Full(Items::F)), sender.send(Items::F));
1048        assert_eq!(5, sender.pending());
1049        assert_eq!(5, sender.receivable());
1050        assert_eq!(5, sender.sent());
1051        assert_eq!(0, sender.received());
1052
1053        assert_node_next!(pointers, 0, 6);
1054        assert_node_next!(pointers, 6, 5);
1055        assert_node_next!(pointers, 5, 4);
1056        assert_node_next!(pointers, 4, 3);
1057        assert_node_next!(pointers, 3, 2);
1058        assert_node_next_nil!(pointers, 2);
1059        assert_node_next_nil!(pointers, 1);
1060        assert_pointer_nodes!(sender, receiver, 0, 2, 1, 1, NIL, NIL);
1061
1062        // Peek at the first message in the channel which should change nothing.
1063        assert_eq!(Ok(Items::A), receiver.peek());
1064        assert_eq!(5, receiver.pending());
1065        assert_eq!(5, receiver.receivable());
1066        assert_eq!(5, receiver.sent());
1067        assert_eq!(0, receiver.received());
1068        assert_node_next!(pointers, 0, 6);
1069        assert_node_next!(pointers, 6, 5);
1070        assert_node_next!(pointers, 5, 4);
1071        assert_node_next!(pointers, 4, 3);
1072        assert_node_next!(pointers, 3, 2);
1073        assert_node_next_nil!(pointers, 2);
1074        assert_node_next_nil!(pointers, 1);
1075        assert_pointer_nodes!(sender, receiver, 0, 2, 1, 1, NIL, NIL);
1076
1077        // Validate that receiving from the channel performs the proper pointer operations.
1078        assert_eq!(Ok(Items::A), receiver.receive());
1079        assert_eq!(4, receiver.pending());
1080        assert_eq!(4, receiver.receivable());
1081        assert_eq!(5, receiver.sent());
1082        assert_eq!(1, receiver.received());
1083        assert_node_next!(pointers, 6, 5);
1084        assert_node_next!(pointers, 5, 4);
1085        assert_node_next!(pointers, 4, 3);
1086        assert_node_next!(pointers, 3, 2);
1087        assert_node_next_nil!(pointers, 2);
1088        assert_node_next!(pointers, 1, 0);
1089        assert_node_next_nil!(pointers, 0);
1090        assert_pointer_nodes!(sender, receiver, 6, 2, 1, 0, NIL, NIL);
1091
1092        assert_eq!(Ok(Items::B), receiver.receive());
1093        assert_eq!(3, receiver.pending());
1094        assert_eq!(3, receiver.receivable());
1095        assert_eq!(5, receiver.sent());
1096        assert_eq!(2, receiver.received());
1097        assert_node_next!(pointers, 5, 4);
1098        assert_node_next!(pointers, 4, 3);
1099        assert_node_next!(pointers, 3, 2);
1100        assert_node_next_nil!(pointers, 2);
1101        assert_node_next!(pointers, 1, 0);
1102        assert_node_next!(pointers, 0, 6);
1103        assert_node_next_nil!(pointers, 6);
1104        assert_pointer_nodes!(sender, receiver, 5, 2, 1, 6, NIL, NIL);
1105
1106        assert_eq!(Ok(Items::C), receiver.receive());
1107        assert_eq!(2, receiver.pending());
1108        assert_eq!(2, receiver.receivable());
1109        assert_eq!(5, receiver.sent());
1110        assert_eq!(3, receiver.received());
1111        assert_node_next!(pointers, 4, 3);
1112        assert_node_next!(pointers, 3, 2);
1113        assert_node_next_nil!(pointers, 2);
1114        assert_node_next!(pointers, 1, 0);
1115        assert_node_next!(pointers, 0, 6);
1116        assert_node_next!(pointers, 6, 5);
1117        assert_node_next_nil!(pointers, 5);
1118        assert_pointer_nodes!(sender, receiver, 4, 2, 1, 5, NIL, NIL);
1119
1120        assert_eq!(Ok(Items::D), receiver.receive());
1121        assert_eq!(1, receiver.pending());
1122        assert_eq!(1, receiver.receivable());
1123        assert_eq!(5, receiver.sent());
1124        assert_eq!(4, receiver.received());
1125        assert_node_next!(pointers, 3, 2);
1126        assert_node_next_nil!(pointers, 2);
1127        assert_node_next!(pointers, 1, 0);
1128        assert_node_next!(pointers, 0, 6);
1129        assert_node_next!(pointers, 6, 5);
1130        assert_node_next!(pointers, 5, 4);
1131        assert_node_next_nil!(pointers, 4);
1132        assert_pointer_nodes!(sender, receiver, 3, 2, 1, 4, NIL, NIL);
1133
1134        assert_eq!(Ok(Items::E), receiver.receive());
1135        assert_eq!(0, receiver.pending());
1136        assert_eq!(0, receiver.receivable());
1137        assert_eq!(5, receiver.sent());
1138        assert_eq!(5, receiver.received());
1139        assert_node_next_nil!(pointers, 2);
1140        assert_node_next!(pointers, 1, 0);
1141        assert_node_next!(pointers, 0, 6);
1142        assert_node_next!(pointers, 6, 5);
1143        assert_node_next!(pointers, 5, 4);
1144        assert_node_next!(pointers, 4, 3);
1145        assert_node_next_nil!(pointers, 3);
1146        assert_pointer_nodes!(sender, receiver, 2, 2, 1, 3, NIL, NIL);
1147
1148        // Validate that we cannot continue to receive from an empty channel and attempts
1149        // don't mangle the pointers.
1150        assert_eq!(Err(SeccErrors::Empty), receiver.receive());
1151        assert_eq!(0, receiver.pending());
1152        assert_eq!(0, receiver.receivable());
1153        assert_eq!(5, receiver.sent());
1154        assert_eq!(5, receiver.received());
1155        assert_node_next_nil!(pointers, 2);
1156        assert_node_next!(pointers, 1, 0);
1157        assert_node_next!(pointers, 0, 6);
1158        assert_node_next!(pointers, 6, 5);
1159        assert_node_next!(pointers, 5, 4);
1160        assert_node_next!(pointers, 4, 3);
1161        assert_node_next_nil!(pointers, 3);
1162        assert_pointer_nodes!(sender, receiver, 2, 2, 1, 3, NIL, NIL);
1163
1164        assert_eq!(Err(SeccErrors::Empty), receiver.receive());
1165        assert_eq!(0, receiver.pending());
1166        assert_eq!(0, receiver.receivable());
1167        assert_eq!(5, receiver.sent());
1168        assert_eq!(5, receiver.received());
1169        assert_node_next_nil!(pointers, 2);
1170        assert_node_next!(pointers, 1, 0);
1171        assert_node_next!(pointers, 0, 6);
1172        assert_node_next!(pointers, 6, 5);
1173        assert_node_next!(pointers, 5, 4);
1174        assert_node_next!(pointers, 4, 3);
1175        assert_node_next_nil!(pointers, 3);
1176        assert_pointer_nodes!(sender, receiver, 2, 2, 1, 3, NIL, NIL);
1177
1178        // Validate that after the channel is empty it can still be sent to and received from.
1179        assert_eq!(Ok(()), sender.send(Items::F));
1180        assert_eq!(1, receiver.pending());
1181        assert_eq!(1, receiver.receivable());
1182        assert_eq!(6, receiver.sent());
1183        assert_eq!(5, receiver.received());
1184        assert_node_next!(pointers, 2, 1);
1185        assert_node_next_nil!(pointers, 1);
1186        assert_node_next!(pointers, 0, 6);
1187        assert_node_next!(pointers, 6, 5);
1188        assert_node_next!(pointers, 5, 4);
1189        assert_node_next!(pointers, 4, 3);
1190        assert_node_next_nil!(pointers, 3);
1191        assert_pointer_nodes!(sender, receiver, 2, 1, 0, 3, NIL, NIL);
1192
1193        assert_eq!(Ok(Items::F), receiver.receive());
1194        assert_eq!(0, receiver.pending());
1195        assert_eq!(0, receiver.receivable());
1196        assert_eq!(6, receiver.sent());
1197        assert_eq!(6, receiver.received());
1198        assert_node_next_nil!(pointers, 1);
1199        assert_node_next!(pointers, 0, 6);
1200        assert_node_next!(pointers, 6, 5);
1201        assert_node_next!(pointers, 5, 4);
1202        assert_node_next!(pointers, 4, 3);
1203        assert_node_next!(pointers, 3, 2);
1204        assert_node_next_nil!(pointers, 2);
1205        assert_pointer_nodes!(sender, receiver, 1, 1, 0, 2, NIL, NIL);
1206
1207        // Skipping in empty queue should return empty and not mangle pointers.
1208        assert_eq!(Err(SeccErrors::Empty), receiver.skip());
1209        assert_eq!(0, receiver.pending());
1210        assert_eq!(0, receiver.receivable());
1211        assert_eq!(6, receiver.sent());
1212        assert_eq!(6, receiver.received());
1213        assert_node_next_nil!(pointers, 1);
1214        assert_node_next!(pointers, 0, 6);
1215        assert_node_next!(pointers, 6, 5);
1216        assert_node_next!(pointers, 5, 4);
1217        assert_node_next!(pointers, 4, 3);
1218        assert_node_next!(pointers, 3, 2);
1219        assert_node_next_nil!(pointers, 2);
1220        assert_pointer_nodes!(sender, receiver, 1, 1, 0, 2, NIL, NIL);
1221
1222        // Send another value to the channel so we can test skipping.
1223        assert_eq!(Ok(()), sender.send(Items::A));
1224        assert_eq!(1, receiver.pending());
1225        assert_eq!(1, receiver.receivable());
1226        assert_eq!(7, receiver.sent());
1227        assert_eq!(6, receiver.received());
1228        assert_node_next!(pointers, 1, 0);
1229        assert_node_next_nil!(pointers, 0);
1230        assert_node_next!(pointers, 6, 5);
1231        assert_node_next!(pointers, 5, 4);
1232        assert_node_next!(pointers, 4, 3);
1233        assert_node_next!(pointers, 3, 2);
1234        assert_node_next_nil!(pointers, 2);
1235        assert_pointer_nodes!(sender, receiver, 1, 0, 6, 2, NIL, NIL);
1236
1237        // Skipping sets the skip cursor.
1238        assert_eq!(Ok(()), receiver.skip());
1239        assert_eq!(1, receiver.pending());
1240        assert_eq!(0, receiver.receivable());
1241        assert_eq!(7, receiver.sent());
1242        assert_eq!(6, receiver.received());
1243        assert_node_next!(pointers, 1, 0);
1244        assert_node_next_nil!(pointers, 0);
1245        assert_node_next!(pointers, 6, 5);
1246        assert_node_next!(pointers, 5, 4);
1247        assert_node_next!(pointers, 4, 3);
1248        assert_node_next!(pointers, 3, 2);
1249        assert_node_next_nil!(pointers, 2);
1250        assert_pointer_nodes!(sender, receiver, 1, 0, 6, 2, 1, 0);
1251
1252        // A skip attempt should return empty and not change the pointers.
1253        assert_eq!(Err(SeccErrors::Empty), receiver.skip());
1254        assert_eq!(1, receiver.pending());
1255        assert_eq!(0, receiver.receivable());
1256        assert_eq!(7, receiver.sent());
1257        assert_eq!(6, receiver.received());
1258        assert_node_next!(pointers, 1, 0);
1259        assert_node_next_nil!(pointers, 0);
1260        assert_node_next!(pointers, 6, 5);
1261        assert_node_next!(pointers, 5, 4);
1262        assert_node_next!(pointers, 4, 3);
1263        assert_node_next!(pointers, 3, 2);
1264        assert_node_next_nil!(pointers, 2);
1265        assert_pointer_nodes!(sender, receiver, 1, 0, 6, 2, 1, 0);
1266
1267        // Sending another item while skipping should work.
1268        assert_eq!(Ok(()), sender.send(Items::B));
1269        assert_eq!(2, receiver.pending());
1270        assert_eq!(1, receiver.receivable());
1271        assert_eq!(8, receiver.sent());
1272        assert_eq!(6, receiver.received());
1273        assert_node_next!(pointers, 1, 0);
1274        assert_node_next!(pointers, 0, 6);
1275        assert_node_next_nil!(pointers, 6);
1276        assert_node_next!(pointers, 5, 4);
1277        assert_node_next!(pointers, 4, 3);
1278        assert_node_next!(pointers, 3, 2);
1279        assert_node_next_nil!(pointers, 2);
1280        assert_pointer_nodes!(sender, receiver, 1, 6, 5, 2, 1, 0);
1281
1282        // Peek will return a reference to cursor's item but not delete it.
1283        assert_eq!(Ok(Items::B), receiver.peek());
1284        assert_eq!(2, receiver.pending());
1285        assert_eq!(1, receiver.receivable());
1286        assert_eq!(8, receiver.sent());
1287        assert_eq!(6, receiver.received());
1288        assert_node_next!(pointers, 1, 0);
1289        assert_node_next!(pointers, 0, 6);
1290        assert_node_next_nil!(pointers, 6);
1291        assert_node_next!(pointers, 5, 4);
1292        assert_node_next!(pointers, 4, 3);
1293        assert_node_next!(pointers, 3, 2);
1294        assert_node_next_nil!(pointers, 2);
1295        assert_pointer_nodes!(sender, receiver, 1, 6, 5, 2, 1, 0);
1296
1297        // Sending another item while skipping and after peeking should work but peek shouldn't
1298        // move to the new node.
1299        assert_eq!(Ok(()), sender.send(Items::C));
1300        assert_eq!(Ok(Items::B), receiver.peek());
1301        assert_eq!(3, receiver.pending());
1302        assert_eq!(2, receiver.receivable());
1303        assert_eq!(9, receiver.sent());
1304        assert_eq!(6, receiver.received());
1305        assert_node_next!(pointers, 1, 0);
1306        assert_node_next!(pointers, 0, 6);
1307        assert_node_next!(pointers, 6, 5);
1308        assert_node_next_nil!(pointers, 5);
1309        assert_node_next!(pointers, 4, 3);
1310        assert_node_next!(pointers, 3, 2);
1311        assert_node_next_nil!(pointers, 2);
1312        assert_pointer_nodes!(sender, receiver, 1, 5, 4, 2, 1, 0);
1313
1314        // Skip again and make sure pointers are right.
1315        assert_eq!(Ok(()), receiver.skip());
1316        assert_node_next!(pointers, 1, 0);
1317        assert_node_next!(pointers, 0, 6);
1318        assert_node_next!(pointers, 6, 5);
1319        assert_node_next_nil!(pointers, 5);
1320        assert_node_next!(pointers, 4, 3);
1321        assert_node_next!(pointers, 3, 2);
1322        assert_node_next_nil!(pointers, 2);
1323        assert_pointer_nodes!(sender, receiver, 1, 5, 4, 2, 0, 6);
1324
1325        // Receive at skip cursor and verify nodes move right.
1326        assert_eq!(Ok(Items::C), receiver.receive());
1327        assert_node_next!(pointers, 1, 0);
1328        assert_node_next!(pointers, 0, 5);
1329        assert_node_next_nil!(pointers, 5);
1330        assert_node_next!(pointers, 4, 3);
1331        assert_node_next!(pointers, 3, 2);
1332        assert_node_next!(pointers, 2, 6);
1333        assert_node_next_nil!(pointers, 6);
1334        assert_pointer_nodes!(sender, receiver, 1, 5, 4, 6, 0, 5);
1335
1336        // If we reset the skip then the cursor is cleared but the rest remains the same.
1337        assert_eq!(Ok(()), receiver.reset_skip());
1338        assert_node_next!(pointers, 1, 0);
1339        assert_node_next!(pointers, 0, 5);
1340        assert_node_next_nil!(pointers, 5);
1341        assert_node_next!(pointers, 4, 3);
1342        assert_node_next!(pointers, 3, 2);
1343        assert_node_next!(pointers, 2, 6);
1344        assert_node_next_nil!(pointers, 6);
1345        assert_pointer_nodes!(sender, receiver, 1, 5, 4, 6, NIL, NIL);
1346
1347        assert_eq!(Ok(()), receiver.skip());
1348        assert_node_next!(pointers, 1, 0);
1349        assert_node_next!(pointers, 0, 5);
1350        assert_node_next_nil!(pointers, 5);
1351        assert_node_next!(pointers, 4, 3);
1352        assert_node_next!(pointers, 3, 2);
1353        assert_node_next!(pointers, 2, 6);
1354        assert_node_next_nil!(pointers, 6);
1355        assert_pointer_nodes!(sender, receiver, 1, 5, 4, 6, 1, 0);
1356
1357        assert_eq!(Ok(Items::B), receiver.receive_and_reset_skip());
1358        assert_node_next!(pointers, 1, 5);
1359        assert_node_next_nil!(pointers, 5);
1360        assert_node_next!(pointers, 4, 3);
1361        assert_node_next!(pointers, 3, 2);
1362        assert_node_next!(pointers, 2, 6);
1363        assert_node_next!(pointers, 6, 0);
1364        assert_node_next_nil!(pointers, 0);
1365        assert_pointer_nodes!(sender, receiver, 1, 5, 4, 0, NIL, NIL);
1366    }
1367
1368    /// Tests that the channel can send and receive messages with separate senders and
1369    /// receivers on different threads.
1370    #[test]
1371    fn test_single_producer_single_receiver() {
1372        let message_count = 200;
1373        let capacity = 32;
1374        let (sender, receiver) = create::<u32>(capacity, Duration::from_millis(20));
1375
1376        let rx = thread::spawn(move || {
1377            let mut count = 0;
1378            while count < message_count {
1379                match receiver.receive_await_timeout(Duration::from_millis(20)) {
1380                    Ok(_v) => count += 1,
1381                    _ => (),
1382                };
1383            }
1384        });
1385
1386        let tx = thread::spawn(move || {
1387            for i in 0..message_count {
1388                sender
1389                    .send_await_timeout(i, Duration::from_millis(20))
1390                    .unwrap();
1391                thread::sleep(Duration::from_millis(1));
1392            }
1393        });
1394
1395        tx.join().unwrap();
1396        rx.join().unwrap();
1397    }
1398
1399    /// Test that if a user attempts to receive before a message is sent, he will be forced
1400    /// to wait for the message.
1401    #[test]
1402    fn test_receive_before_send() {
1403        let (sender, receiver) = create::<u32>(5, Duration::from_millis(20));
1404        let receiver2 = receiver.clone();
1405        let mutex = Arc::new(Mutex::new(false));
1406        let rx_mutex = mutex.clone();
1407
1408        let rx = thread::spawn(move || {
1409            let mut guard = rx_mutex.lock().unwrap();
1410            *guard = true;
1411            drop(guard);
1412            match receiver2.receive_await_timeout(Duration::from_millis(20)) {
1413                Ok(_) => assert!(true),
1414                e => assert!(false, "Error {:?} when receive.", e),
1415            };
1416        });
1417
1418        // Keep trying to lock until the mutex is true meaning receive is ready.
1419        loop {
1420            let guard = mutex.lock().unwrap();
1421            if *guard == true {
1422                break;
1423            }
1424        }
1425
1426        let tx = thread::spawn(move || {
1427            match sender.send_await_timeout(1, Duration::from_millis(20)) {
1428                Ok(_) => assert!(true),
1429                e => assert!(false, "Error {:?} when receive.", e),
1430            };
1431        });
1432
1433        tx.join().unwrap();
1434        rx.join().unwrap();
1435
1436        assert_eq!(1, receiver.sent());
1437        assert_eq!(1, receiver.received());
1438        assert_eq!(0, receiver.pending());
1439        assert_eq!(0, receiver.receivable());
1440    }
1441
1442    /// Tests that triggering send and receive as close to at the same time as possible does
1443    /// not cause any race conditions.
1444    #[test]
1445    fn test_receive_concurrent_send() {
1446        let (sender, receiver) = create::<u32>(5, Duration::from_millis(20));
1447        let receiver2 = receiver.clone();
1448        let pair = Arc::new((Mutex::new((false, false)), Condvar::new()));
1449        let rx_pair = pair.clone();
1450        let tx_pair = pair.clone();
1451
1452        let rx = thread::spawn(move || {
1453            let mut guard = rx_pair.0.lock().unwrap();
1454            guard.0 = true;
1455            let c_guard = rx_pair.1.wait(guard).unwrap();
1456            drop(c_guard);
1457            match receiver2.receive_await_timeout(Duration::from_millis(20)) {
1458                Ok(_) => assert!(true),
1459                e => assert!(false, "Error {:?} when receive.", e),
1460            };
1461        });
1462        let tx = thread::spawn(move || {
1463            let mut guard = tx_pair.0.lock().unwrap();
1464            guard.1 = true;
1465            let c_guard = tx_pair.1.wait(guard).unwrap();
1466            drop(c_guard);
1467            match sender.send_await_timeout(1 as u32, Duration::from_millis(20)) {
1468                Ok(_) => assert!(true),
1469                e => assert!(false, "Error {:?} when receive.", e),
1470            };
1471        });
1472
1473        // Wait until both threads are ready and waiting.
1474        loop {
1475            let guard = pair.0.lock().unwrap();
1476            if guard.0 && guard.1 {
1477                break;
1478            }
1479        }
1480
1481        let guard = pair.0.lock().unwrap();
1482        pair.1.notify_all();
1483        drop(guard);
1484
1485        tx.join().unwrap();
1486        rx.join().unwrap();
1487
1488        assert_eq!(1, receiver.sent());
1489        assert_eq!(1, receiver.received());
1490        assert_eq!(0, receiver.pending());
1491        assert_eq!(0, receiver.receivable());
1492    }
1493
1494    /// Creates a thread that will send a clone of the `message` passed until the `sender.send()`
1495    /// reaches the given count. The `pair` is used to trigger the thread to start when the
1496    /// Condvar notifies the thread.
1497    fn counted_sender<T: Sync + Send + Clone + 'static>(
1498        sender: SeccSender<T>,
1499        pair: Arc<(Mutex<bool>, Condvar)>,
1500        message: T,
1501        count: usize,
1502    ) -> JoinHandle<()> {
1503        thread::spawn(move || {
1504            let (ref mutex, ref condvar) = &*pair;
1505            let mut started = mutex.lock().unwrap();
1506            while !*started {
1507                started = condvar.wait(started).unwrap();
1508            }
1509            drop(started);
1510
1511            while sender.sent() < count {
1512                let _ = sender.send_await_timeout(message.clone(), Duration::from_millis(10));
1513            }
1514        })
1515    }
1516
1517    /// Creates a thread that will receive a `message` until the `receiver.received()` reaches
1518    /// the given count. The `pair` is used to trigger the thread to start when the Condvar
1519    /// notifies the thread.
1520    fn counted_receiver<T: Sync + Send + Clone + 'static>(
1521        receiver: SeccReceiver<T>,
1522        pair: Arc<(Mutex<bool>, Condvar)>,
1523        count: usize,
1524    ) -> JoinHandle<()> {
1525        thread::spawn(move || {
1526            let (ref mutex, ref condvar) = &*pair;
1527            let mut started = mutex.lock().unwrap();
1528            while !*started {
1529                started = condvar.wait(started).unwrap();
1530            }
1531            drop(started);
1532
1533            while receiver.received() < count {
1534                let _ = receiver.receive_await_timeout(Duration::from_millis(10));
1535            }
1536        })
1537    }
1538
1539    /// A helper for creating tests with multiple senders and receivers.
1540    fn multiple_thread_helper<T: Sync + Send + Clone + 'static>(
1541        receiver_count: u8,
1542        sender_count: u8,
1543        message_count: usize,
1544        time_limit: Duration,
1545        message: T,
1546    ) {
1547        let (sender, receiver) = create::<T>(10, Duration::from_millis(1));
1548        let pair = Arc::new((Mutex::new(false), Condvar::new()));
1549        let total_thread_count: usize = receiver_count as usize + sender_count as usize;
1550        let mut handles: Vec<JoinHandle<()>> = Vec::with_capacity(total_thread_count);
1551
1552        for _ in 0..receiver_count {
1553            handles.push(counted_receiver(
1554                receiver.clone(),
1555                pair.clone(),
1556                message_count,
1557            ));
1558        }
1559
1560        for _ in 0..sender_count {
1561            handles.push(counted_sender(
1562                sender.clone(),
1563                pair.clone(),
1564                message.clone(),
1565                message_count,
1566            ));
1567        }
1568
1569        // We will wait a short time to make sure all threads are ready to go.
1570        thread::sleep(Duration::from_millis(10));
1571
1572        // Notify the `Condvar`, triggering all threads to start but then drop the `Mutex` to
1573        // avoid any potential deadlock in the test.
1574        let (ref mutex, ref condvar) = &*pair;
1575        let mut started = mutex.lock().unwrap();
1576        *started = true;
1577        condvar.notify_all();
1578        drop(started);
1579
1580        // Start a timer that will fail if the test takes too long. This could fail if there
1581        // is some sort of live lock or deadlock in the code.
1582        let start = Instant::now();
1583        while sender.sent() < message_count && receiver.received() < message_count {
1584            if Instant::elapsed(&start) > time_limit {
1585                panic!("Test took more than {:?} ms to run!", time_limit);
1586            }
1587        }
1588
1589        // Wait for all of the thread handles to join before concluding the test.
1590        for handle in handles {
1591            handle.join().unwrap();
1592        }
1593    }
1594
1595    /// Tests channel under multiple receivers and a single sender.
1596    #[test]
1597    fn test_multiple_receiver_single_sender() {
1598        multiple_thread_helper(2, 1, 10_000, Duration::from_millis(1000), 7 as u32);
1599    }
1600
1601    /// Tests channel under multiple senders and a single receiver.
1602    #[test]
1603    fn test_multiple_sender_single_receiver() {
1604        multiple_thread_helper(1, 3, 10_000, Duration::from_millis(1000), 7 as u32);
1605    }
1606
1607    /// Tests channel under multiple receivers and a multiple senders.
1608    #[test]
1609    fn test_multiple_receiver_multiple_sender() {
1610        multiple_thread_helper(3, 3, 10_000, Duration::from_millis(1000), 7 as u32);
1611    }
1612
1613}