78 (let |
78 (let |
79 val _ = Thread.setAttributes new_atts; |
79 val _ = Thread.setAttributes new_atts; |
80 val result = Exn.capture (f orig_atts) x; |
80 val result = Exn.capture (f orig_atts) x; |
81 val _ = restore (); |
81 val _ = restore (); |
82 in result end |
82 in result end |
83 handle Interrupt => (restore (); Exn.Exn Interrupt)) |
83 handle Exn.Interrupt => (restore (); Exn.Exn Exn.Interrupt)) |
84 end; |
84 end; |
85 |
85 |
86 fun interruptible f = with_attributes regular_interrupts (fn _ => f); |
86 fun interruptible f = with_attributes regular_interrupts (fn _ => f); |
87 |
87 |
88 fun uninterruptible f = |
88 fun uninterruptible f = |
103 val watchdog = Thread.fork (fn () => |
103 val watchdog = Thread.fork (fn () => |
104 (OS.Process.sleep time; timeout := true; Thread.interrupt worker), []); |
104 (OS.Process.sleep time; timeout := true; Thread.interrupt worker), []); |
105 |
105 |
106 (*RACE! timeout signal vs. external Interrupt*) |
106 (*RACE! timeout signal vs. external Interrupt*) |
107 val result = Exn.capture (restore_attributes f) x; |
107 val result = Exn.capture (restore_attributes f) x; |
108 val was_timeout = (case result of Exn.Exn Interrupt => ! timeout | _ => false); |
108 val was_timeout = (case result of Exn.Exn Exn.Interrupt => ! timeout | _ => false); |
109 |
109 |
110 val _ = Thread.interrupt watchdog handle Thread _ => (); |
110 val _ = Thread.interrupt watchdog handle Thread _ => (); |
111 in if was_timeout then raise TimeOut else Exn.release result end) (); |
111 in if was_timeout then raise TimeOut else Exn.release result end) (); |
112 |
112 |
113 end; |
113 end; |
163 (OS.Process.sleep (Time.fromMilliseconds 100); if n > 0 then kill (n - 1) else ()); |
163 (OS.Process.sleep (Time.fromMilliseconds 100); if n > 0 then kill (n - 1) else ()); |
164 |
164 |
165 val _ = while ! result = Wait do |
165 val _ = while ! result = Wait do |
166 restore_attributes (fn () => |
166 restore_attributes (fn () => |
167 (ConditionVar.waitUntil (result_cond, result_mutex, Time.now () + Time.fromMilliseconds 100); ()) |
167 (ConditionVar.waitUntil (result_cond, result_mutex, Time.now () + Time.fromMilliseconds 100); ()) |
168 handle Interrupt => kill 10) (); |
168 handle Exn.Interrupt => kill 10) (); |
169 |
169 |
170 (*cleanup*) |
170 (*cleanup*) |
171 val output = read_file output_name handle IO.Io _ => ""; |
171 val output = read_file output_name handle IO.Io _ => ""; |
172 val _ = OS.FileSys.remove script_name handle OS.SysErr _ => (); |
172 val _ = OS.FileSys.remove script_name handle OS.SysErr _ => (); |
173 val _ = OS.FileSys.remove pid_name handle OS.SysErr _ => (); |
173 val _ = OS.FileSys.remove pid_name handle OS.SysErr _ => (); |
174 val _ = OS.FileSys.remove output_name handle OS.SysErr _ => (); |
174 val _ = OS.FileSys.remove output_name handle OS.SysErr _ => (); |
175 val _ = Thread.interrupt system_thread handle Thread _ => (); |
175 val _ = Thread.interrupt system_thread handle Thread _ => (); |
176 val rc = (case ! result of Signal => raise Interrupt | Result rc => rc); |
176 val rc = (case ! result of Signal => raise Exn.Interrupt | Result rc => rc); |
177 in (output, rc) end) (); |
177 in (output, rc) end) (); |
178 |
178 |
179 |
179 |
180 (* critical section -- may be nested within the same thread *) |
180 (* critical section -- may be nested within the same thread *) |
181 |
181 |