author | wenzelm |
Thu, 04 Sep 2008 19:45:13 +0200 | |
changeset 28135 | 4f6f0496e93c |
child 28139 | 831e545c655e |
permissions | -rw-r--r-- |
28135
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
1 |
(* Title: Pure/Concurrent/mailbox.ML |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
2 |
ID: $Id$ |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
3 |
|
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
4 |
Concurrent message exchange via mailbox -- with unbounded queueing. |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
5 |
*) |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
6 |
|
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
7 |
signature MAILBOX = |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
8 |
sig |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
9 |
type 'a T |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
10 |
val create: unit -> 'a T |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
11 |
val send: 'a -> 'a T -> unit |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
12 |
val receive: 'a T -> 'a |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
13 |
end; |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
14 |
|
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
15 |
structure Mailbox: MAILBOX = |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
16 |
struct |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
17 |
|
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
18 |
datatype 'a T = Mailbox of |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
19 |
{lock: Mutex.mutex, |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
20 |
cond: ConditionVar.conditionVar, |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
21 |
messages: 'a Queue.T ref}; |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
22 |
|
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
23 |
fun create () = Mailbox |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
24 |
{lock = Mutex.mutex (), |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
25 |
cond = ConditionVar.conditionVar (), |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
26 |
messages = ref Queue.empty}; |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
27 |
|
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
28 |
fun send msg (Mailbox {lock, cond, messages}) = uninterruptible (fn _ => fn () => |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
29 |
let |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
30 |
val _ = Mutex.lock lock; |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
31 |
val _ = change messages (Queue.enqueue msg); |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
32 |
val _ = Mutex.unlock lock; |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
33 |
val _ = ConditionVar.signal cond; |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
34 |
in () end) (); |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
35 |
|
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
36 |
fun receive (Mailbox {lock, cond, messages}) = uninterruptible (fn restore_attributes => fn () => |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
37 |
let |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
38 |
val _ = Mutex.lock lock; |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
39 |
fun check () = while (Queue.is_empty (! messages)) do (ConditionVar.wait (cond, lock)); |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
40 |
val _ = restore_attributes check () handle Interrupt => (Mutex.unlock lock; raise Interrupt); |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
41 |
val (msg, msgs) = Queue.dequeue (! messages); |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
42 |
val _ = messages := msgs; |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
43 |
val _ = Mutex.unlock lock; |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
44 |
in msg end) (); |
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
45 |
|
4f6f0496e93c
Concurrent message exchange via mailbox -- with unbounded queueing.
wenzelm
parents:
diff
changeset
|
46 |
end; |