-
Notifications
You must be signed in to change notification settings - Fork 71
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
Mutex API ergonomics #336
Comments
Yeah, I was wondering about doing that. In the end, I decided to make it look more like the stdlib's Mutex. I don't have enough experience with Rust to know if it's more ergonomic (I assumed Rust did it that way because it had no choice - it can't prevent concurrent access to the resource if it's outside the mutex). Having the resource inside the mutex makes a lot of sense though, and would probably work better with OCaml's proposed modal types (haven't got access to the talk yet, so not sure). But should val use_rw : protect:bool -> 'a t -> ('a -> 'a * 'b) -> 'b |
Interesting question, I think in my above example it is intrinsically 'updating' the resource (i.e. saving to the path) but the update is not reflected in the type. The |
Yes, it's probably not necessary to allow updating the resource itself. It would only be useful for something like an int, and you'd be better off with an atomic there. Also, people can always pass Are you planning to make a PR for this? |
Exactly. Sure, I'll take a crack at it! |
I have this in containers. Note that Updating the value is useful if the lock protects a purely functional value, e.g. a let update_my_resource (r: _ CCLock.t) =
let action =
(* critical section here *)
CCLock.update_map r (fun cur ->
let new_value, action = (* something using [cur] *) in
new_value, action)
in
(* perform action outside the critical section *)
perform action Note that we both want to update the lock's protected content, and to return something to do later (or, say, a flag indicating what to do next). |
I have to admit, I don't quite understand why we need a mutex to protect the update of a purely functional immutable value like say a If we are making the argument that we need to update an immutable value and synchronize that update among multiple observers, then we would probably want to use an |
You can do the same with an atomic if the critical section is idempotent (since you might have to do it several times under contention) and if it's cheap (ditto). A mutex is more general and sometimes more convenient. If you just update an |
In @c-cube's API, |
An atomic is fine if you're willing to do the update several times in case of contention, and if you don't need to do anything else than updating the map. For anything a bit longer or more complex, I find mutexes to be a very useful tool :-)
|
Sure. Let's say you have a complex data |
The later, yes. In containers: (* in CCLock.ml *)
type 'a t = { mutex: Mutex.t; mutable content: 'a } |
Wouldn't this be a duplication of mutability if we are already dealing with a mutable data structure e.g. let's say now In my view it would be simpler to separate the concepts of 'holding the lock' and 'mutating the data'. If you have an immutable data structure, then you could just use a e.g. |
It's this way because it's more flexible. No one forces you to actually mutate it, and some functions assume you use internal mutation (like I know that if I want to protect data, I just use |
Can we draw inspiration from Rust's Mutex to make
Eio.Mutex
a bit more ergonomic? E.g. usage adapted from https://github.com/ocaml-multicore/eio#the-rest-mutex-semaphore-and-condition:We would need signatures like this:
Having said that, I realize we don't have borrow/move checking in OCaml so we wouldn't get the same level of safety. But it should make it a bit more ergonomic as the key idea is that a mutex is always paired with its data.
The text was updated successfully, but these errors were encountered: