Skip to content

Commit a5ff8df

Browse files
authored
bugfix: Ensure that ex.run() produces a Send future
This commit makes sure that the run() and tick() functions produce futures that are Send and Sync, to prevent a regression introduced in PR #37. Tests are also added to prevent this regression in the future. Signed-off-by: John Nunley <[email protected]>
1 parent e195733 commit a5ff8df

File tree

1 file changed

+37
-3
lines changed

1 file changed

+37
-3
lines changed

src/lib.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ impl<'a> Executor<'a> {
269269
// Try to push into the local queue.
270270
LocalQueue::with(|local_queue| {
271271
// Make sure that we don't accidentally push to an executor that isn't ours.
272-
if !std::ptr::eq(local_queue.state, &*state) {
272+
if local_queue.state != &*state as *const State as usize {
273273
return;
274274
}
275275

@@ -858,7 +858,7 @@ struct LocalQueue {
858858
/// The pointer to the state of the executor.
859859
///
860860
/// Used to make sure we don't push runnables to the wrong executor.
861-
state: *const State,
861+
state: usize,
862862

863863
/// The concurrent queue.
864864
queue: Arc<ConcurrentQueue<Runnable>>,
@@ -889,7 +889,7 @@ impl LocalQueue {
889889
let mut old = with_waker(|waker| {
890890
LOCAL_QUEUE.with(move |slot| {
891891
slot.borrow_mut().replace(LocalQueue {
892-
state: state as *const State,
892+
state: state as *const State as usize,
893893
queue: queue.clone(),
894894
waker: waker.clone(),
895895
})
@@ -1052,3 +1052,37 @@ fn with_waker<F: FnOnce(&Waker) -> R, R>(f: F) -> impl Future<Output = R> {
10521052
Poll::Ready(f(cx.waker()))
10531053
})
10541054
}
1055+
1056+
fn _ensure_send_and_sync() {
1057+
use futures_lite::future::pending;
1058+
1059+
fn is_send<T: Send>(_: T) {}
1060+
fn is_sync<T: Sync>(_: T) {}
1061+
1062+
is_send::<Executor<'_>>(Executor::new());
1063+
is_sync::<Executor<'_>>(Executor::new());
1064+
1065+
let ex = Executor::new();
1066+
is_send(ex.run(pending::<()>()));
1067+
is_sync(ex.run(pending::<()>()));
1068+
is_send(ex.tick());
1069+
is_sync(ex.tick());
1070+
1071+
/// ```compile_fail
1072+
/// use async_executor::LocalExecutor;
1073+
/// use futures_lite::future::pending;
1074+
///
1075+
/// fn is_send<T: Send>(_: T) {}
1076+
/// fn is_sync<T: Sync>(_: T) {}
1077+
///
1078+
/// is_send::<LocalExecutor<'_>>(LocalExecutor::new());
1079+
/// is_sync::<LocalExecutor<'_>>(LocalExecutor::new());
1080+
///
1081+
/// let ex = LocalExecutor::new();
1082+
/// is_send(ex.run(pending::<()>()));
1083+
/// is_sync(ex.run(pending::<()>()));
1084+
/// is_send(ex.tick());
1085+
/// is_sync(ex.tick());
1086+
/// ```
1087+
fn _negative_test() {}
1088+
}

0 commit comments

Comments
 (0)