src/Pure/System/isabelle_process.ML
changeset 71667 4d2de35214c5
parent 71656 3e121f999120
child 71675 55cb4271858b
equal deleted inserted replaced
71666:e15ca98ffbfe 71667:4d2de35214c5
     5 *)
     5 *)
     6 
     6 
     7 signature ISABELLE_PROCESS =
     7 signature ISABELLE_PROCESS =
     8 sig
     8 sig
     9   val is_active: unit -> bool
     9   val is_active: unit -> bool
       
    10   exception STOP
       
    11   exception EXIT of int
    10   val protocol_command: string -> (string list -> unit) -> unit
    12   val protocol_command: string -> (string list -> unit) -> unit
    11   val reset_tracing: Document_ID.exec -> unit
    13   val reset_tracing: Document_ID.exec -> unit
    12   exception EXIT of int
       
    13   val crashes: exn list Synchronized.var
    14   val crashes: exn list Synchronized.var
    14   val init_options: unit -> unit
    15   val init_options: unit -> unit
    15   val init_options_interactive: unit -> unit
    16   val init_options_interactive: unit -> unit
    16   val init: unit -> unit
    17   val init: unit -> unit
    17   val init_build: unit -> unit
    18   val init_build: unit -> unit
    33 val protocol_modes2 = [isabelle_processN, Pretty.symbolicN];
    34 val protocol_modes2 = [isabelle_processN, Pretty.symbolicN];
    34 
    35 
    35 
    36 
    36 (* protocol commands *)
    37 (* protocol commands *)
    37 
    38 
       
    39 exception STOP;
       
    40 exception EXIT of int;
       
    41 
       
    42 val is_protocol_exn = fn STOP => true | EXIT _ => true | _ => false;
       
    43 
    38 local
    44 local
    39 
    45 
    40 val commands =
    46 val commands =
    41   Synchronized.var "Isabelle_Process.commands"
    47   Synchronized.var "Isabelle_Process.commands"
    42     (Symtab.empty: (string list -> unit) Symtab.table);
    48     (Symtab.empty: (string list -> unit) Symtab.table);
    52 fun run_command name args =
    58 fun run_command name args =
    53   (case Symtab.lookup (Synchronized.value commands) name of
    59   (case Symtab.lookup (Synchronized.value commands) name of
    54     NONE => error ("Undefined Isabelle protocol command " ^ quote name)
    60     NONE => error ("Undefined Isabelle protocol command " ^ quote name)
    55   | SOME cmd =>
    61   | SOME cmd =>
    56       (Runtime.exn_trace_system (fn () => cmd args)
    62       (Runtime.exn_trace_system (fn () => cmd args)
    57         handle _ (*sic!*) => error ("Isabelle protocol command failure: " ^ quote name)));
    63         handle exn =>
       
    64           if is_protocol_exn exn then Exn.reraise exn
       
    65           else error ("Isabelle protocol command failure: " ^ quote name)));
    58 
    66 
    59 end;
    67 end;
    60 
    68 
    61 
    69 
    62 (* restricted tracing messages *)
    70 (* restricted tracing messages *)
    96       end);
   104       end);
    97 
   105 
    98 
   106 
    99 (* init protocol -- uninterruptible *)
   107 (* init protocol -- uninterruptible *)
   100 
   108 
   101 exception EXIT of int;
       
   102 
       
   103 val crashes = Synchronized.var "Isabelle_Process.crashes" ([]: exn list);
   109 val crashes = Synchronized.var "Isabelle_Process.crashes" ([]: exn list);
   104 
   110 
   105 local
   111 local
   106 
   112 
   107 fun recover crash =
   113 fun recover crash =
   179 
   185 
   180     (* protocol *)
   186     (* protocol *)
   181 
   187 
   182     fun protocol_loop () =
   188     fun protocol_loop () =
   183       let
   189       let
   184         val continue =
   190         val _ =
   185           (case Byte_Message.read_message in_stream of
   191           (case Byte_Message.read_message in_stream of
   186             NONE => false
   192             NONE => raise STOP
   187           | SOME [] => (Output.system_message "Isabelle process: no input"; true)
   193           | SOME [] => Output.system_message "Isabelle process: no input"
   188           | SOME (name :: args) => (run_command name args; true))
   194           | SOME (name :: args) => run_command name args)
   189           handle exn as EXIT _ => Exn.reraise exn
   195           handle exn =>
   190             | exn => (Runtime.exn_system_message exn handle crash => recover crash; true);
   196             if is_protocol_exn exn then Exn.reraise exn
   191       in if continue then protocol_loop () else () end;
   197             else (Runtime.exn_system_message exn handle crash => recover crash);
       
   198       in protocol_loop () end;
   192 
   199 
   193     fun protocol () =
   200     fun protocol () =
   194      (Session.init_protocol_handlers ();
   201      (Session.init_protocol_handlers ();
   195       message Markup.initN [] [XML.Text (Session.welcome ())];
   202       message Markup.initN [] [XML.Text (Session.welcome ())];
   196       protocol_loop ());
   203       protocol_loop ());
   203     val _ = Future.shutdown ();
   210     val _ = Future.shutdown ();
   204     val _ = Execution.reset ();
   211     val _ = Execution.reset ();
   205     val _ = Message_Channel.shutdown msg_channel;
   212     val _ = Message_Channel.shutdown msg_channel;
   206     val _ = BinIO.closeIn in_stream;
   213     val _ = BinIO.closeIn in_stream;
   207     val _ = BinIO.closeOut out_stream;
   214     val _ = BinIO.closeOut out_stream;
       
   215 
   208   in
   216   in
   209     (case result of
   217     (case result of
   210       Exn.Exn (EXIT rc) => exit rc
   218       Exn.Exn STOP => ()
       
   219     | Exn.Exn (EXIT rc) => exit rc
   211     | _ => Exn.release result)
   220     | _ => Exn.release result)
   212   end);
   221   end);
   213 
   222 
   214 end;
   223 end;
   215 
   224