| author | wenzelm | 
| Thu, 15 Jul 2021 16:35:45 +0200 | |
| changeset 73987 | fc363a3b690a | 
| parent 73897 | 0ddb5de0506e | 
| child 75393 | 87ebf5a50283 | 
| 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 | ||
| 57917 | 14 | object Isabelle_Process | 
| 15 | {
 | |
| 73802 | 16 | def start( | 
| 71594 | 17 | session: Session, | 
| 65216 | 18 | options: Options, | 
| 71594 | 19 | sessions_structure: Sessions.Structure, | 
| 71598 | 20 | store: Sessions.Store, | 
| 65216 | 21 | logic: String = "", | 
| 71639 
ec84f542e411
clarified signature of ML_Process vs. Isabelle_Process: proper support for "isabelle build -P -b";
 wenzelm parents: 
71607diff
changeset | 22 | 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 | 23 | 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 | 24 | eval_main: String = "", | 
| 65216 | 25 | modes: List[String] = Nil, | 
| 65310 | 26 | cwd: JFile = null, | 
| 73897 | 27 | env: JMap[String, String] = Isabelle_System.settings()): Isabelle_Process = | 
| 65216 | 28 |   {
 | 
| 62556 
c115e69f457f
more abstract Session.start, without prover command-line;
 wenzelm parents: 
62555diff
changeset | 29 | val channel = System_Channel() | 
| 
c115e69f457f
more abstract Session.start, without prover command-line;
 wenzelm parents: 
62555diff
changeset | 30 | val process = | 
| 57916 | 31 |       try {
 | 
| 69572 
09a6a7c04b45
more robust system channel via options that are private to the user;
 wenzelm parents: 
68209diff
changeset | 32 | val channel_options = | 
| 
09a6a7c04b45
more robust system channel via options that are private to the user;
 wenzelm parents: 
68209diff
changeset | 33 |           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 | 34 |             string.update("system_channel_password", channel.password)
 | 
| 71598 | 35 | 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 | 36 | 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 | 37 | 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 | 38 | modes = modes, cwd = cwd, env = env) | 
| 57916 | 39 | } | 
| 69572 
09a6a7c04b45
more robust system channel via options that are private to the user;
 wenzelm parents: 
68209diff
changeset | 40 |       catch { case exn @ ERROR(_) => channel.shutdown(); throw exn }
 | 
| 57917 | 41 | |
| 73802 | 42 | 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 | 43 | process.stdin.close() | 
| 73802 | 44 | session.start(receiver => new Prover(receiver, session.cache, channel, process)) | 
| 45 | ||
| 46 | isabelle_process | |
| 57917 | 47 | } | 
| 57916 | 48 | } | 
| 71604 | 49 | |
| 73802 | 50 | class Isabelle_Process private(session: Session, process: Bash.Process) | 
| 71604 | 51 | {
 | 
| 71607 | 52 | private val startup = Future.promise[String] | 
| 53 | private val terminated = Future.promise[Process_Result] | |
| 71604 | 54 | |
| 55 | session.phase_changed += | |
| 56 |     Session.Consumer(getClass.getName) {
 | |
| 57 | case Session.Ready => | |
| 71607 | 58 |         startup.fulfill("")
 | 
| 59 | case Session.Terminated(result) => | |
| 60 |         if (!result.ok && !startup.is_finished) {
 | |
| 61 | val syslog = session.syslog_content() | |
| 62 | val err = "Session startup failed" + (if (syslog.isEmpty) "" else ":\n" + syslog) | |
| 63 | startup.fulfill(err) | |
| 64 | } | |
| 65 | terminated.fulfill(result) | |
| 71604 | 66 | case _ => | 
| 67 | } | |
| 68 | ||
| 71607 | 69 | def await_startup(): Isabelle_Process = | 
| 70 |     startup.join match {
 | |
| 71 | case "" => this | |
| 72 | case err => session.stop(); error(err) | |
| 71604 | 73 | } | 
| 74 | ||
| 71667 
4d2de35214c5
proper treatment of protocol exceptions and prover termination: avoid session.stop while saving image;
 wenzelm parents: 
71639diff
changeset | 75 | def await_shutdown(): Process_Result = | 
| 
4d2de35214c5
proper treatment of protocol exceptions and prover termination: avoid session.stop while saving image;
 wenzelm parents: 
71639diff
changeset | 76 |   {
 | 
| 
4d2de35214c5
proper treatment of protocol exceptions and prover termination: avoid session.stop while saving image;
 wenzelm parents: 
71639diff
changeset | 77 | val result = terminated.join | 
| 
4d2de35214c5
proper treatment of protocol exceptions and prover termination: avoid session.stop while saving image;
 wenzelm parents: 
71639diff
changeset | 78 | session.stop() | 
| 
4d2de35214c5
proper treatment of protocol exceptions and prover termination: avoid session.stop while saving image;
 wenzelm parents: 
71639diff
changeset | 79 | result | 
| 
4d2de35214c5
proper treatment of protocol exceptions and prover termination: avoid session.stop while saving image;
 wenzelm parents: 
71639diff
changeset | 80 | } | 
| 71718 | 81 | |
| 73367 | 82 | 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 | 83 | } |