-
Notifications
You must be signed in to change notification settings - Fork 306
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
wasm 'RuntimeError: Atomics.wait cannot be called in this context' #1910
Comments
Hmm, I quickly searched it and see WebAssembly/threads#106. Quick guess (need experiments to verify!): Is it because that, Maybe we can firstly reproduce this by creating a minimal Rust code that calls |
I confirmed that if I convert my data structure that is involved in this from RustAutoOpaque to translatable, the issue no longer occurs (or maybe occurs much more rarely). When it is RustAutoOpaque, possibly because of nondeterminism in my app's behavior, it shows up every few refreshes. From reading that thread and a few others around it, it's not safe for any FRB code to call any Atomics.wait-using code, unless there's a way to mark some FRB code as "only off main thread" and enforce that. Other ways would be to explicitly drop multithreading and +atomics, or take out '&var' support and insist on only pure owned data transfers, &mut, or pure copies, but no locking until the Rust atomics story is cleared up. |
Yes I think so, due to limitations of web assembly. That limitations holds only for Web, and non-Web platforms are always happy though.
Firstly, for user code, as long as you do not use sync mode, i.e. use the default mode, I guess you are safe. This is because the default mode uses a thread pool, thus no main thread is blocked. However, for this specific bug report, it is because of
Feel free to PR, alternatively I will try to squeeze out time working on it! |
A couple other notes, without solving anything:
|
After some more thought, it's clearer now: When targeting wasm there is no safe way to use standard concurrency primitives that ultimately depend on In particular any frb(sync) function cannot wait on any lock/mutex because all lock/mutex code will ultimately need either Assuming we can eliminate the automatic RwLock wrapper, you can safely use frb(sync) with:
It can never be made safe to mix frb(sync) with async methods accessing the same data from the Rust thread pool. Now for async with Finally, auto-wrapping in an RwLock only works for data where all accesses are async and sent to the web worker thread pool. I could see a few different ways of supporting this from the FRB layer. One way would be allow users finer-grained control of the RustAutoOpaque wrapping to allow avoiding the automatic RwLock. Another helpful feature would be allow running an async call on the main thread event loop rather than the thread pool. Then for some data that had a |
With no further changes to FRB, the simplest way to make Rust mutable data safe might be to choose either async or sync globally. Either run everything in the thread pool where RwLock works, or run everything sync where Atomic.wait will never be needed. |
Do not remember very clearly, but in web it seems we use the main thread and web primitives for
Elaborate this a little bit: We can convert arbitrary main-thread code into non-main-thread, by letting main thread runs function body in non-main-thread, and main thread just do busy wait (if other waiting primitive is not allowed). This may not be harmful (except for overhead of changing thread), because even without this change, the main thread will be blocked by exactly the same amount of time. |
Apologies for the lack of clarity - in all of the above, when talking about async functions, I only meant non- I'm not sure of the right tradeoffs between main thread busy-waits and other approaches. At first glance it would seem unfortunate to be forced into main thread busy-waits because it could result in surprising performance behavior. |
More information why increment_strong_count utilizes Atomics.wait: It seems that you are using the quickstart mode. Try to set |
Btw, as is mentioned in your another post, another simple way to avoid this issue may be to use |
Up to you how you want to track full solutions. For my case I am working around issues by exclusively using frb(sync) and I've turned on |
Close since this is solved by, for example, always use |
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new issue. |
Describe the bug
I have a rust crate "other" and a type within it "LocalEditor".
In my flutter_rust_bridge target crate, I have
use other::LocalEditor
.In the flutter_rust_bridge crate, I have a method
pub fn uses_local_editor(editor: &mut<LocalEditor>) -> Option<Vec<u8>>{...}
In dart I have an async function 'doesStuff' and I call doesStuff() with no await so it runs independently in the main event loop. It parses some data in Rust and eventually calls notifyListeners() if applicable.
doesStuff has:
final value = await usesLocalEditor(editor: anEditor);
I sometimes get, but it's not reliablie or frequent, and I can't repro:
This is on up-to-date Chrome with up-to-date FRB. No reliable repro, it doesn't happen every time, but I wanted to report in case the stack trace / error message are something you're familiar with.
Steps to reproduce
N/A
Logs
Expected behavior
No response
Generated binding code
No response
OS
No response
Version of
flutter_rust_bridge_codegen
No response
Flutter info
No response
Version of
clang++
No response
Additional context
No response
The text was updated successfully, but these errors were encountered: