alice
library
manual.

Alice Project

The Lock structure


________ Synopsis ____________________________________________________

    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


________ Import ______________________________________________________

Imported implicitly.


________ Interface ___________________________________________________

    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
  

________ Description _________________________________________________

type lock
type t = alt

The type of synchronisation locks.

lock ()

Creates a new lock.

sync lock f

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.

Sync (val lock = lock signature S = S structure X = X)

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.


________ Example _____________________________________________________

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')
  


last modified 2007/Mar/30 17:10