with_attributes: enforces InterruptAsynch => InterruptAsynchOnce to avoid race condition;
authorwenzelm
Thu, 02 Oct 2008 21:21:21 +0200
changeset 28466 6e35fbfc32b8
parent 28465 db8667d84dd2
child 28467 c8336c42668e
with_attributes: enforces InterruptAsynch => InterruptAsynchOnce to avoid race condition; removed pointless comments;
src/Pure/ML-Systems/multithreading_polyml.ML
--- a/src/Pure/ML-Systems/multithreading_polyml.ML	Thu Oct 02 19:59:01 2008 +0200
+++ b/src/Pure/ML-Systems/multithreading_polyml.ML	Thu Oct 02 21:21:21 2008 +0200
@@ -69,20 +69,20 @@
 val regular_interrupts =
   [Thread.EnableBroadcastInterrupt true, Thread.InterruptState Thread.InterruptAsynchOnce];
 
+val safe_interrupts = map
+  (fn Thread.InterruptState Thread.InterruptAsynch =>
+      Thread.InterruptState Thread.InterruptAsynchOnce
+    | x => x);
+
 fun with_attributes new_atts f x =
   let
     val orig_atts = Thread.getAttributes ();
     fun restore () = Thread.setAttributes orig_atts;
-  in
-    Exn.release
-    (*RACE for fully asynchronous interrupts!*)
-    (let
-        val _ = Thread.setAttributes new_atts;
-        val result = Exn.capture (f orig_atts) x;
-        val _ = restore ();
-      in result end
-      handle Exn.Interrupt => (restore (); Exn.Exn Exn.Interrupt))
-  end;
+    val result =
+      (Thread.setAttributes (safe_interrupts new_atts);
+        Exn.Result (f orig_atts x) before restore ())
+      handle e => Exn.Exn e before restore ()
+  in Exn.release result end;
 
 fun interruptible f = with_attributes regular_interrupts (fn _ => f);
 
@@ -104,7 +104,6 @@
     val watchdog = Thread.fork (fn () =>
       (OS.Process.sleep time; timeout := true; Thread.interrupt worker), []);
 
-    (*RACE! timeout signal vs. external Interrupt*)
     val result = Exn.capture (restore_attributes f) x;
     val was_timeout = (case result of Exn.Exn Exn.Interrupt => ! timeout | _ => false);