-
Notifications
You must be signed in to change notification settings - Fork 32
Support blocking and non-blocking operations on the same Mutex #25
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
Conversation
Thanks @joshtriplett ! LGTM. Could see check why the mini test is failing? |
|
I'm a bit concerned about this. If this crate moves to a different backing implementation of synchronization, this may include a higher burden of porting. |
Add `lock_blocking` and `lock_arc_blocking` methods to allow sharing the same lock between blocking and non-blocking code. Introduce a helper macro to avoid duplicating the code of the `acquire_slow` method.
638399e
to
c17eb74
Compare
@zeenix Rebased. @notgull Support for both blocking and non-blocking seems fairly fundamental to |
I see. I wonder if this could be done for |
@notgull I very much hope so! |
@smol-rs/admins so any objections in merging this? |
match self | ||
.state | ||
.compare_exchange(0, 1, Ordering::Acquire, Ordering::Acquire) | ||
.unwrap_or_else(|x| x) | ||
{ | ||
// Lock acquired! | ||
0 => return, | ||
|
||
// Lock is held and nobody is starved. | ||
1 => {} | ||
|
||
// Somebody is starved. | ||
_ => break, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we factor this block of code into a separate method? It is repeated 2 times in this method with small variations in the _=>
case, and with this PR applied would then be duplicated again, resulting in 5 repetitions...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we can factor that into a method, since it includes control flow. I could make it a macro if you like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since it includes control flow
that can be factored out, using something like the core
::ops
::ControlFlow
, e.g.:
enum ScxResult {
/// Lock acquired
Acquired,
/// Lock is held and nobody is starved
HeldUnstarved,
/// Somebody is starved
Starved,
}
fn do_scx(state: &...) -> ScxResult {
use ScxResult::*;
match state
.compare_exchange(0, 1, Ordering::Acquire, Ordering::Acquire)
.unwrap_or_else(|x| x)
{
0 => Acquired,
1 => HeldUnstarved,
_ => Starved,
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could refactor this into a trait, like I did for the OnceCell
in #27.
I think a caveat like "calling this method on async code may cause deadlock" would be nice. Otherwise LGTM.
I would accept a PR that does this. |
What's needed for getting this in? It would also be super useful to have this for |
It would need a rebase, among other things. I've opened #39 as a replacement that also implements blocking ops for the other lock types. |
Closed by #56 |
Add
lock_blocking
andlock_arc_blocking
methods to allow sharing thesame lock between blocking and non-blocking code.
Introduce a helper macro to avoid duplicating the code of the
acquire_slow
method.