| author | wenzelm | 
| Fri, 10 Jun 2011 12:51:29 +0200 | |
| changeset 43348 | 3e153e719039 | 
| parent 42897 | 6bc8a6dcb3e0 | 
| child 43671 | a250b092ac66 | 
| permissions | -rw-r--r-- | 
| 30173 
eabece26b89b
moved isabelle_process.ML, isabelle_process.scala, isar.ML, session.ML to Pure/System/ (together with associated Isar commands);
 wenzelm parents: 
29522diff
changeset | 1 | (* Title: Pure/System/isabelle_process.ML | 
| 25528 
e67230c2b952
Isabelle process wrapper -- interaction via external program.
 wenzelm parents: diff
changeset | 2 | Author: Makarius | 
| 
e67230c2b952
Isabelle process wrapper -- interaction via external program.
 wenzelm parents: diff
changeset | 3 | |
| 38445 
ba9ea6b9b75c
simplified internal message format: dropped special Symbol.STX header;
 wenzelm parents: 
38270diff
changeset | 4 | Isabelle process wrapper, based on private fifos for maximum | 
| 
ba9ea6b9b75c
simplified internal message format: dropped special Symbol.STX header;
 wenzelm parents: 
38270diff
changeset | 5 | robustness and performance. | 
| 39528 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 6 | |
| 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 7 | Startup phases: | 
| 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 8 | . raw Posix process startup with uncontrolled output on stdout/stderr | 
| 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 9 | . stdout \002: ML running | 
| 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 10 | .. stdin/stdout/stderr freely available (raw ML loop) | 
| 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 11 | .. protocol thread initialization | 
| 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 12 | ... switch to in_fifo/out_fifo channels (rendezvous via open) | 
| 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 13 | ... out_fifo INIT(pid): channels ready | 
| 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 14 | ... out_fifo STATUS(keywords) | 
| 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 15 | ... out_fifo READY: main loop ready | 
| 25528 
e67230c2b952
Isabelle process wrapper -- interaction via external program.
 wenzelm parents: diff
changeset | 16 | *) | 
| 
e67230c2b952
Isabelle process wrapper -- interaction via external program.
 wenzelm parents: diff
changeset | 17 | |
| 
e67230c2b952
Isabelle process wrapper -- interaction via external program.
 wenzelm parents: diff
changeset | 18 | signature ISABELLE_PROCESS = | 
| 
e67230c2b952
Isabelle process wrapper -- interaction via external program.
 wenzelm parents: diff
changeset | 19 | sig | 
| 42897 | 20 | val is_active: unit -> bool | 
| 38270 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 21 | val add_command: string -> (string list -> unit) -> unit | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 22 | val command: string -> string list -> unit | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 23 | val crashes: exn list Unsynchronized.ref | 
| 38253 
3d4e521014f7
Isabelle_Process: separate input fifo for commands (still using the old tty protocol);
 wenzelm parents: 
38236diff
changeset | 24 | val init: string -> string -> unit | 
| 25528 
e67230c2b952
Isabelle process wrapper -- interaction via external program.
 wenzelm parents: diff
changeset | 25 | end; | 
| 
e67230c2b952
Isabelle process wrapper -- interaction via external program.
 wenzelm parents: diff
changeset | 26 | |
| 31797 | 27 | structure Isabelle_Process: ISABELLE_PROCESS = | 
| 25528 
e67230c2b952
Isabelle process wrapper -- interaction via external program.
 wenzelm parents: diff
changeset | 28 | struct | 
| 
e67230c2b952
Isabelle process wrapper -- interaction via external program.
 wenzelm parents: diff
changeset | 29 | |
| 42897 | 30 | (* print mode *) | 
| 25554 | 31 | |
| 25748 | 32 | val isabelle_processN = "isabelle_process"; | 
| 33 | ||
| 42897 | 34 | fun is_active () = Print_Mode.print_mode_active isabelle_processN; | 
| 35 | ||
| 26550 | 36 | val _ = Output.add_mode isabelle_processN Output.default_output Output.default_escape; | 
| 28036 | 37 | val _ = Markup.add_mode isabelle_processN YXML.output_markup; | 
| 25841 | 38 | |
| 39 | ||
| 38270 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 40 | (* commands *) | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 41 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 42 | local | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 43 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 44 | val global_commands = Unsynchronized.ref (Symtab.empty: (string list -> unit) Symtab.table); | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 45 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 46 | in | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 47 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 48 | fun add_command name cmd = CRITICAL (fn () => | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 49 | Unsynchronized.change global_commands (fn cmds => | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 50 | (if not (Symtab.defined cmds name) then () | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 51 |     else warning ("Redefining Isabelle process command " ^ quote name);
 | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 52 | Symtab.update (name, cmd) cmds))); | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 53 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 54 | fun command name args = | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 55 | (case Symtab.lookup (! global_commands) name of | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 56 |     NONE => error ("Undefined Isabelle process command " ^ quote name)
 | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 57 | | SOME cmd => cmd args); | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 58 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 59 | end; | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 60 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 61 | |
| 40134 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 62 | (* message channels *) | 
| 25841 | 63 | |
| 64 | local | |
| 25810 | 65 | |
| 40134 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 66 | fun chunk s = [string_of_int (size s), "\n", s]; | 
| 26574 
560d07845442
support "YXML" mode for output transfer notation;
 wenzelm parents: 
26550diff
changeset | 67 | |
| 34096 
e438a5875c16
simplified message format: chunks with explicit size in bytes;
 wenzelm parents: 
33225diff
changeset | 68 | fun message _ _ _ "" = () | 
| 40134 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 69 | | message mbox ch raw_props body = | 
| 34096 
e438a5875c16
simplified message format: chunks with explicit size in bytes;
 wenzelm parents: 
33225diff
changeset | 70 | let | 
| 38445 
ba9ea6b9b75c
simplified internal message format: dropped special Symbol.STX header;
 wenzelm parents: 
38270diff
changeset | 71 | val robust_props = map (pairself YXML.escape_controls) raw_props; | 
| 
ba9ea6b9b75c
simplified internal message format: dropped special Symbol.STX header;
 wenzelm parents: 
38270diff
changeset | 72 | val header = YXML.string_of (XML.Elem ((ch, robust_props), [])); | 
| 40134 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 73 | in Mailbox.send mbox (chunk header @ chunk body) end; | 
| 25554 | 74 | |
| 40134 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 75 | fun standard_message mbox with_serial ch body = | 
| 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 76 | message mbox ch | 
| 39509 
cab2719398a7
Isabelle_Process: status/report do not require serial numbers;
 wenzelm parents: 
39234diff
changeset | 77 | ((if with_serial then cons (Markup.serialN, serial_string ()) else I) | 
| 
cab2719398a7
Isabelle_Process: status/report do not require serial numbers;
 wenzelm parents: 
39234diff
changeset | 78 | (Position.properties_of (Position.thread_data ()))) body; | 
| 25554 | 79 | |
| 40134 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 80 | fun message_output mbox out_stream = | 
| 28188 | 81 | let | 
| 40134 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 82 | fun loop receive = | 
| 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 83 | (case receive mbox of | 
| 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 84 | SOME msg => | 
| 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 85 | (List.app (fn s => TextIO.output (out_stream, s)) msg; | 
| 40301 | 86 | loop (Mailbox.receive_timeout (seconds 0.02))) | 
| 40134 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 87 | | NONE => (try TextIO.flushOut out_stream; loop (SOME o Mailbox.receive))); | 
| 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 88 | in fn () => loop (SOME o Mailbox.receive) end; | 
| 28188 | 89 | |
| 90 | in | |
| 91 | ||
| 38253 
3d4e521014f7
Isabelle_Process: separate input fifo for commands (still using the old tty protocol);
 wenzelm parents: 
38236diff
changeset | 92 | fun setup_channels in_fifo out_fifo = | 
| 28189 
fbad2eb5be9e
auto_flush: uniform block buffering for all output streams;
 wenzelm parents: 
28188diff
changeset | 93 | let | 
| 39530 
16adc476348f
Isabelle_Process: more robust rendezvous, even without proper blocking on open (Cygwin);
 wenzelm parents: 
39528diff
changeset | 94 | (*rendezvous*) | 
| 
16adc476348f
Isabelle_Process: more robust rendezvous, even without proper blocking on open (Cygwin);
 wenzelm parents: 
39528diff
changeset | 95 | val in_stream = TextIO.openIn in_fifo; | 
| 
16adc476348f
Isabelle_Process: more robust rendezvous, even without proper blocking on open (Cygwin);
 wenzelm parents: 
39528diff
changeset | 96 | val out_stream = TextIO.openOut out_fifo; | 
| 
16adc476348f
Isabelle_Process: more robust rendezvous, even without proper blocking on open (Cygwin);
 wenzelm parents: 
39528diff
changeset | 97 | |
| 40134 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 98 | val _ = TextIO.StreamIO.setBufferMode (TextIO.getOutstream TextIO.stdOut, IO.LINE_BUF); | 
| 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 99 | val _ = TextIO.StreamIO.setBufferMode (TextIO.getOutstream TextIO.stdErr, IO.LINE_BUF); | 
| 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 100 | |
| 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 101 | val mbox = Mailbox.create () : string list Mailbox.T; | 
| 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 102 | val _ = Simple_Thread.fork false (message_output mbox out_stream); | 
| 28044 | 103 | in | 
| 40134 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 104 | Output.Private_Hooks.status_fn := standard_message mbox false "B"; | 
| 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 105 | Output.Private_Hooks.report_fn := standard_message mbox false "C"; | 
| 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 106 | Output.Private_Hooks.writeln_fn := standard_message mbox true "D"; | 
| 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 107 | Output.Private_Hooks.tracing_fn := standard_message mbox true "E"; | 
| 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 108 | Output.Private_Hooks.warning_fn := standard_message mbox true "F"; | 
| 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 109 | Output.Private_Hooks.error_fn := standard_message mbox true "G"; | 
| 40133 
b61d52de66f0
more explicit indication of Output.Private_Hooks (still public to accomodate clones of Proof General for now);
 wenzelm parents: 
40132diff
changeset | 110 | Output.Private_Hooks.urgent_message_fn := ! Output.Private_Hooks.writeln_fn; | 
| 
b61d52de66f0
more explicit indication of Output.Private_Hooks (still public to accomodate clones of Proof General for now);
 wenzelm parents: 
40132diff
changeset | 111 | Output.Private_Hooks.prompt_fn := ignore; | 
| 40134 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 112 | message mbox "A" [] (Session.welcome ()); | 
| 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 113 | in_stream | 
| 28044 | 114 | end; | 
| 25841 | 115 | |
| 28188 | 116 | end; | 
| 117 | ||
| 25841 | 118 | |
| 39234 
d76a2fd129b5
main command loops are supposed to be uninterruptible -- no special treatment here;
 wenzelm parents: 
38871diff
changeset | 119 | (* protocol loop -- uninterruptible *) | 
| 38270 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 120 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 121 | val crashes = Unsynchronized.ref ([]: exn list); | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 122 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 123 | local | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 124 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 125 | fun recover crash = | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 126 | (CRITICAL (fn () => Unsynchronized.change crashes (cons crash)); | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 127 | warning "Recovering from Isabelle process crash -- see also Isabelle_Process.crashes"); | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 128 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 129 | fun read_chunk stream len = | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 130 | let | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 131 | val n = | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 132 | (case Int.fromString len of | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 133 | SOME n => n | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 134 |       | NONE => error ("Isabelle process: malformed chunk header " ^ quote len));
 | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 135 | val chunk = TextIO.inputN (stream, n); | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 136 | val m = size chunk; | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 137 | in | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 138 | if m = n then chunk | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 139 |     else error ("Isabelle process: bad chunk (" ^ string_of_int m ^ " vs. " ^ string_of_int n ^ ")")
 | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 140 | end; | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 141 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 142 | fun read_command stream = | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 143 | (case TextIO.inputLine stream of | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 144 | NONE => raise Runtime.TERMINATE | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 145 | | SOME line => map (read_chunk stream) (space_explode "," line)); | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 146 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 147 | fun run_command name args = | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 148 | Runtime.debugging (command name) args | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 149 | handle exn => | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 150 |       error ("Isabelle process command failure: " ^ name ^ "\n" ^ ML_Compiler.exn_message exn);
 | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 151 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 152 | in | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 153 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 154 | fun loop stream = | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 155 | let val continue = | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 156 | (case read_command stream of | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 157 | [] => (Output.error_msg "Isabelle process: no input"; true) | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 158 | | name :: args => (run_command name args; true)) | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 159 | handle Runtime.TERMINATE => false | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 160 | | exn => (Output.error_msg (ML_Compiler.exn_message exn) handle crash => recover crash; true); | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 161 | in if continue then loop stream else () end; | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 162 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 163 | end; | 
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 164 | |
| 
71bb3c273dd1
native Isabelle_Process commands, based on efficient byte channel protocol for string lists;
 wenzelm parents: 
38265diff
changeset | 165 | |
| 25554 | 166 | (* init *) | 
| 167 | ||
| 39528 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 168 | fun init in_fifo out_fifo = ignore (Simple_Thread.fork false (fn () => | 
| 38253 
3d4e521014f7
Isabelle_Process: separate input fifo for commands (still using the old tty protocol);
 wenzelm parents: 
38236diff
changeset | 169 | let | 
| 40301 | 170 | val _ = OS.Process.sleep (seconds 0.5); (*yield to raw ML toplevel*) | 
| 39733 
6d373e9dcb9d
renamed raw output primitives to emphasize their meaning -- not to be used in user-space;
 wenzelm parents: 
39626diff
changeset | 171 | val _ = Output.raw_stdout Symbol.STX; | 
| 39528 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 172 | |
| 40521 
8896bd93488e
back to quick_and_dirty, which is still practically important since the scheduler does not jump over subproofs;
 wenzelm parents: 
40518diff
changeset | 173 | val _ = quick_and_dirty := true; | 
| 40518 
035a27279705
defensive defaults for more robust experience for new users;
 wenzelm parents: 
40301diff
changeset | 174 | val _ = Goal.parallel_proofs := 0; | 
| 39528 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 175 | val _ = Context.set_thread_data NONE; | 
| 38253 
3d4e521014f7
Isabelle_Process: separate input fifo for commands (still using the old tty protocol);
 wenzelm parents: 
38236diff
changeset | 176 | val _ = Unsynchronized.change print_mode | 
| 
3d4e521014f7
Isabelle_Process: separate input fifo for commands (still using the old tty protocol);
 wenzelm parents: 
38236diff
changeset | 177 | (fold (update op =) [isabelle_processN, Keyword.keyword_statusN, Pretty.symbolicN]); | 
| 39528 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 178 | |
| 40134 
8baded087d34
explicit message_output thread, with flushing after timeout, ensure atomic user-operations without the danger of IO Interrupt;
 wenzelm parents: 
40133diff
changeset | 179 | val in_stream = setup_channels in_fifo out_fifo; | 
| 38253 
3d4e521014f7
Isabelle_Process: separate input fifo for commands (still using the old tty protocol);
 wenzelm parents: 
38236diff
changeset | 180 | val _ = Keyword.status (); | 
| 39626 
a5d0bcfb95a3
manage persistent syslog via Session, not Isabelle_Process;
 wenzelm parents: 
39591diff
changeset | 181 | val _ = Output.status (Markup.markup Markup.ready "process ready"); | 
| 39528 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 182 | in loop in_stream end)); | 
| 25528 
e67230c2b952
Isabelle process wrapper -- interaction via external program.
 wenzelm parents: diff
changeset | 183 | |
| 
e67230c2b952
Isabelle process wrapper -- interaction via external program.
 wenzelm parents: diff
changeset | 184 | end; | 
| 39528 
c01d89d18ff0
refined Isabelle_Process startup: emit \002 before rendezvous on fifos, more robust treatment of startup failure with timeout, do not quit() after main loop;
 wenzelm parents: 
39513diff
changeset | 185 |