src/Pure/System/isabelle_process.scala
changeset 39587 f84b70e3bb9c
parent 39585 00be8711082f
child 39591 a43a723753e6
equal deleted inserted replaced
39586:ea8f3ea13a95 39587:f84b70e3bb9c
   134         List(system.getenv_strict("ISABELLE_PROCESS"), "-W", in_fifo + ":" + out_fifo) ++ args
   134         List(system.getenv_strict("ISABELLE_PROCESS"), "-W", in_fifo + ":" + out_fifo) ++ args
   135       new system.Managed_Process(true, cmdline: _*)
   135       new system.Managed_Process(true, cmdline: _*)
   136     }
   136     }
   137     catch { case e: IOException => rm_fifos(); throw(e) }
   137     catch { case e: IOException => rm_fifos(); throw(e) }
   138 
   138 
       
   139   val process_result =
       
   140     Simple_Thread.future("process_result") { process.join }
       
   141 
   139   private def terminate_process()
   142   private def terminate_process()
   140   {
   143   {
   141     try { process.terminate }
   144     try { process.terminate }
   142     catch { case e: IOException => system_result("Failed to terminate Isabelle: " + e.getMessage) }
   145     catch { case e: IOException => system_result("Failed to terminate Isabelle: " + e.getMessage) }
   143   }
   146   }
   147     val (startup_failed, startup_output) =
   150     val (startup_failed, startup_output) =
   148     {
   151     {
   149       val expired = System.currentTimeMillis() + timeout
   152       val expired = System.currentTimeMillis() + timeout
   150       val result = new StringBuilder(100)
   153       val result = new StringBuilder(100)
   151 
   154 
   152       var finished = false
   155       var finished: Option[Boolean] = None
   153       while (!finished && System.currentTimeMillis() <= expired) {
   156       while (finished.isEmpty && System.currentTimeMillis() <= expired) {
   154         while (!finished && process.stdout.ready) {
   157         while (finished.isEmpty && process.stdout.ready) {
   155           val c = process.stdout.read
   158           val c = process.stdout.read
   156           if (c == 2) finished = true
   159           if (c == 2) finished = Some(true)
   157           else result += c.toChar
   160           else result += c.toChar
   158         }
   161         }
   159         Thread.sleep(10)
   162         if (process_result.is_finished) finished = Some(false)
   160       }
   163         else Thread.sleep(10)
   161       (!finished, result.toString)
   164       }
       
   165       (finished.isEmpty || !finished.get, result.toString)
   162     }
   166     }
   163     system_result(startup_output)
   167     system_result(startup_output)
   164 
   168 
   165     if (startup_failed) {
   169     if (startup_failed) {
   166       put_result(Markup.EXIT, "127")
   170       put_result(Markup.EXIT, "127")
   167       process.stdin.close
   171       process.stdin.close
   168       Thread.sleep(300)
   172       Thread.sleep(300)
   169       terminate_process()
   173       terminate_process()
       
   174       process_result.join
   170     }
   175     }
   171     else {
   176     else {
   172       // rendezvous
   177       // rendezvous
   173       val command_stream = system.fifo_output_stream(in_fifo)
   178       val command_stream = system.fifo_output_stream(in_fifo)
   174       val message_stream = system.fifo_input_stream(out_fifo)
   179       val message_stream = system.fifo_input_stream(out_fifo)
   176       standard_input = stdin_actor()
   181       standard_input = stdin_actor()
   177       val stdout = stdout_actor()
   182       val stdout = stdout_actor()
   178       command_input = input_actor(command_stream)
   183       command_input = input_actor(command_stream)
   179       val message = message_actor(message_stream)
   184       val message = message_actor(message_stream)
   180 
   185 
   181       val rc = process.join
   186       val rc = process_result.join
   182       system_result("Isabelle process terminated")
   187       system_result("Isabelle process terminated")
   183       for ((thread, _) <- List(standard_input, stdout, command_input, message)) thread.join
   188       for ((thread, _) <- List(standard_input, stdout, command_input, message)) thread.join
   184       system_result("process_manager terminated")
   189       system_result("process_manager terminated")
   185       put_result(Markup.EXIT, rc.toString)
   190       put_result(Markup.EXIT, rc.toString)
   186     }
   191     }