|
114 | 114 | use crate::sync::notify::Notify;
|
115 | 115 |
|
116 | 116 | use crate::loom::sync::atomic::AtomicUsize;
|
117 |
| -use crate::loom::sync::atomic::Ordering::Relaxed; |
| 117 | +use crate::loom::sync::atomic::Ordering::{AcqRel, Relaxed}; |
118 | 118 | use crate::loom::sync::{Arc, RwLock, RwLockReadGuard};
|
119 | 119 | use std::fmt;
|
120 | 120 | use std::mem;
|
@@ -146,6 +146,16 @@ pub struct Sender<T> {
|
146 | 146 | shared: Arc<Shared<T>>,
|
147 | 147 | }
|
148 | 148 |
|
| 149 | +impl<T> Clone for Sender<T> { |
| 150 | + fn clone(&self) -> Self { |
| 151 | + self.shared.ref_count_tx.fetch_add(1, Relaxed); |
| 152 | + |
| 153 | + Self { |
| 154 | + shared: self.shared.clone(), |
| 155 | + } |
| 156 | + } |
| 157 | +} |
| 158 | + |
149 | 159 | /// Returns a reference to the inner value.
|
150 | 160 | ///
|
151 | 161 | /// Outstanding borrows hold a read lock on the inner value. This means that
|
@@ -238,6 +248,9 @@ struct Shared<T> {
|
238 | 248 | /// Tracks the number of `Receiver` instances.
|
239 | 249 | ref_count_rx: AtomicUsize,
|
240 | 250 |
|
| 251 | + /// Tracks the number of `Sender` instances. |
| 252 | + ref_count_tx: AtomicUsize, |
| 253 | + |
241 | 254 | /// Notifies waiting receivers that the value changed.
|
242 | 255 | notify_rx: big_notify::BigNotify,
|
243 | 256 |
|
@@ -485,6 +498,7 @@ pub fn channel<T>(init: T) -> (Sender<T>, Receiver<T>) {
|
485 | 498 | value: RwLock::new(init),
|
486 | 499 | state: AtomicState::new(),
|
487 | 500 | ref_count_rx: AtomicUsize::new(1),
|
| 501 | + ref_count_tx: AtomicUsize::new(1), |
488 | 502 | notify_rx: big_notify::BigNotify::new(),
|
489 | 503 | notify_tx: Notify::new(),
|
490 | 504 | });
|
@@ -1302,8 +1316,10 @@ impl<T> Sender<T> {
|
1302 | 1316 |
|
1303 | 1317 | impl<T> Drop for Sender<T> {
|
1304 | 1318 | fn drop(&mut self) {
|
1305 |
| - self.shared.state.set_closed(); |
1306 |
| - self.shared.notify_rx.notify_waiters(); |
| 1319 | + if self.shared.ref_count_tx.fetch_sub(1, AcqRel) == 1 { |
| 1320 | + self.shared.state.set_closed(); |
| 1321 | + self.shared.notify_rx.notify_waiters(); |
| 1322 | + } |
1307 | 1323 | }
|
1308 | 1324 | }
|
1309 | 1325 |
|
|
0 commit comments