Skip to content

Commit b0bbf16

Browse files
authored
[workerd-cxx] remove + Send from futures (#41)
We don't want c++ promises to be shared between different threads.
1 parent bd77fec commit b0bbf16

File tree

5 files changed

+10
-29
lines changed

5 files changed

+10
-29
lines changed

kj-rs/awaiter.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,6 @@ use std::task::Context;
55
use crate::ffi::{GuardedRustPromiseAwaiter, GuardedRustPromiseAwaiterRepr};
66
use crate::waker::try_into_kj_waker_ptr;
77

8-
// =======================================================================================
9-
// GuardedRustPromiseAwaiter
10-
11-
// Safety: KJ Promises are not associated with threads, but with event loops at construction time.
12-
// Therefore, they can be polled from any thread, as long as that thread has the correct event loop
13-
// active at the time of the call to `poll()`. If the correct event loop is not active,
14-
// GuardedRustPromiseAwaiter's API will panic. (The Guarded- prefix refers to the C++ class template
15-
// ExecutorGuarded, which enforces the correct event loop requirement.)
16-
unsafe impl Send for GuardedRustPromiseAwaiter {}
17-
188
// =======================================================================================
199
// Await syntax for OwnPromiseNode
2010

kj-rs/future.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,19 @@ pub(crate) mod repr {
3838

3939
type DropCallback = unsafe extern "C" fn(fut: *mut c_void);
4040

41-
type FuturePtr<'a, T> = *mut (dyn Future<Output = Result<T, String>> + Send + 'a);
41+
type FuturePtr<'a, T> = *mut (dyn Future<Output = Result<T, String>> + 'a);
4242

43-
/// Represents a `dyn Future<Output = Result<T, String>>` + Send.
43+
/// Represents a `dyn Future<Output = Result<T, String>>`.
4444
#[repr(C)]
4545
pub struct RustFuture<'a, T> {
4646
pub fut: FuturePtr<'a, T>,
4747
pub poll: PollCallback,
4848
pub drop: DropCallback,
4949
}
5050

51-
type InfallibleFuturePtr<'a, T> = *mut (dyn Future<Output = T> + Send + 'a);
51+
type InfallibleFuturePtr<'a, T> = *mut (dyn Future<Output = T> + 'a);
5252

53-
/// Represents a `dyn Future<Output = T> + Send` where T is not a Result.
53+
/// Represents a `dyn Future<Output = T>` where T is not a Result.
5454
#[repr(C)]
5555
pub struct RustInfallibleFuture<'a, T> {
5656
pub fut: InfallibleFuturePtr<'a, T>,
@@ -127,7 +127,7 @@ pub(crate) mod repr {
127127

128128
#[must_use]
129129
pub fn future<'a, T: Unpin>(
130-
fut: Pin<Box<dyn Future<Output = Result<T, String>> + Send + 'a>>,
130+
fut: Pin<Box<dyn Future<Output = Result<T, String>> + 'a>>,
131131
) -> RustFuture<'a, T> {
132132
let fut = Box::into_raw(unsafe { Pin::into_inner_unchecked(fut) });
133133
let poll = RustFuture::<T>::poll;
@@ -137,7 +137,7 @@ pub(crate) mod repr {
137137

138138
#[must_use]
139139
pub fn infallible_future<'a, T: Unpin>(
140-
fut: Pin<Box<dyn Future<Output = T> + Send + 'a>>,
140+
fut: Pin<Box<dyn Future<Output = T> + 'a>>,
141141
) -> RustInfallibleFuture<'a, T> {
142142
let fut = Box::into_raw(unsafe { Pin::into_inner_unchecked(fut) });
143143
let poll = RustInfallibleFuture::<T>::poll;

kj-rs/promise.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,6 @@ type CxxResult<T> = std::result::Result<T, cxx::Exception>;
1919
#[repr(transparent)]
2020
pub struct OwnPromiseNode(*mut c_void /* kj::_::PromiseNode* */);
2121

22-
// Safety: KJ Promises are not associated with threads, but with event loops at construction time.
23-
// Therefore, they can be polled from any thread, as long as that thread has the correct event loop
24-
// active at the time of the call to `poll()`. If the correct event loop is not active, the
25-
// OwnPromiseNode's API will typically panic, undefined behavior could be possible. However, Rust
26-
// doesn't have direct access to OwnPromiseNode's API. Instead, it can only use the Promise by
27-
// having GuardedRustPromiseAwaiter consume it, and GuardedRustPromiseAwaiter implements the
28-
// correct-executor guarantee.
29-
unsafe impl Send for OwnPromiseNode {}
30-
3122
// Note: drop is not the only way for OwnPromiseNode to be destroyed.
3223
// It is forgotten using `MaybeUninit` and its ownership passed over to c++ in `unwrap`.
3324
impl Drop for OwnPromiseNode {

kj-rs/tests/test_futures.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ pub async fn new_layered_ready_future_void() -> Result<()> {
150150

151151
// From example at https://doc.rust-lang.org/std/future/fn.poll_fn.html#capturing-a-pinned-state
152152
async fn naive_select<T>(
153-
a: impl Future<Output = T> + Send,
154-
b: impl Future<Output = T> + Send,
153+
a: impl Future<Output = T>,
154+
b: impl Future<Output = T>,
155155
) -> T {
156156
let (mut a, mut b) = (pin!(a), pin!(b));
157157
future::poll_fn(move |cx| {

macro/src/expand.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,9 +1281,9 @@ fn expand_rust_function_shim_super(
12811281
};
12821282

12831283
if fut.throws_tokens.is_some() {
1284-
quote!(-> std::pin::Pin<Box<dyn ::std::future::Future<Output = ::std::result::Result<#output, String>> + Send #lifetimes>>)
1284+
quote!(-> std::pin::Pin<Box<dyn ::std::future::Future<Output = ::std::result::Result<#output, String>> #lifetimes>>)
12851285
} else {
1286-
quote!(-> std::pin::Pin<Box<dyn ::std::future::Future<Output = #output> + Send #lifetimes>>)
1286+
quote!(-> std::pin::Pin<Box<dyn ::std::future::Future<Output = #output> #lifetimes>>)
12871287
}
12881288
} else {
12891289
expand_return_type(&sig.ret)

0 commit comments

Comments
 (0)