# HG changeset patch # User wenzelm # Date 1223905720 -7200 # Node ID c7f2a08996791d3b4e8ff3a0e66ad69cc73f273a # Parent bd2456e0d944e958b674406ab72422be34e2e144 State variables with synchronized access. diff -r bd2456e0d944 -r c7f2a0899679 src/Pure/Concurrent/synchronized.ML --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Pure/Concurrent/synchronized.ML Mon Oct 13 15:48:40 2008 +0200 @@ -0,0 +1,53 @@ +(* Title: Pure/Concurrent/synchronized.ML + ID: $Id$ + Author: Fabian Immler and Makarius + +State variables with synchronized access. +*) + +signature SYNCHRONIZED = +sig + type 'a var + val var: string -> 'a -> 'a var + val guarded_change: ('a -> bool) -> ('a -> Time.time option) -> + 'a var -> (bool -> 'a -> 'b * 'a) -> 'b + val change_result: 'a var -> ('a -> 'b * 'a) -> 'b + val change: 'a var -> ('a -> 'a) -> unit +end; + +structure Synchronized: SYNCHRONIZED = +struct + +(* state variables *) + +datatype 'a var = Var of + {name: string, + lock: Mutex.mutex, + cond: ConditionVar.conditionVar, + var: 'a ref}; + +fun var name x = Var + {name = name, + lock = Mutex.mutex (), + cond = ConditionVar.conditionVar (), + var = ref x}; + + +(* synchronized access *) + +fun guarded_change guard time_limit (Var {name, lock, cond, var}) f = + SimpleThread.synchronized name lock (fn () => + let + fun check () = guard (! var) orelse + (case time_limit (! var) of + NONE => (ConditionVar.wait (cond, lock); check ()) + | SOME t => ConditionVar.waitUntil (cond, lock, t) andalso check ()); + val ok = check (); + val res = change_result var (f ok); + val _ = ConditionVar.broadcast cond; + in res end); + +fun change_result var f = guarded_change (K true) (K NONE) var (K f); +fun change var f = change_result var (fn x => ((), f x)); + +end;