sync: revert Clone impl for broadcast::Receiver (#3020)

The `Receiver` handle maintains a position in the broadcast channel for
itself. Cloning implies copying the state of the value. Intuitively,
cloning a `broadcast::Receiver` would return a new receiver with an
identical position. However, the current implementation returns a new
`Receiver` positioned at the tail of the channel.

This behavior subtlety is why `new_subscriber()` is used to create
`Receiver` handles. An alternate API should consider the position issue.

Refs: #2933
This commit is contained in:
Carl Lerche
2020-10-21 15:14:52 -07:00
committed by GitHub
parent b48fec9655
commit 8bfb1c92ce
2 changed files with 2 additions and 11 deletions
+1 -9
View File
@@ -405,8 +405,7 @@ const MAX_RECEIVERS: usize = usize::MAX >> 2;
///
/// The `Sender` can be cloned to `send` to the same channel from multiple
/// points in the process or it can be used concurrently from an `Arc`. New
/// `Receiver` handles can be cloned from an existing `Receiver` or created by
/// calling [`Sender::subscribe`].
/// `Receiver` handles are created by calling [`Sender::subscribe`].
///
/// If all [`Receiver`] handles are dropped, the `send` method will return a
/// [`SendError`]. Similarly, if all [`Sender`] handles are dropped, the [`recv`]
@@ -985,13 +984,6 @@ impl<T: Clone> Receiver<T> {
}
}
impl<T> Clone for Receiver<T> {
fn clone(&self) -> Self {
let shared = self.shared.clone();
new_receiver(shared)
}
}
impl<T> Drop for Receiver<T> {
fn drop(&mut self) {
let mut tail = self.shared.tail.lock();
+1 -2
View File
@@ -92,12 +92,11 @@ fn broadcast_two() {
});
}
// Exercise the Receiver Clone impl as well
#[test]
fn broadcast_wrap() {
loom::model(|| {
let (tx, mut rx1) = broadcast::channel(2);
let mut rx2 = rx1.clone();
let mut rx2 = tx.subscribe();
let th1 = thread::spawn(move || {
block_on(async {