more robust kill: not always running on Isabelle_Thread (e.g. POSIX_Interrupt handler);
authorwenzelm
Mon, 06 Apr 2020 21:04:33 +0200
changeset 71712 c6b7f4da67b3
parent 71711 d9aaafcd872b
child 71713 928fd852f3e2
more robust kill: not always running on Isabelle_Thread (e.g. POSIX_Interrupt handler);
src/Pure/Concurrent/isabelle_thread.scala
src/Pure/System/bash.scala
--- a/src/Pure/Concurrent/isabelle_thread.scala	Mon Apr 06 20:11:07 2020 +0200
+++ b/src/Pure/Concurrent/isabelle_thread.scala	Mon Apr 06 21:04:33 2020 +0200
@@ -20,6 +20,9 @@
       case _ => error("Isabelle-specific thread required")
     }
 
+  def check_self: Boolean =
+    Thread.currentThread.isInstanceOf[Isabelle_Thread]
+
 
   /* create threads */
 
@@ -107,6 +110,10 @@
 
   def uninterruptible[A](body: => A): A =
     interrupt_handler(Interrupt_Handler.uninterruptible)(body)
+
+  def try_uninterruptible[A](body: => A): A =
+    if (check_self) interrupt_handler(Interrupt_Handler.uninterruptible)(body)
+    else body
 }
 
 class Isabelle_Thread private(main: Runnable, name: String, group: ThreadGroup,
--- a/src/Pure/System/bash.scala	Mon Apr 06 20:11:07 2020 +0200
+++ b/src/Pure/System/bash.scala	Mon Apr 06 21:04:33 2020 +0200
@@ -116,14 +116,14 @@
       }
     }
 
-    def terminate(): Unit = Isabelle_Thread.uninterruptible
+    def terminate(): Unit = Isabelle_Thread.try_uninterruptible
     {
       kill("INT", count = 7) && kill("TERM", count = 3) && kill("KILL")
       proc.destroy
       do_cleanup()
     }
 
-    def interrupt(): Unit = Isabelle_Thread.uninterruptible
+    def interrupt(): Unit = Isabelle_Thread.try_uninterruptible
     {
       Isabelle_System.kill("INT", pid)
     }
@@ -131,7 +131,7 @@
 
     // JVM shutdown hook
 
-    private val shutdown_hook = new Thread { override def run = terminate() }
+    private val shutdown_hook = Isabelle_Thread.create(() => terminate())
 
     try { Runtime.getRuntime.addShutdownHook(shutdown_hook) }
     catch { case _: IllegalStateException => }