mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-09-28 12:10:37 +00:00
Make Barrier::wait future Send (#1611)
It wasn't before. Now it is. And that is better.
This commit is contained in:
parent
159abb375f
commit
611b4e11a7
@ -83,22 +83,26 @@ impl Barrier {
|
||||
// deadlock even if another future is concurrently holding the lock.
|
||||
// It is _desireable_ to do so as synchronous Mutexes are, at least in theory, faster than
|
||||
// the asynchronous counter-parts, so we should use them where possible [citation needed].
|
||||
let mut state = self.state.lock().unwrap();
|
||||
let generation = state.generation;
|
||||
state.arrived += 1;
|
||||
if state.arrived == self.n {
|
||||
// we are the leader for this generation
|
||||
// wake everyone, increment the generation, and return
|
||||
state
|
||||
.waker
|
||||
.broadcast(state.generation)
|
||||
.expect("there is at least one receiver");
|
||||
state.arrived = 0;
|
||||
state.generation += 1;
|
||||
return BarrierWaitResult(true);
|
||||
}
|
||||
// NOTE: the extra scope here is so that the compiler doesn't think `state` is held across
|
||||
// a yield point, and thus marks the returned future as !Send.
|
||||
let generation = {
|
||||
let mut state = self.state.lock().unwrap();
|
||||
let generation = state.generation;
|
||||
state.arrived += 1;
|
||||
if state.arrived == self.n {
|
||||
// we are the leader for this generation
|
||||
// wake everyone, increment the generation, and return
|
||||
state
|
||||
.waker
|
||||
.broadcast(state.generation)
|
||||
.expect("there is at least one receiver");
|
||||
state.arrived = 0;
|
||||
state.generation += 1;
|
||||
return BarrierWaitResult(true);
|
||||
}
|
||||
|
||||
drop(state);
|
||||
generation
|
||||
};
|
||||
|
||||
// we're going to have to wait for the last of the generation to arrive
|
||||
let mut wait = self.wait.clone();
|
||||
|
@ -4,6 +4,13 @@ use tokio_sync::Barrier;
|
||||
use tokio_test::task::spawn;
|
||||
use tokio_test::{assert_pending, assert_ready};
|
||||
|
||||
struct IsSend<T: Send>(T);
|
||||
#[test]
|
||||
fn barrier_future_is_send() {
|
||||
let b = Barrier::new(0);
|
||||
IsSend(b.wait());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zero_does_not_block() {
|
||||
let b = Barrier::new(0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user