signature LOCK structure Lock : LOCK
The Lock structure defines a simple means to implement monitor-like synchronisation of arbitrary sets of functions or whole modules.
See the example at the and of this page for a common idiom for building up such synchronisation.
See also: Future, Thread, Remote.Proxy
Imported implicitly.
signature LOCK = sig type lock type t = lock val lock : unit -> lock val sync : lock -> ('a -> 'b) -> ('a -> 'b) functor Sync (val lock : lock signature S structure X : S) : S end
The type of synchronisation locks.
Creates a new lock.
Returns a function f', that has the same behaviour as f, but is synchronised with respect to lock. Only one function per lock can be evaluated at one time, other threads will block until that function returns. Locking is not reentrant.
returns a wrapper of structure X where all fields of function type are synchronised with respect to lock lock. A function that returns a function will return a synchronised function, respectively (i.e. the wrapping is recursively performed for curried functions, such that each partial application is again synchronised).
If X is a functor, then the functor itself is synchronised. When the functor is applied, the resulting module will be wrapped recursively (i.e. the wrapping is recursively performed for curried functors and any resulting structure).
Example:
Sync (val lock = lock () signature S = (val x : int val f : int -> int val g : int -> int -> int) structure X = (val x = 5 fun f n = n + 1 fun f n m = n + m))
returns a structure that is equivalent to
struct val x = 5 val f = sync lock (fn n => n + 1) val g = sync lock (fn n => sync lock (fn m => n + m)) end
Similarly,
Sync (val lock = lock () signature S = fct () -> (val x : int val f : int -> int -> int) structure X = fct () => (val x = 5 fun f n m = n + m))
returns a synchronised functor equivalent to
fct () => (val x = 5 val f = sync lock (fn n => sync lock (fn m => n + m)))
Note that structure fields of non-function type will not be wrapped, even if they contain function values. For example,
Sync (val lock = lock () signature S = (val p : (int -> int) * (int -> int)) structure X = (val p = (fn n => n, fn n => n + 1)))
returns X unchanged.
The following structure provides two synchronised functions even and odd. Only one thread can run within the implementation of these functions.
signature MONITOR = sig val even : int -> unit val odd : int -> unit end structure Monitor : MONITOR = struct fun even 0 = () | even n = odd(n-1) and odd 0 = () | odd n = even(n-1) val lock = Lock.lock() val even = Lock.sync lock even val odd = Lock.sync lock odd end
Alternatively, the structure can be constructed like this:
structure Monitor' = struct fun even 0 = () | even n = odd(n-1) and odd 0 = () | odd n = even(n-1) end structure Monitor = Lock.Sync (val lock = Lock.lock() signature S = MONITOR structure X = Monitor')