util.rs

 1use std::ops::Deref;
 2use std::sync::mpsc::Sender;
 3
 4use parking_lot::Mutex;
 5use thread_local::ThreadLocal;
 6
 7/// Unbounded standard library sender which is stored per thread to get around
 8/// the lack of sync on the standard library version while still being unbounded
 9/// Note: this locks on the cloneable sender, but its done once per thread, so it
10/// shouldn't result in too much contention
11pub struct UnboundedSyncSender<T: Send> {
12    cloneable_sender: Mutex<Sender<T>>,
13    local_senders: ThreadLocal<Sender<T>>,
14}
15
16impl<T: Send> UnboundedSyncSender<T> {
17    pub fn new(sender: Sender<T>) -> Self {
18        Self {
19            cloneable_sender: Mutex::new(sender),
20            local_senders: ThreadLocal::new(),
21        }
22    }
23}
24
25impl<T: Send> Deref for UnboundedSyncSender<T> {
26    type Target = Sender<T>;
27
28    fn deref(&self) -> &Self::Target {
29        self.local_senders
30            .get_or(|| self.cloneable_sender.lock().clone())
31    }
32}