| author | wenzelm | 
| Thu, 21 Apr 2022 10:07:17 +0200 | |
| changeset 75441 | 400e325a5416 | 
| parent 75393 | 87ebf5a50283 | 
| child 76488 | 1eed7e1300ed | 
| permissions | -rw-r--r-- | 
| 43283 | 1 | /* Title: Pure/System/isabelle_process.scala | 
| 27949 
6eb0327c0b9b
Isabelle process management -- always reactive due to multi-threaded I/O.
 wenzelm parents: diff
changeset | 2 | Author: Makarius | 
| 
6eb0327c0b9b
Isabelle process management -- always reactive due to multi-threaded I/O.
 wenzelm parents: diff
changeset | 3 | |
| 57916 | 4 | Isabelle process wrapper. | 
| 27949 
6eb0327c0b9b
Isabelle process management -- always reactive due to multi-threaded I/O.
 wenzelm parents: diff
changeset | 5 | */ | 
| 
6eb0327c0b9b
Isabelle process management -- always reactive due to multi-threaded I/O.
 wenzelm parents: diff
changeset | 6 | |
| 
6eb0327c0b9b
Isabelle process management -- always reactive due to multi-threaded I/O.
 wenzelm parents: diff
changeset | 7 | package isabelle | 
| 
6eb0327c0b9b
Isabelle process management -- always reactive due to multi-threaded I/O.
 wenzelm parents: diff
changeset | 8 | |
| 55618 | 9 | |
| 73897 | 10 | import java.util.{Map => JMap}
 | 
| 65310 | 11 | import java.io.{File => JFile}
 | 
| 12 | ||
| 13 | ||
| 75393 | 14 | object Isabelle_Process {
 | 
| 73802 | 15 | def start( | 
| 71594 | 16 | session: Session, | 
| 65216 | 17 | options: Options, | 
| 71594 | 18 | sessions_structure: Sessions.Structure, | 
| 71598 | 19 | store: Sessions.Store, | 
| 65216 | 20 | logic: String = "", | 
| 71639 
ec84f542e411
clarified signature of ML_Process vs. Isabelle_Process: proper support for "isabelle build -P -b";
 wenzelm parents: 
71607diff
changeset | 21 | raw_ml_system: Boolean = false, | 
| 
ec84f542e411
clarified signature of ML_Process vs. Isabelle_Process: proper support for "isabelle build -P -b";
 wenzelm parents: 
71607diff
changeset | 22 | use_prelude: List[String] = Nil, | 
| 
ec84f542e411
clarified signature of ML_Process vs. Isabelle_Process: proper support for "isabelle build -P -b";
 wenzelm parents: 
71607diff
changeset | 23 | eval_main: String = "", | 
| 65216 | 24 | modes: List[String] = Nil, | 
| 65310 | 25 | cwd: JFile = null, | 
| 75393 | 26 | env: JMap[String, String] = Isabelle_System.settings() | 
| 27 |   ): Isabelle_Process = {
 | |
| 62556 
c115e69f457f
more abstract Session.start, without prover command-line;
 wenzelm parents: 
62555diff
changeset | 28 | val channel = System_Channel() | 
| 
c115e69f457f
more abstract Session.start, without prover command-line;
 wenzelm parents: 
62555diff
changeset | 29 | val process = | 
| 57916 | 30 |       try {
 | 
| 69572 
09a6a7c04b45
more robust system channel via options that are private to the user;
 wenzelm parents: 
68209diff
changeset | 31 | val channel_options = | 
| 
09a6a7c04b45
more robust system channel via options that are private to the user;
 wenzelm parents: 
68209diff
changeset | 32 |           options.string.update("system_channel_address", channel.address).
 | 
| 
09a6a7c04b45
more robust system channel via options that are private to the user;
 wenzelm parents: 
68209diff
changeset | 33 |             string.update("system_channel_password", channel.password)
 | 
| 71598 | 34 | ML_Process(channel_options, sessions_structure, store, | 
| 71639 
ec84f542e411
clarified signature of ML_Process vs. Isabelle_Process: proper support for "isabelle build -P -b";
 wenzelm parents: 
71607diff
changeset | 35 | logic = logic, raw_ml_system = raw_ml_system, | 
| 
ec84f542e411
clarified signature of ML_Process vs. Isabelle_Process: proper support for "isabelle build -P -b";
 wenzelm parents: 
71607diff
changeset | 36 | use_prelude = use_prelude, eval_main = eval_main, | 
| 
ec84f542e411
clarified signature of ML_Process vs. Isabelle_Process: proper support for "isabelle build -P -b";
 wenzelm parents: 
71607diff
changeset | 37 | modes = modes, cwd = cwd, env = env) | 
| 57916 | 38 | } | 
| 69572 
09a6a7c04b45
more robust system channel via options that are private to the user;
 wenzelm parents: 
68209diff
changeset | 39 |       catch { case exn @ ERROR(_) => channel.shutdown(); throw exn }
 | 
| 57917 | 40 | |
| 73802 | 41 | val isabelle_process = new Isabelle_Process(session, process) | 
| 73803 
2141d6c83511
tuned --- potentially more robust (e.g. session.phase_changed vs. isabelle_process.terminated);
 wenzelm parents: 
73802diff
changeset | 42 | process.stdin.close() | 
| 73802 | 43 | session.start(receiver => new Prover(receiver, session.cache, channel, process)) | 
| 44 | ||
| 45 | isabelle_process | |
| 57917 | 46 | } | 
| 57916 | 47 | } | 
| 71604 | 48 | |
| 75393 | 49 | class Isabelle_Process private(session: Session, process: Bash.Process) {
 | 
| 71607 | 50 | private val startup = Future.promise[String] | 
| 51 | private val terminated = Future.promise[Process_Result] | |
| 71604 | 52 | |
| 53 | session.phase_changed += | |
| 54 |     Session.Consumer(getClass.getName) {
 | |
| 55 | case Session.Ready => | |
| 71607 | 56 |         startup.fulfill("")
 | 
| 57 | case Session.Terminated(result) => | |
| 58 |         if (!result.ok && !startup.is_finished) {
 | |
| 59 | val syslog = session.syslog_content() | |
| 60 | val err = "Session startup failed" + (if (syslog.isEmpty) "" else ":\n" + syslog) | |
| 61 | startup.fulfill(err) | |
| 62 | } | |
| 63 | terminated.fulfill(result) | |
| 71604 | 64 | case _ => | 
| 65 | } | |
| 66 | ||
| 71607 | 67 | def await_startup(): Isabelle_Process = | 
| 68 |     startup.join match {
 | |
| 69 | case "" => this | |
| 70 | case err => session.stop(); error(err) | |
| 71604 | 71 | } | 
| 72 | ||
| 75393 | 73 |   def await_shutdown(): Process_Result = {
 | 
| 71667 
4d2de35214c5
proper treatment of protocol exceptions and prover termination: avoid session.stop while saving image;
 wenzelm parents: 
71639diff
changeset | 74 | val result = terminated.join | 
| 
4d2de35214c5
proper treatment of protocol exceptions and prover termination: avoid session.stop while saving image;
 wenzelm parents: 
71639diff
changeset | 75 | session.stop() | 
| 
4d2de35214c5
proper treatment of protocol exceptions and prover termination: avoid session.stop while saving image;
 wenzelm parents: 
71639diff
changeset | 76 | result | 
| 
4d2de35214c5
proper treatment of protocol exceptions and prover termination: avoid session.stop while saving image;
 wenzelm parents: 
71639diff
changeset | 77 | } | 
| 71718 | 78 | |
| 73367 | 79 | def terminate(): Unit = process.terminate() | 
| 71667 
4d2de35214c5
proper treatment of protocol exceptions and prover termination: avoid session.stop while saving image;
 wenzelm parents: 
71639diff
changeset | 80 | } |