(* $Id: netsys_oothr.ml 1529 2011-01-04 01:37:10Z gerd $ *)
class type mtprovider =
object
method single_threaded : bool
method create_thread : 's 't . ('s -> 't) -> 's -> thread
method self : thread
method yield : unit -> unit
method create_mutex : unit -> mutex
method create_condition : unit -> condition
end
and thread =
object
method id : int
method join : unit -> unit
method repr : exn
end
and mutex =
object
method lock : unit -> unit
method unlock : unit -> unit
method try_lock : unit -> bool
method repr : exn
end
and condition =
object
method wait : mutex -> unit
method signal : unit -> unit
method broadcast : unit -> unit
method repr : exn
end
(* single-threaded dummy stuff: *)
exception Dummy
let stthread() : thread =
( object
method id = 0
method join() =
failwith "Netsys_oothr: join not possible in single-threaded program"
method repr = Dummy
end
)
let stmutex() : mutex =
( object
method lock() = ()
method unlock() = ()
method try_lock() = true
method repr = Dummy
end
)
let stcondition() : condition =
( object
method wait _ = ()
method signal() = ()
method broadcast() = ()
method repr = Dummy
end
)
let stprovider : mtprovider =
( object
method single_threaded = true
method create_thread : 's 't . ('s -> 't) -> 's -> thread =
fun _ _ -> failwith "Netsys_oothr: create_thread not possible in single-threaded program"
method self = stthread()
method yield() = ()
method create_mutex() = stmutex()
method create_condition() = stcondition()
end
)
let provider = ref stprovider
let single_threaded = ref false (* whether we know this for sure *)
let st_init = ref false
let serialize mutex f arg =
if !single_threaded then (
f arg
)
else (
if not !st_init then (
single_threaded := !provider # single_threaded;
st_init := true
);
mutex # lock();
let r =
try f arg
with e -> mutex # unlock(); raise e in
mutex # unlock();
r
)