shared_sender.rs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. /// A `std::sync::mpsc::Sender` that is also `Sync`.
  2. ///
  3. /// The builtin `Sender` is not sync, because it uses internal mutability to
  4. /// implement an optimization for non-shared one-shot sending. The queue that
  5. /// backs the sender initially accepts only one item from a single producer.
  6. /// If the sender is cloned, the internal queue turns into a multi-producer
  7. /// multi-shot queue. After that, the internal mutability is never invoked
  8. /// again for the sender. The `Sender` structure becomes essentially immutable
  9. /// and thus, `Sync`.
  10. ///
  11. /// This optimization, and the internal mutability is meaningless for the
  12. /// purpose of this crate. `SharedSender` forces the transition into a shared
  13. /// queue, and declares itself `Sync`.
  14. ///
  15. /// Note that the same reasoning does not apply to the `Receiver`. There are
  16. /// more levels of mutability in the `Receiver`.
  17. #[derive(Debug)]
  18. pub struct SharedSender<T>(std::sync::mpsc::Sender<T>);
  19. unsafe impl<T> Sync for SharedSender<T> where T: Sync {}
  20. // A better way to implement this might be the following.
  21. //
  22. // unsafe impl<T> Sync for SharedSender<T> where
  23. // std::sync::mpsc::Flavor<T>::Shared: Sync {}
  24. impl<T> SharedSender<T> {
  25. /// Create a shared sender.
  26. pub fn new(inner: std::sync::mpsc::Sender<T>) -> SharedSender<T> {
  27. // Force the transition to a shared queue in Sender.
  28. let _clone = inner.clone();
  29. SharedSender(inner)
  30. }
  31. /// A proxy to `std::syc::mpsc::Sender::send()`.
  32. pub fn send(&self, t: T) -> Result<(), std::sync::mpsc::SendError<T>> {
  33. self.0.send(t)
  34. }
  35. }
  36. impl<T> From<std::sync::mpsc::Sender<T>> for SharedSender<T> {
  37. fn from(inner: std::sync::mpsc::Sender<T>) -> Self {
  38. Self::new(inner)
  39. }
  40. }
  41. impl<T> From<SharedSender<T>> for std::sync::mpsc::Sender<T> {
  42. fn from(this: SharedSender<T>) -> Self {
  43. this.0
  44. }
  45. }
  46. impl<T> Clone for SharedSender<T> {
  47. fn clone(&self) -> Self {
  48. Self(self.0.clone())
  49. }
  50. }