# HG changeset patch # User wenzelm # Date 1290885057 -3600 # Node ID 2064991db2aced26b155b7064861cf7789bc1cd0 # Parent cb6698d2dbaf4292ba1f87b8792f97df7653cdf8 more thorough process termination (cf. Scala version); diff -r cb6698d2dbaf -r 2064991db2ac 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);