support for watchdog thread;
authorwenzelm
Thu, 12 Nov 2020 16:07:25 +0100
changeset 72598 d9f2be66ebad
parent 72597 e8d7dc1c229c
child 72599 76550282267f
support for watchdog thread;
src/Pure/System/bash.scala
src/Pure/System/isabelle_system.scala
--- a/src/Pure/System/bash.scala	Thu Nov 12 12:34:36 2020 +0100
+++ b/src/Pure/System/bash.scala	Thu Nov 12 16:07:25 2020 +0100
@@ -45,6 +45,8 @@
 
   /* process and result */
 
+  type Watchdog = (Time, Process => Boolean)
+
   def process(script: String,
       cwd: JFile = null,
       env: Map[String, String] = Isabelle_System.settings(),
@@ -168,6 +170,7 @@
     def result(
       progress_stdout: String => Unit = (_: String) => (),
       progress_stderr: String => Unit = (_: String) => (),
+      watchdog: Option[Watchdog] = None,
       strict: Boolean = true): Process_Result =
     {
       stdin.close
@@ -177,9 +180,23 @@
       val err_lines =
         Future.thread("bash_stderr") { File.read_lines(stderr, progress_stderr) }
 
+      val watchdog_thread =
+        for ((time, check) <- watchdog)
+        yield {
+          Future.thread("bash_watchdog") {
+            while (proc.isAlive) {
+              time.sleep
+              if (check(this)) interrupt()
+            }
+          }
+        }
+
       val rc =
         try { join }
         catch { case Exn.Interrupt() => terminate(); Exn.Interrupt.return_code }
+
+      watchdog_thread.foreach(_.cancel)
+
       if (strict && rc == Exn.Interrupt.return_code) throw Exn.Interrupt()
 
       Process_Result(rc, out_lines.join, err_lines.join, false, get_timing)
--- a/src/Pure/System/isabelle_system.scala	Thu Nov 12 12:34:36 2020 +0100
+++ b/src/Pure/System/isabelle_system.scala	Thu Nov 12 16:07:25 2020 +0100
@@ -347,11 +347,13 @@
     redirect: Boolean = false,
     progress_stdout: String => Unit = (_: String) => (),
     progress_stderr: String => Unit = (_: String) => (),
+    watchdog: Option[Bash.Watchdog] = None,
     strict: Boolean = true,
     cleanup: () => Unit = () => ()): Process_Result =
   {
     Bash.process(script, cwd = cwd, env = env, redirect = redirect, cleanup = cleanup).
-      result(progress_stdout, progress_stderr, strict)
+      result(progress_stdout = progress_stdout, progress_stderr = progress_stderr,
+        watchdog = watchdog, strict = strict)
   }
 
   def jconsole(): Process_Result =