Skip to content
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

RwLock blocking_read/write methods rely on block_on #7097

Open
eloff opened this issue Jan 14, 2025 · 1 comment
Open

RwLock blocking_read/write methods rely on block_on #7097

eloff opened this issue Jan 14, 2025 · 1 comment
Labels
A-tokio Area: The main tokio crate C-bug Category: This is a bug. M-sync Module: tokio/sync

Comments

@eloff
Copy link

eloff commented Jan 14, 2025

I think these methods could be implemented as in a normal mutex and just block.

The problem with calling the async versions via block_on is that it's not allowed to nest calls to block_on in tokio. If you're using tokio there's going to be a block_on somewhere higher up the stack, including if you just use #[tokio::test].

The user ends up having to spin in a loop using try_lock instead, which is inferior to how regular mutexes work.

Current implementation: https://docs.rs/tokio/latest/src/tokio/sync/rwlock.rs.html#522

The tokio queues have the same problem with the blocking send/recv methods as well.

@eloff eloff added A-tokio Area: The main tokio crate C-bug Category: This is a bug. labels Jan 14, 2025
@Darksonn Darksonn added the M-sync Module: tokio/sync label Jan 14, 2025
@Darksonn
Copy link
Contributor

This panic is intentional to stop people from making the mistake you are currently making. Blocking on this lock within async code is incorrect for the reasons outlined in this article.

I recommend that you rearchitect your code to avoid synchronously blocking for a long time in an async context. You probably need to make one of these changes:

  1. Make the function async so that you can call the async lock method.
  2. Change the RwLock into an std lock. This works because the std lock can never be held locked across an .await point.

There is also an escape hatch called block_in_place that you can use with block_in_place(|| rw_lock.blocking_write()). But it has various disadvantages compared to the above solutions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate C-bug Category: This is a bug. M-sync Module: tokio/sync
Projects
None yet
Development

No branches or pull requests

2 participants