mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-07 19:55:31 -05:00
add CCMutex.{with_lock_as_ref,incr,decr}
This commit is contained in:
parent
b818b26751
commit
42e54fabc5
2 changed files with 75 additions and 0 deletions
|
|
@ -32,6 +32,8 @@ type 'a t = {
|
||||||
mutable content : 'a;
|
mutable content : 'a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type 'a lock = 'a t
|
||||||
|
|
||||||
let create content = {
|
let create content = {
|
||||||
mutex = Mutex.create();
|
mutex = Mutex.create();
|
||||||
content;
|
content;
|
||||||
|
|
@ -47,6 +49,50 @@ let with_lock l f =
|
||||||
Mutex.unlock l.mutex;
|
Mutex.unlock l.mutex;
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
(*$R
|
||||||
|
let l = create 0 in
|
||||||
|
let try_incr l =
|
||||||
|
update l (fun x -> Thread.yield(); x+1)
|
||||||
|
in
|
||||||
|
for i = 1 to 10 do ignore (Thread.create try_incr l) done;
|
||||||
|
Thread.delay 0.10 ;
|
||||||
|
assert_equal 10 (get l)
|
||||||
|
*)
|
||||||
|
|
||||||
|
module LockRef = struct
|
||||||
|
type 'a t = 'a lock
|
||||||
|
let get t = t.content
|
||||||
|
let set t x = t.content <- x
|
||||||
|
let update t f = t.content <- f t.content
|
||||||
|
end
|
||||||
|
|
||||||
|
let with_lock_as_ref l f =
|
||||||
|
Mutex.lock l.mutex;
|
||||||
|
try
|
||||||
|
let x = f l in
|
||||||
|
Mutex.unlock l.mutex;
|
||||||
|
x
|
||||||
|
with e ->
|
||||||
|
Mutex.unlock l.mutex;
|
||||||
|
raise e
|
||||||
|
|
||||||
|
(*$R
|
||||||
|
let l = create 0 in
|
||||||
|
let test_it l =
|
||||||
|
with_lock_as_ref l
|
||||||
|
(fun r ->
|
||||||
|
let x = LockRef.get r in
|
||||||
|
LockRef.set r (x+10);
|
||||||
|
Thread.yield ();
|
||||||
|
let y = LockRef.get r in
|
||||||
|
LockRef.set r (y - 10);
|
||||||
|
)
|
||||||
|
in
|
||||||
|
for i = 1 to 100 do ignore (Thread.create test_it l) done;
|
||||||
|
Thread.delay 0.10;
|
||||||
|
assert_equal 0 (get l)
|
||||||
|
*)
|
||||||
|
|
||||||
let mutex l = l.mutex
|
let mutex l = l.mutex
|
||||||
|
|
||||||
let update l f =
|
let update l f =
|
||||||
|
|
@ -58,4 +104,7 @@ let get l =
|
||||||
Mutex.unlock l.mutex;
|
Mutex.unlock l.mutex;
|
||||||
x
|
x
|
||||||
|
|
||||||
|
let incr l = update l (fun x -> x+1)
|
||||||
|
|
||||||
|
let decr l = update l (fun x -> x-1)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,24 @@ val with_lock : 'a t -> ('a -> 'b) -> 'b
|
||||||
the lock [l], in a critical section. If [f x] fails, [with_lock l f]
|
the lock [l], in a critical section. If [f x] fails, [with_lock l f]
|
||||||
fails too but the lock is released *)
|
fails too but the lock is released *)
|
||||||
|
|
||||||
|
(** Type allowing to manipulate the lock as a reference
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
module LockRef : sig
|
||||||
|
type 'a t
|
||||||
|
|
||||||
|
val get : 'a t -> 'a
|
||||||
|
|
||||||
|
val set : 'a t -> 'a -> unit
|
||||||
|
|
||||||
|
val update : 'a t -> ('a -> 'a) -> unit
|
||||||
|
end
|
||||||
|
|
||||||
|
val with_lock_as_ref : 'a t -> ('a LockRef.t -> 'b) -> 'b
|
||||||
|
(** [with_lock_as_ref l f] calls [f] with a reference-like object
|
||||||
|
that allows to manipulate the value of [l] safely.
|
||||||
|
The object passed to [f] must not escape the function call
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val update : 'a t -> ('a -> 'a) -> unit
|
val update : 'a t -> ('a -> 'a) -> unit
|
||||||
(** [update l f] replaces the content [x] of [l] with [f x], atomically *)
|
(** [update l f] replaces the content [x] of [l] with [f x], atomically *)
|
||||||
|
|
||||||
|
|
@ -49,3 +67,11 @@ val mutex : _ t -> Mutex.t
|
||||||
val get : 'a t -> 'a
|
val get : 'a t -> 'a
|
||||||
(** Get the value in the lock. The value that is returned isn't protected! *)
|
(** Get the value in the lock. The value that is returned isn't protected! *)
|
||||||
|
|
||||||
|
val incr : int t -> unit
|
||||||
|
(** Atomically increment the value
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val decr : int t -> unit
|
||||||
|
(** Atomically decrement the value
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue