more thorough process termination (cf. Scala version);
authorwenzelm
Sat, 27 Nov 2010 20:10:57 +0100
changeset 40750 2064991db2ac
parent 40749 cb6698d2dbaf
child 40756 782399904d9c
more thorough process termination (cf. Scala version);
src/Pure/Concurrent/bash.ML
--- a/src/Pure/Concurrent/bash.ML	Sat Nov 27 19:17:55 2010 +0100
+++ b/src/Pure/Concurrent/bash.ML	Sat Nov 27 20:10:57 2010 +0100
@@ -38,28 +38,41 @@
           in Synchronized.change result (K res) end
           handle _ (*sic*) => Synchronized.change result (fn Wait => Signal | res => res)));
 
+    fun terminate () =
+      let
+        val sig_test = Posix.Signal.fromWord 0w0;
+
+        fun kill_group pid s =
+          (Posix.Process.kill
+            (Posix.Process.K_GROUP (Posix.Process.wordToPid (LargeWord.fromInt pid)), s); true)
+          handle OS.SysErr _ => false;
+
+        fun kill s =
+          (case Int.fromString (File.read pid_path) of
+            NONE => true
+          | SOME pid => (kill_group pid s; kill_group pid sig_test))
+          handle IO.Io _ => true;
+
+        fun multi_kill count s =
+          count = 0 orelse
+            kill s andalso (OS.Process.sleep (seconds 0.1); multi_kill (count - 1) s);
+        val _ =
+          multi_kill 10 Posix.Signal.int andalso
+          multi_kill 10 Posix.Signal.term andalso
+          multi_kill 10 Posix.Signal.kill;
+      in () end;
+
     fun cleanup () =
-     (Simple_Thread.interrupt system_thread;
+     (terminate ();
+      Simple_Thread.interrupt system_thread;
       try File.rm script_path;
       try File.rm output_path;
       try File.rm pid_path);
-
-    fun kill n =
-      (case Int.fromString (File.read pid_path) of
-        SOME pid =>
-          Posix.Process.kill
-            (Posix.Process.K_GROUP (Posix.Process.wordToPid (LargeWord.fromInt pid)),
-              Posix.Signal.int)
-      | NONE => ())
-      handle OS.SysErr _ => ()
-        | IO.Io _ => (OS.Process.sleep (seconds 0.1); if n > 0 then kill (n - 1) else ());
   in
     let
-      (*proxy for interrupts*)
       val _ =
         restore_attributes (fn () =>
-          Synchronized.guarded_access result (fn Wait => NONE | x => SOME ((), x))) ()
-        handle exn => (if Exn.is_interrupt exn then kill 10 else (); reraise exn);
+          Synchronized.guarded_access result (fn Wait => NONE | x => SOME ((), x))) ();
 
       val output = the_default "" (try File.read output_path);
       val rc = (case Synchronized.value result of Signal => Exn.interrupt () | Result rc => rc);