←back to thread

517 points bkolobara | 5 comments | | HN request time: 0s | source
Show context
Spivak ◴[] No.45041771[source]
How do you encode the locking issue in the type system, it seems magical? Can you just never hold any locks when calling await, is it smart enough to know that this scheduler might move work between threads?
replies(5): >>45041806 #>>45041833 #>>45041852 #>>45041891 #>>45041898 #
1. jvanderbot ◴[] No.45041806[source]
Yes Rust has ways of verifying single access to locks through the borrow checker and lifetimes.
replies(1): >>45041860 #
2. Spivak ◴[] No.45041860[source]
Well yes but this seems more complicated. If the code was executed on a single thread it would be correct. The compiler somehow knows that await might move the work to another thread in which the code would still be correct if it weren't for the pesky undefined behavior. At all points it seems like it would be single access and yet it catches this.
replies(3): >>45042126 #>>45042240 #>>45042247 #
3. 0x1ceb00da ◴[] No.45042126[source]
An async function call returns a future which is an object holding the state of the async computation. Multithreaded runtimes like tokio require this future to be `Send`, which means it can be moved from one thread to another. The future generated by the compiler is not Send if there is a local variable crossing an await boundary that is not `Send`.
4. ViewTrick1002 ◴[] No.45042240[source]
That comes from the where the tokio task is spawned annotating the future with send.

https://docs.rs/tokio/latest/tokio/task/fn.spawn.html

If you want to run everything on the same thread then localset enables that. See how the spawn function does not include the send bound.

https://docs.rs/tokio/latest/tokio/task/struct.LocalSet.html

5. veber-alex ◴[] No.45042247[source]
The compiler doesn't know anything about threads.

The compiler knows the Future doesn't implement the Send trait because MutexGuard is not Send and it crosses await points.

Then, tokio the aysnc runtime requires that futures that it runs are Send because it can move them to another thread.

This is how Rust safety works. The internals of std, tokio and other low level libraries are unsafe but they expose interfaces that are impossible to misuse.