-
Notifications
You must be signed in to change notification settings - Fork 340
awaiting a spawn_local JoinHandle is not Send even if the Output is Send #960
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@Fishrock123 the title of this issue mentions |
Hmm, yeah looking at your example now and I'm really unsure what's causing this. This indeed seems like the compiler may be incorrectly passing along the This is probably worth opening on issue for on the compiler so the working group can triage it! |
Sorry, I must have mistyped. This is about |
relevant: rust-lang/rust#71072 — is the goal specifically to hold a std::sync::MutexGuard across an await boundary, or is that just how you're building a !Send future? The problem goes away if you use async_std::sync::Mutex. Is it safe to reduce this example to just "any !Send future?" |
if it's just about a !Send future, here's a simpler repro: use async_std::future::ready;
use async_std::task::{self, block_on, spawn, spawn_local};
use std::rc::Rc;
pub fn main() {
block_on(async {
spawn(async {
spawn_local(async {
ready(Rc::new(())).await;
})
.await
})
.await;
})
} |
Oh, huh. I never thought to try |
My specific problem was regarding a |
Agreed on the output, plus I think it should be possible to await the task representing a !Send future from within a Send future, but maybe that hasn't been implemented yet. I think it'd require some indirection like using a channel instead of directly awaiting the inner task. We can achieve that result that in user code like this, but it seems like something async-std could do: use async_std::channel;
use async_std::future::ready;
use async_std::task::{block_on, spawn, spawn_local};
use std::rc::Rc;
pub fn main() {
block_on(async {
spawn(async {
let (tx, rx) = channel::bounded(1);
spawn_local(async move {
ready(Rc::new(())).await;
tx.send(()).await.unwrap();
});
rx.recv().await.unwrap();
})
.await;
})
} |
To be clear - I am not 100% sure if this is supposed to work, but I think I have reason to believe it reasonably should work.
I have an example at https://gist.github.com/Fishrock123/82e742454a844914513be49738e4a34e where a
Mutex
inside anArc
is moved into aspawn_local
from an outertask::spawn
, but fails to compile with this error:This is strange, because I am going through the effort to prevent exactly this, by only accessing the
Mutex
from within aspawn_local
. This seems to only occur if theMutex
'd struct has an async function called from it. In my case, that's happening with&mut self
. I believe that an async function at this point should not requireSend
, since it is all running within the same thread, absent any othertask::spawn
s, but I guess it does, for some reason? The error is particularly bizarre, and probably also a compiler output bug, because it seems to refer to the wrong things in general.The example also compiles if the outer
task::spawn
is alsospawn_local
, which is undesirable in the actual code this example is based off of (I want a thread / threadpool for a queue reading client).The text was updated successfully, but these errors were encountered: