mirror of
https://github.com/c-cube/moonpool.git
synced 2025-12-06 03:05:30 -05:00
feat: add a Lock module
This commit is contained in:
parent
b07d460b3f
commit
2852741360
4 changed files with 73 additions and 0 deletions
36
src/lock.ml
Normal file
36
src/lock.ml
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
type 'a t = {
|
||||||
|
mutex: Mutex.t;
|
||||||
|
mutable content: 'a;
|
||||||
|
}
|
||||||
|
|
||||||
|
let create content : _ t = { mutex = Mutex.create (); content }
|
||||||
|
|
||||||
|
let with_ (self : _ t) f =
|
||||||
|
Mutex.lock self.mutex;
|
||||||
|
try
|
||||||
|
let x = f self.content in
|
||||||
|
Mutex.unlock self.mutex;
|
||||||
|
x
|
||||||
|
with e ->
|
||||||
|
Mutex.unlock self.mutex;
|
||||||
|
raise e
|
||||||
|
|
||||||
|
let[@inline] mutex self = self.mutex
|
||||||
|
let[@inline] update self f = with_ self (fun x -> self.content <- f x)
|
||||||
|
|
||||||
|
let[@inline] update_map l f =
|
||||||
|
with_ l (fun x ->
|
||||||
|
let x', y = f x in
|
||||||
|
l.content <- x';
|
||||||
|
y)
|
||||||
|
|
||||||
|
let get l =
|
||||||
|
Mutex.lock l.mutex;
|
||||||
|
let x = l.content in
|
||||||
|
Mutex.unlock l.mutex;
|
||||||
|
x
|
||||||
|
|
||||||
|
let set l x =
|
||||||
|
Mutex.lock l.mutex;
|
||||||
|
l.content <- x;
|
||||||
|
Mutex.unlock l.mutex
|
||||||
35
src/lock.mli
Normal file
35
src/lock.mli
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
(** Mutex-protected resource.
|
||||||
|
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
type 'a t
|
||||||
|
(** A value protected by a mutex *)
|
||||||
|
|
||||||
|
val create : 'a -> 'a t
|
||||||
|
(** Create a new protected value. *)
|
||||||
|
|
||||||
|
val with_ : 'a t -> ('a -> 'b) -> 'b
|
||||||
|
(** [with_ l f] runs [f x] where [x] is the value protected with
|
||||||
|
the lock [l], in a critical section. If [f x] fails, [with_lock l f]
|
||||||
|
fails too but the lock is released. *)
|
||||||
|
|
||||||
|
val update : 'a t -> ('a -> 'a) -> unit
|
||||||
|
(** [update l f] replaces the content [x] of [l] with [f x], while protected
|
||||||
|
by the mutex. *)
|
||||||
|
|
||||||
|
val update_map : 'a t -> ('a -> 'a * 'b) -> 'b
|
||||||
|
(** [update_map l f] computes [x', y = f (get l)], then puts [x'] in [l]
|
||||||
|
and returns [y], while protected by the mutex. *)
|
||||||
|
|
||||||
|
val mutex : _ t -> Mutex.t
|
||||||
|
(** Underlying mutex. *)
|
||||||
|
|
||||||
|
val get : 'a t -> 'a
|
||||||
|
(** Atomically get the value in the lock. The value that is returned
|
||||||
|
isn't protected! *)
|
||||||
|
|
||||||
|
val set : 'a t -> 'a -> unit
|
||||||
|
(** Atomically set the value.
|
||||||
|
|
||||||
|
{b NOTE} caution: using {!get} and {!set} as if this were a {!ref}
|
||||||
|
is an anti pattern and will not protect data against some race conditions. *)
|
||||||
|
|
@ -5,6 +5,7 @@ let start_thread_on_some_domain f x =
|
||||||
module Atomic = Atomic_
|
module Atomic = Atomic_
|
||||||
module Blocking_queue = Bb_queue
|
module Blocking_queue = Bb_queue
|
||||||
module Chan = Chan
|
module Chan = Chan
|
||||||
|
module Lock = Lock
|
||||||
module Fork_join = Fork_join
|
module Fork_join = Fork_join
|
||||||
module Fut = Fut
|
module Fut = Fut
|
||||||
module Pool = Pool
|
module Pool = Pool
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ val start_thread_on_some_domain : ('a -> unit) -> 'a -> Thread.t
|
||||||
to run the thread. This ensures that we don't always pick the same domain
|
to run the thread. This ensures that we don't always pick the same domain
|
||||||
to run all the various threads needed in an application (timers, event loops, etc.) *)
|
to run all the various threads needed in an application (timers, event loops, etc.) *)
|
||||||
|
|
||||||
|
module Lock = Lock
|
||||||
module Fut = Fut
|
module Fut = Fut
|
||||||
module Chan = Chan
|
module Chan = Chan
|
||||||
module Fork_join = Fork_join
|
module Fork_join = Fork_join
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue