Earlier quoted context omitted.
The ideas that have been batted around is called "async drop" [1] And it looks like it's still just an unaddressed well known problem [2]. Honestly, once the Mozilla sackening of rust devs happened it seems like the language has been practically rudderless. The RFC system seems almost dead as a lot of the main contributors are no longer working on rust. This initiative hasn't had motion since 2021. [3] [1] https://ru…
While the Mozilla layoffs were a stressful time with a lot of uncertainty involved, in the end it hasn't appeared to have had a deleterious effect on Rust development. Today the activity in the Rust repo is as high as it's ever been ( https://github.com/rust-lang/rust/graphs/contributors ) and the governance of the project is more organized and healthy than it's ever been ( https://blog.rust-lang.org/2025/10/15/annou…
Futurelock: A subtle risk in async Rust
241–250 of 251 posts
Re: Futurelock: A subtle risk in async Rust
#242Earlier quoted context omitted.
In fairness, if you're a layman to the rust development process (as I am, so I'm speaking from personal experience here) it's damn near impossible to figure out the status of things. There tracking issues, RFCs, etc which is very confusing as an outsider and gives no obvious place to look to find out the current status of a proposal. I'm sure there is a logic to it and that if I spent the time to learn it would make…
If you want to find out the status of something, the best bet is to go to the Rust Zulip and ask around: https://rust-lang.zulipchat.com/ . Most Rust initiatives are pushed forward by volunteers who are happy to talk about what they're working on, but who only periodically write status reports on tracking issues (usually in response to someone asking them what the status is). Rust isn't a company where documentation…
Re: Futurelock: A subtle risk in async Rust
#243Earlier quoted context omitted.
Since you are of of the people working directly on this codebase, may I ask you why is select! being used/allowed in the first place? Its footgun-y nature has been known for years (IIRC even the first version of the tokio documentation warned against that) and as such I don't really understand why people are still using it. (For context I was the lead of a Rust team working on a pretty complex async networking progra…
What to use instead?
Edit: tokio docs actually provide several suggestions: https://docs.rs/tokio/latest/tokio/macro.select.html#alterna...
Re: Futurelock: A subtle risk in async Rust
#244Earlier quoted context omitted.
From my understanding this talk describes how he implemented a solution for a similar problem https://www.youtube.com/watch?v=Kvsvd67XUKw I'm saying if you're not writing multi-threaded code everyday, use a library. It can use atomics/locks but you shouldn't use it directly. If the library is designed well it'd be impossible to deadlock.
If you take programming serious, learn it. With a library that encapsulates a low number of patterns (like message passing) you'll be very limited. If you never start learning about lower level multi-threading issues you'll never learn it. And it's not _that_ hard. I'm not writing multi threaded every day (by far), but often enough that I can write useful things (using shared memory, atomics, mutexes, condition varia…
A problem with writing an article is that if I don't show real code, people might think I'm exaggerating; if I do show real code, it'd look like I'm calling someone a bad programmer
Re: Futurelock: A subtle risk in async Rust
#245Earlier quoted context omitted.
I completely disagree with you and I do write performance code (but not specifically HPC) and my current day job is highly async code with a GUI
Are you saying GUIs in general don't need multithreading or just that you think you haven't needed it so far? Or that you use some high-level async framework that hides just the synchronisation bits (at the cost of async type complexity)?
Re: Futurelock: A subtle risk in async Rust
#246Earlier quoted context omitted.
If you take programming serious, learn it. With a library that encapsulates a low number of patterns (like message passing) you'll be very limited. If you never start learning about lower level multi-threading issues you'll never learn it. And it's not _that_ hard. I'm not writing multi threaded every day (by far), but often enough that I can write useful things (using shared memory, atomics, mutexes, condition varia…
I do write code that uses multi-threading every day and usually I write a few lockless functions every month for the in-house library I use. I was considering writing an article on atomics after all the mistakes and bad code I've seen. A problem with writing an article is that if I don't show real code, people might think I'm exaggerating; if I do show real code, it'd look like I'm calling someone a bad programmer
I'm very doubtful that multi-threading can be abstracted behind a library. Simple message passing can cover a lot of use cases but not everything by far. I've also seen the Javascript model work fine, but it's not real multi-threading (no parallelism). As to async frameworks, they too are restrictive and they come with a lot of complexity.
Re: Futurelock: A subtle risk in async Rust
#247Earlier quoted context omitted.
"Not inert" does not at all imply "a single runtime within std+compiler." You've jumped way too far in the opposite direction there. The problem is that the particular interface Rust chose for controlling dispatch is not granular enough. When you are doing your own dispatch, you only get access to separate tasks, but for individual futures you are at the mercy of combinators like `select!` or `FuturesUnordered` that…
If you’ve got eager dispatch I’m eager (pun intended) to learn how you have an executor that’s not baked into the std library and limited to a single runtime per process because at the time of construction you need the language to schedule dispatch of the created future. This is one of the main challenges behind the pluggable executor effort - the set of executors that could be written is so different (work stealing…
The core of an eager cooperative multitasking system does not even need the concept of an executor. You can spawn a new task by giving it some stack space and running its body to its first suspension point, right there on the current thread. When it suspends, the leaf API (e.g. `lock`) grabs the current top of the stack and stashes it somewhere, and when it's time to resume it again just runs the next part of the task right there on the current thread.
You can build different kinds of schedulers on top of this first-class ability to resume a particular leaf call in a task. For example, a `lock` integrated with a particular scheduler might queue up the resume somewhere instead of invoking it immediately. Or, a generic `lock` might be wrapped with an adapter that re-suspends and queues that up. None of this requires that the language know anything about the scheduler at all.
This is all typical of how higher level languages implement both stackful and stackless coroutines. The difference is that we want control over the "give it some stack space" part- we want the compiler to compute a maximum size and have us specify where to store it, whether that's on the heap (e.g. tokio::spawn) or nested in some other task's stack (e.g. join, select) or some statically-allocated storage (e.g. on a microcontroller).
(Of course the question then becomes, how do you ensure `lock` can't resume the task after it's been freed, either due to normal resumption or cancellation? Rust answers this with `Waker`, but this conflates the unit of stack ownership with the unit of scheduling, and in the process enables intermediate futures to route a given wakeup incorrectly. These must be decoupled so that `lock` can hold onto both the overall stack and the exact leaf suspension point it will eventually resume.)
Cancellation doesn't change much here. Given a task held from the "caller end" (as opposed to the leaf callee resume handles above), the language needs to provide a way to destruct the stack and let the decoupled `Waker` mechanism respond. This still propagates naturally to nested tasks like join/select arms, though there is now an additional wrinkle that a nested task may be actively running (and may even be the thing that indirectly provoked the cancellation).
Re: Futurelock: A subtle risk in async Rust
#248Earlier quoted context omitted.
> So yeah, which of those concerns was async Rust really designed around? All of them I guess? Yes, all of them. Futures needed to work on embedded platforms (so no allocation), needed to be highly optimizable (so no virtual dispatch), and need to act reasonably in the presence of code that crosses FFI boundaries (so no stack shenanigans). Once you come to terms with these constraints--and then add on Rust's other pr…
In my view, the major design sin was not _forcing_ failure into the outcome list. .await(DEADLINE) (where deadline is any non 0 unit, and 0 is 'reference defined' but a real number) should have been the easy interface. Either it yields a value or it doesn't, then the programmer has to expressly handle failure. Deadline would only be the minimum duration after which the language, when evaluating the future / task, wou…
Re: Futurelock: A subtle risk in async Rust
#249Skimming through, this document feels thorough and transparent. Clearly, a hard lesson learned. The footnotes, in particular, caught my eye https://rfd.shared.oxide.computer/rfd/397#_external_referenc... > Why does this situation suck? It’s clear that many of us haven’t been aware of cancellation safety and it seems likely there are many cancellation issues all over Omicron. It’s awfully stressful to find out while w…
I guess one big question here is whether there's a higher layer abstraction that is available to wrap around patterns to avoid this. It does feel like there's still generally possibilities of deadlocks in Rust concurrency right? I understand the feeling here that it feels like ... uhh... RAII-style _something_ should be preventing this, because it feels like statically we should be able to identify this issue in this…
Re: Futurelock: A subtle risk in async Rust
#250Earlier quoted context omitted.
> All the Rust evangelists talk about safety when stuff like this exists? JFC. Deadlocks can happen anywhere? You can replicate this pattern in golang.
Golang doesn't have legions of evangelicals claiming it's a safe language and everything should be written in it.
But, to be very clear, Rust has never claimed to prevent deadlocks?
See: https://doc.rust-lang.org/reference/behavior-not-considered-...