Lazy.Mutexed(3)
πΈ NAME πΈ
okay so bestie, this is the Lazy.Mutexed(3) page from the OCaml library β and the official name bit is literally Lazy.Mutexed β no description. Iconic of them to give us no description π but don't worry, we got you.
π Module π
Module Lazy.Mutexed
Module Mutexed : sig end
β¨ Documentation β¨
Simple mutex-protected lazy thunks, which can be accessed from several domains or several threads. Slay for concurrency π
This implementation has two downsides:
- -It is less optimized than
Lazy.t. - -It uses a standard library
Mutexto wait on concurrent initialization, so it does not interoperate well with user-level fiber/task abstractions (see theLazy.Mutexed.forcedocumentation for a dangerous example).
A typical use-case is optional library initialization code that is moderately expensive, or acquires resources. The library author does not want to do this work on startup, because it may not be needed, but using 'a Lazy.t is incorrect if the library may be used in concurrent settings. 'a Lazy.Mutexed.t can be used, as long as the blocking behavior is acceptable.
Note:'a Lazy.tcontains a protection against recursively forcing a thunk, it will raiseLazy.Undefined. On the other hand,'a Lazy.Mutexed.twill try to lock the mutex recursively, which will raiseSys_error.
See Lazy.Mutexed.examples below.
type !'a tβ the thunk type itself. main character energy, no cap.val is_val : 'a t -> boolβis_val xreturnstrueif the deferred computationxhas already been forced and its result is a value, not an exception.val from_val : 'a -> 'a tβfrom_val vis a deferred computation which is already finished and whose result is the valuev.val from_fun : (unit -> 'a) -> 'a tβfrom_fun fis a deferred computation that will take a mutex and callfwhen forced.val force : 'a t -> 'aβforce xforces the suspensionx. Ifxhas already been forced,Lazy.force xreturns the same value again without recomputing it. If it raised an exception, the same exception is raised again.
If a concurrent call to force happens while the result is being computed, the caller will block on a Mutex .
β οΈ RaisesSys_errorif the suspension is forced on a thread where it is already being forced. This can happen if the thunk tries to force itself recursively, but it can also happen if the thunk code contains ayield()operation for a user-level fiber/task abstraction, and two fibers/tasks try to force the thunk in parallel on the same domain:
(* This is wrong, a mutex-protected thunk should not yield control. *)
let thunk = Lazy.Mutexed.from_fun (fun () -> ... Fiber.yield () ...)
(* It may result in a same-thread [Sys_error] exception below. *)
let wrong =
Fiber.both
(fun () -> Lazy.Mutexed.force thunk)
(fun () -> Lazy.Mutexed.force thunk)
To avoid such errors, you should ensure that mutex-protected thunks never yield control outside of their sub-computation -- by not using a user-level thread library within it, or by using appropriate blocking/masking functions if available.
π¦ Examples π¦
A typical use-case is to initialize some library-local state that is used by library functions.
let config = Lazy.Mutexed.from_fun (fun () ->
match Sys.getenv_opt "MYLIB_CONFIG_PATH" with
| None | Some "" -> Config.default ()
| Some path -> Config.read_from_path path
)
let entropy =
(* we use a mibibyte of random data from /dev/urandom *)
Lazy.Mutexed.from_fun (fun () ->
In_channel.with_open_bin "/dev/urandom" (fun chan ->
In_channel.really_input_string chan (1024 * 1024)
)
)
mwah π this page is from OCamldoc, dated 2026-06-22 β bye bestie, go force those thunks responsibly π«Άβ¨
π¦ where this page comes from
- arch rolling: ocaml 5.5.0-1 Β· LGPL2.1 AND custom: QPL-1.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms