|
1 (* Title: Pure/Concurrent/thread_attributes.ML |
|
2 Author: Makarius |
|
3 |
|
4 Thread attributes for interrupt handling. |
|
5 *) |
|
6 |
|
7 signature THREAD_ATTRIBUTES = |
|
8 sig |
|
9 type attributes = Thread.Thread.threadAttribute list |
|
10 val no_interrupts: attributes |
|
11 val test_interrupts: attributes |
|
12 val public_interrupts: attributes |
|
13 val private_interrupts: attributes |
|
14 val sync_interrupts: attributes -> attributes |
|
15 val safe_interrupts: attributes -> attributes |
|
16 val with_attributes: attributes -> (attributes -> 'a) -> 'a |
|
17 val uninterruptible: ((('c -> 'd) -> 'c -> 'd) -> 'a -> 'b) -> 'a -> 'b |
|
18 end; |
|
19 |
|
20 structure Thread_Attributes: THREAD_ATTRIBUTES = |
|
21 struct |
|
22 |
|
23 type attributes = Thread.Thread.threadAttribute list; |
|
24 |
|
25 val no_interrupts = |
|
26 [Thread.Thread.EnableBroadcastInterrupt false, |
|
27 Thread.Thread.InterruptState Thread.Thread.InterruptDefer]; |
|
28 |
|
29 val test_interrupts = |
|
30 [Thread.Thread.EnableBroadcastInterrupt false, |
|
31 Thread.Thread.InterruptState Thread.Thread.InterruptSynch]; |
|
32 |
|
33 val public_interrupts = |
|
34 [Thread.Thread.EnableBroadcastInterrupt true, |
|
35 Thread.Thread.InterruptState Thread.Thread.InterruptAsynchOnce]; |
|
36 |
|
37 val private_interrupts = |
|
38 [Thread.Thread.EnableBroadcastInterrupt false, |
|
39 Thread.Thread.InterruptState Thread.Thread.InterruptAsynchOnce]; |
|
40 |
|
41 val sync_interrupts = map |
|
42 (fn x as Thread.Thread.InterruptState Thread.Thread.InterruptDefer => x |
|
43 | Thread.Thread.InterruptState _ => Thread.Thread.InterruptState Thread.Thread.InterruptSynch |
|
44 | x => x); |
|
45 |
|
46 val safe_interrupts = map |
|
47 (fn Thread.Thread.InterruptState Thread.Thread.InterruptAsynch => |
|
48 Thread.Thread.InterruptState Thread.Thread.InterruptAsynchOnce |
|
49 | x => x); |
|
50 |
|
51 fun with_attributes new_atts e = |
|
52 let |
|
53 val orig_atts = safe_interrupts (Thread.Thread.getAttributes ()); |
|
54 val result = Exn.capture (fn () => |
|
55 (Thread.Thread.setAttributes (safe_interrupts new_atts); e orig_atts)) (); |
|
56 val _ = Thread.Thread.setAttributes orig_atts; |
|
57 in Exn.release result end; |
|
58 |
|
59 fun uninterruptible f x = |
|
60 with_attributes no_interrupts (fn atts => |
|
61 f (fn g => fn y => with_attributes atts (fn _ => g y)) x); |
|
62 |
|
63 end; |