Module Await_sync.Mutex

A poisonable mutual exclusion lock.

module Capsule := Capsule.Expert

Creating a mutex

type 'k t

k t is the type of a mutex protecting the contents of the k capsule.

val create : ?padded:bool @ local -> ('k Capsule.Key.t @ unique -> 'k t) @ local @@ portable

create k creates a new mutex for the capsule 'k associated with k, consuming the key itself.

The optional padded argument specifies whether to pad the data structure to avoid false sharing. See Atomic.make for a longer explanation.

Executing critical sections

With uncontended Access

val with_access : 'a 'k. Await_kernel.Await.t @ local -> ('k t @ local -> (f: ('k Capsule.Access.t -> 'a @ unique once portable contended) @ local once portable -> 'a @ unique once portable contended) @ local) @ local @@ portable

with_access w t ~f acquires t, runs f within the associated capsule, then releases t. If t is locked then uses w to wait until it is unlocked.

  • raises Poisoned

    if t cannot be acquired because it is poisoned.

  • raises Terminated

    if w is terminated before the mutex is acquired.

val with_access_poisoning : 'a 'k. Await_kernel.Await.t @ local -> ('k t @ local -> (f: ('k Capsule.Access.t -> 'a @ unique portable contended) @ local once portable -> 'a @ unique once portable contended) @ local) @ local @@ portable

with_access_poisoning w t ~f acquires t, runs f within the associated capsule, then releases t. If t is locked then uses w to wait until it is unlocked.

Poisons t if f raises an uncaught exception.

  • raises Poisoned

    if t cannot be acquired because it is poisoned.

  • raises Terminated

    if w is terminated before the mutex is acquired.

val with_access_or_cancel : 'a 'k. Await_kernel.Await.t @ local -> (Await_kernel.Cancellation.t @ local -> ('k t @ local -> (f: ('k Capsule.Access.t -> 'a @ unique portable contended) @ local once portable -> 'a Await_kernel.Or_canceled.t @ unique once portable contended) @ local) @ local) @ local @@ portable

with_access_or_cancel w c t f is Completed (with_access w t f) if c is not canceled, otherwise it is Canceled.

  • raises Terminated

    if w is terminated, even if c is canceled.

val with_access_or_cancel_poisoning : 'a 'k. Await_kernel.Await.t @ local -> (Await_kernel.Cancellation.t @ local -> ('k t @ local -> (f: ('k Capsule.Access.t -> 'a @ unique portable contended) @ local once portable -> 'a Await_kernel.Or_canceled.t @ unique once portable contended) @ local) @ local) @ local @@ portable

with_access_or_cancel_poisoning w c t f is Completed (with_access_poisoning w t f) if c is not canceled, otherwise it is Canceled.

Poisons t if f raises an uncaught exception.

  • raises Terminated

    if w is terminated, even if c is canceled.

With a local Password

val with_password : 'a 'k. Await_kernel.Await.t @ local -> ('k t @ local -> (f:('k Capsule.Password.t @ local -> 'a @ unique) @ local once -> 'a @ unique) @ local) @ local @@ portable

with_password w t f acquires t, runs f with permission to access the associated capsule, then releases t. If t is locked then uses w to wait until it is unlocked.

  • raises Poisoned

    if t cannot be acquired because it is poisoned.

  • raises Terminated

    if w is terminated before the mutex is acquired.

val with_password_poisoning : 'a 'k. Await_kernel.Await.t @ local -> ('k t @ local -> (f:('k Capsule.Password.t @ local -> 'a @ unique) @ local once -> 'a @ unique) @ local) @ local @@ portable

with_password_poisoning w t f acquires t, runs f with permission to access the associated capsule, then releases t. If t is locked then uses w to wait until it is unlocked.

Poisons t if f raises an exception.

  • raises Poisoned

    if t cannot be acquired because it is poisoned.

  • raises Terminated

    if w is terminated before the mutex is acquired.

val with_password_or_cancel : 'a 'k. Await_kernel.Await.t @ local -> (Await_kernel.Cancellation.t @ local -> ('k t @ local -> (f:('k Capsule.Password.t @ local -> 'a @ unique) @ local once -> 'a Await_kernel.Or_canceled.t @ unique) @ local) @ local) @ local @@ portable

with_password_or_cancel w c t f is Completed (with_password w t f) if c is not canceled, otherwise it is Canceled.

  • raises Terminated

    if w is terminated, even if c is canceled.

val with_password_or_cancel_poisoning : 'a 'k. Await_kernel.Await.t @ local -> (Await_kernel.Cancellation.t @ local -> ('k t @ local -> (f:('k Capsule.Password.t @ local -> 'a @ unique) @ local once -> 'a Await_kernel.Or_canceled.t @ unique) @ local) @ local) @ local @@ portable

with_password_or_cancel_poisoning w c t f is Completed (with_password_poisoning w t f) if c is not canceled, otherwise it is Canceled.

Poisons t if f raises an exception.

  • raises Terminated

    if w is terminated, even if c is canceled.

With a unique Key

val with_key : 'a 'k. Await_kernel.Await.t @ local -> ('k t @ local -> (f: ('k Capsule.Key.t @ unique -> #('a * 'k Capsule.Key.t) @ unique once) @ local once -> 'a @ unique once) @ local) @ local

with_key t ~f locks t and runs f, providing it a key for 'k uniquely. If t is locked, then with_key uses w to wait until it is unlocked.

  • raises Poisoned

    if t cannot be acquired because it is poisoned.

  • raises Terminated

    if w is terminated before the mutex is acquired.

val with_key_poisoning : 'a 'k. Await_kernel.Await.t @ local -> ('k t @ local -> (f: ('k Capsule.Key.t @ unique -> #('a * 'k Capsule.Key.t) @ unique once) @ local once -> 'a @ unique once) @ local) @ local

with_key_poisoning t ~f locks t and runs f, providing it a key for 'k uniquely. If the function raises without returning the key back, the mutex is poisoned. If t is locked, then with_key_poisoning uses w to wait until it is unlocked.

  • raises Poisoned

    if t cannot be acquired because it is poisoned.

  • raises Terminated

    if w is terminated before the mutex is acquired.

val with_key_or_cancel : 'a 'k. Await_kernel.Await.t @ local -> (Await_kernel.Cancellation.t @ local -> ('k t @ local -> (f: ('k Capsule.Key.t @ unique -> #('a * 'k Capsule.Key.t) @ unique once) @ local once -> 'a Await_kernel.Or_canceled.t @ unique once) @ local) @ local) @ local

with_key_or_cancel w c t ~f is Completed (with_key w t ~f) if c is not canceled, otherwise it is Canceled.

  • raises Terminated

    if w is terminated, even if c is canceled.

val with_key_or_cancel_poisoning : 'a 'k. Await_kernel.Await.t @ local -> (Await_kernel.Cancellation.t @ local -> ('k t @ local -> (f: ('k Capsule.Key.t @ unique -> #('a * 'k Capsule.Key.t) @ unique once) @ local once -> 'a Await_kernel.Or_canceled.t @ unique once) @ local) @ local) @ local

with_key_or_cancel_poisoning w c t ~f is Completed (with_key_poisoning w t ~f) if c is not canceled, otherwise it is Canceled.

  • raises Terminated

    if w is terminated, even if c is canceled.

And waiting for a Condition

module Condition : sig ... end

Condition variable for waiting for changes to state protected by a lock.

And releasing temporarily

val release_temporarily : 'a 'k. Await_kernel.Await.t @ local -> ('k t @ local -> ('k Capsule.Key.t @ unique -> (f:(unit -> 'a @ unique) @ local once -> #('a * 'k Capsule.Key.t) @ unique) @ local once) @ local) @ local @@ portable

release_temporarily w t k ~f releases t, runs f without the mutex, reacquires t and returns the result of running f along with the k.

To obtain a key to pass to release_temporarily, use with_key or similar functions.

  • raises Poisoned

    if t cannot be reacquired because it is poisoned.

  • raises Terminated

    if w is terminated before the mutex is reacquired.

val release_temporarily_or_cancel : 'a. Await_kernel.Await.t @ local -> (Await_kernel.Cancellation.t @ local -> ('k t @ local -> ('k Capsule.Key.t @ unique -> (f:(unit -> 'a @ unique) @ local once -> #('a * 'k Capsule.Key.t) Await_kernel.Or_canceled.t__'value_or_null_void' @ unique) @ local once) @ local) @ local) @ local @@ portable

release_temporarily_or_cancel w c t k ~f is Completed (release_temporarily w t k ~f) if c is not canceled, otherwise it is Canceled.

And poisoning indefinitely

val poison : 'k t @ local -> ('k Capsule.Key.t @ unique -> 'k Capsule.Key.t @ unique) @ local @@ portable

poison t key poisons the mutex associated with the key.

Note that poisoning a mutex does not signal waiters on associated condition variables.

Indefinitely through poisoning

val acquire_and_poison : Await_kernel.Await.t @ local -> ('k t @ local -> 'k Capsule.Key.t @ unique) @ local @@ portable

acquire_and_poison w t acquires t and then immediately poisons it, returning the key to the protected capsule.

  • raises Poisoned

    if t cannot be acquired because it is poisoned.

  • raises Terminated

    if w is terminated before the mutex is acquired.

val acquire_and_poison_or_cancel : Await_kernel.Await.t @ local -> (Await_kernel.Cancellation.t @ local -> ('k t @ local -> 'k Capsule.Key.t Await_kernel.Or_canceled.t__void @ unique) @ local) @ local @@ portable

acquire_and_poison_or_cancel w c t is Completed (acquire_and_poison w t) if c is not canceled, otherwise it is Canceled.

With arbitrary dynamic scope

module Guard : sig ... end
val acquire : Await_kernel.Await.t @ local -> ('k t -> 'k Guard.t @ unique) @ local @@ portable

acquire w t acquires t and returns a guard for the locked mutex. If t is locked, then acquire uses w to wait until it is unlocked.

  • raises Poisoned

    if t cannot be acquired because it is poisoned.

  • raises Terminated

    if w is terminated before the mutex is acquired.

val acquire_or_cancel : Await_kernel.Await.t @ local -> (Await_kernel.Cancellation.t @ local -> ('k t -> 'k Guard.t Await_kernel.Or_canceled.t @ unique) @ local) @ local @@ portable

acquire_or_cancel w c t is Completed (acquire w t) if c is not canceled, otherwise it is Canceled.

Poisoning as a signal

val is_poisoned : 'k t @ local -> bool @@ portable

is_poisoned t determines whether the mutex t is poisoned.

val poison_unacquired : 'k t @ local -> unit @@ portable

poison_unacquired t poisons t without acquiring it. Does nothing if t is already poisoned.

Note that this can render the capsule associated with t innaccessible, since it potentially destroys the associated key.

Note that poisoning a mutex does not signal waiters on associated condition variables.