Crate blink_channel

source ·
Expand description

Fast, Lock-free, Bounded, Lossy broadcast channel. This is implemented with ring buffer and atomic operations, which provide us with lock-free behavior with no extra dependencies.

The API of the blink-channel is similar to that of the std::sync::mpsc channels. However, there are some differences:

  • It allows for multiple consumers (receivers) and multiple prodocuers (senders).
  • The channel broadcasts every send to every consumer.
  • Lossy, the sender will overwrite old data, so receivers must be quick or they will lose the old data (don’ t blink).
  • Implemented for no_std environments.

The data sent must implment Clone, because it will be kept in the buffer, and readers can read it multiple times.

The original object will remain in the buffer until its overwritten, at that point it will be dropped. Thus be careful if the value is a large allocation for example big Arc. One of the clones (original) will be kept by the buffer and will result in a delayed deallocation if that was not expected by the user. See issue #1

§Example

Single sender multiple receivers

use blink_channel::channel;

let (sender, mut receiver1) = channel::<i32, 4>();
sender.send(1);
sender.send(2);

let mut receiver2 = receiver1.clone();

assert_eq!(receiver1.recv(), Some(1));
assert_eq!(receiver1.recv(), Some(2));
assert_eq!(receiver1.recv(), None);

assert_eq!(receiver2.recv(), Some(1));
assert_eq!(receiver2.recv(), Some(2));
assert_eq!(receiver2.recv(), None);

Multiple senders multiple receivers

use blink_channel::channel;
use std::thread;
let (sender1, mut receiver1) = channel::<i32, 100>();
let sender2 = sender1.clone();

let t1 = thread::spawn(move || {
    for i in 0..50 {
        sender1.send(i);
    }
});
let t2 = thread::spawn(move || {
    for i in 0..50 {
        sender2.send(i);
    }
});

t1.join().unwrap();
t2.join().unwrap();

let mut receiver2 = receiver1.clone();

let mut sum1 = 0;
let mut sum2 = 0;
for i in 0..100 {
   let v1 = receiver1.recv().unwrap();
   let v2 = receiver2.recv().unwrap();
   sum1 += v1;
   sum2 += v2;
   assert_eq!(v1, v2);
}
assert_eq!(sum1, 49 * 50);
assert_eq!(sum2, 49 * 50);

Structs§

Functions§