added interrupt_timeout;
authorwenzelm
Thu, 20 Sep 2007 20:58:40 +0200
changeset 24668 4058b7b0925c
parent 24667 9f29588d57d5
child 24669 4579eac2c997
added interrupt_timeout; tuned signature;
src/Pure/ML-Systems/multithreading_polyml.ML
--- a/src/Pure/ML-Systems/multithreading_polyml.ML	Thu Sep 20 20:56:54 2007 +0200
+++ b/src/Pure/ML-Systems/multithreading_polyml.ML	Thu Sep 20 20:58:40 2007 +0200
@@ -10,8 +10,9 @@
 signature MULTITHREADING =
 sig
   include MULTITHREADING
-  val uninterruptible: (Thread.threadAttribute list -> 'a -> 'b) -> 'a -> 'b
-  val interruptible: (Thread.threadAttribute list -> 'a -> 'b) -> 'a -> 'b
+  val ignore_interrupt: ('a -> 'b) -> 'a -> 'b
+  val raise_interrupt: ('a -> 'b) -> 'a -> 'b
+  val interrupt_timeout: Time.time -> ('a -> 'b) -> 'a -> 'b
 end;
 
 structure Multithreading: MULTITHREADING =
@@ -59,12 +60,28 @@
       handle Interrupt => (restore (); Exn.Exn Interrupt))
   end;
 
+
+(* interrupt handling *)
+
 fun uninterruptible f x = with_attributes
   [Thread.EnableBroadcastInterrupt false, Thread.InterruptState Thread.InterruptDefer] f x;
 
 fun interruptible f x = with_attributes
   [Thread.EnableBroadcastInterrupt true, Thread.InterruptState Thread.InterruptAsynchOnce] f x;
 
+fun ignore_interrupt f = uninterruptible (fn _ => f);
+fun raise_interrupt f = interruptible (fn _ => f);
+
+fun interrupt_timeout time f x =
+  uninterruptible (fn atts => fn () =>
+    let
+      val worker = Thread.self ();
+      val watchdog = Thread.fork (interruptible (fn _ => fn () =>
+        (OS.Process.sleep time; Thread.interrupt worker)), []);
+      val result = Exn.capture (with_attributes atts (fn _ => f)) x;
+      val _ = Thread.interrupt watchdog handle Thread _ => ();
+    in Exn.release result end) ();
+
 
 (* critical section -- may be nested within the same thread *)
 
@@ -206,7 +223,7 @@
 
 val NAMED_CRITICAL = Multithreading.NAMED_CRITICAL;
 val CRITICAL = Multithreading.CRITICAL;
+val ignore_interrupt = Multithreading.ignore_interrupt;
+val raise_interrupt = Multithreading.raise_interrupt;
+val interrupt_timeout = Multithreading.interrupt_timeout;
 
-fun ignore_interrupt f = Multithreading.uninterruptible (fn _ => f);
-fun raise_interrupt f = Multithreading.interruptible (fn _ => f);
-