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