Skip to content

Commit

Permalink
sync: use intrusive list strategy for broadcast (#2509)
Browse files Browse the repository at this point in the history
Previously, in the broadcast channel, receiver wakers were passed to the
sender via an atomic stack with allocated nodes. When a message was
sent, the stack was drained. This caused a problem when many receivers
pushed a waiter node then dropped. The waiter node remained indefinitely
in cases where no values were sent.

This patch switches broadcast to use the intrusive linked-list waiter
strategy used by `Notify` and `Semaphore.
  • Loading branch information
carllerche committed May 12, 2020
1 parent a32f918 commit fb7dfcf
Show file tree
Hide file tree
Showing 4 changed files with 455 additions and 134 deletions.
4 changes: 0 additions & 4 deletions tokio/src/loom/std/atomic_ptr.rs
Expand Up @@ -11,10 +11,6 @@ impl<T> AtomicPtr<T> {
let inner = std::sync::atomic::AtomicPtr::new(ptr);
AtomicPtr { inner }
}

pub(crate) fn with_mut<R>(&mut self, f: impl FnOnce(&mut *mut T) -> R) -> R {
f(self.inner.get_mut())
}
}

impl<T> Deref for AtomicPtr<T> {
Expand Down
2 changes: 1 addition & 1 deletion tokio/src/sync/batch_semaphore.rs
Expand Up @@ -186,7 +186,7 @@ impl Semaphore {

/// Release `rem` permits to the semaphore's wait list, starting from the
/// end of the queue.
///
///
/// If `rem` exceeds the number of permits needed by the wait list, the
/// remainder are assigned back to the semaphore.
fn add_permits_locked(&self, mut rem: usize, waiters: MutexGuard<'_, Waitlist>) {
Expand Down

0 comments on commit fb7dfcf

Please sign in to comment.