137 |
137 |
138 (** interrupts **) |
138 (** interrupts **) |
139 |
139 |
140 exception Interrupt; |
140 exception Interrupt; |
141 |
141 |
142 fun ignore_interrupt f x = |
142 local |
143 let |
143 |
144 val old_handler = Signals.setHandler (Signals.sigINT, Signals.IGNORE); |
144 fun change_signal new_handler f x = |
145 val result = Exn.capture f x; |
145 let |
|
146 val old_handler = Signals.setHandler (Signals.sigINT, new_handler); |
|
147 val result = Exn.capture (f old_handler) x; |
146 val _ = Signals.setHandler (Signals.sigINT, old_handler); |
148 val _ = Signals.setHandler (Signals.sigINT, old_handler); |
147 in Exn.release result end; |
149 in Exn.release result end; |
148 |
150 |
149 fun raise_interrupt f x = |
151 in |
150 let |
152 |
151 val interrupted = ref false; |
153 fun interruptible (f: 'a -> 'b) x = |
152 val result = ref (Exn.Result ()); |
154 let |
|
155 val result = ref (Exn.Exn Interrupt: 'b Exn.result); |
153 val old_handler = Signals.inqHandler Signals.sigINT; |
156 val old_handler = Signals.inqHandler Signals.sigINT; |
154 in |
157 in |
155 SMLofNJ.Cont.callcc (fn cont => |
158 SMLofNJ.Cont.callcc (fn cont => |
156 (Signals.setHandler (Signals.sigINT, Signals.HANDLER (fn _ => (interrupted := true; cont))); |
159 (Signals.setHandler (Signals.sigINT, Signals.HANDLER (fn _ => cont)); |
157 result := Exn.capture f x)); |
160 result := Exn.capture f x)); |
158 Signals.setHandler (Signals.sigINT, old_handler); |
161 Signals.setHandler (Signals.sigINT, old_handler); |
159 if ! interrupted then raise Interrupt else Exn.release (! result) |
162 Exn.release (! result) |
160 end; |
163 end; |
|
164 |
|
165 fun uninterruptible f = |
|
166 change_signal Signals.IGNORE |
|
167 (fn old_handler => f (fn g => change_signal old_handler (fn _ => g))); |
|
168 |
|
169 end; |
161 |
170 |
162 |
171 |
163 (* basis library fixes *) |
172 (* basis library fixes *) |
164 |
173 |
165 structure TextIO = |
174 structure TextIO = |