src/Pure/Tools/debugger.ML
changeset 60888 35d85fd89fc1
parent 60887 9d8b244234ab
child 60889 7f210887cc4e
equal deleted inserted replaced
60887:9d8b244234ab 60888:35d85fd89fc1
    35   handle exn =>
    35   handle exn =>
    36     if Exn.is_interrupt exn then reraise exn
    36     if Exn.is_interrupt exn then reraise exn
    37     else error_message (Runtime.exn_message exn);
    37     else error_message (Runtime.exn_message exn);
    38 
    38 
    39 
    39 
    40 (* thread names and input *)
    40 (* thread input *)
    41 
    41 
    42 datatype state =
    42 val thread_input =
    43   State of {
    43   Synchronized.var "Debugger.state" (Symtab.empty: string list Queue.T Symtab.table);
    44     threads: Thread.thread Symtab.table,  (*thread name ~> thread*)
       
    45     input: string list Queue.T Symtab.table  (*thread name ~> input queue*)
       
    46   };
       
    47 
       
    48 fun make_state (threads, input) = State {threads = threads, input = input};
       
    49 val init_state = make_state (Symtab.empty, Symtab.empty);
       
    50 fun map_state f (State {threads, input}) = make_state (f (threads, input));
       
    51 
       
    52 val global_state = Synchronized.var "Debugger.state" init_state;
       
    53 
       
    54 fun cancel thread_name =
       
    55   Synchronized.change global_state (tap (fn State {threads, ...} =>
       
    56     (case Symtab.lookup threads thread_name of
       
    57       NONE => ()
       
    58     | SOME thread => Simple_Thread.interrupt_unsynchronized thread)));
       
    59 
    44 
    60 fun input thread_name msg =
    45 fun input thread_name msg =
    61   Synchronized.change global_state (map_state (fn (threads, input) =>
    46   Synchronized.change thread_input
    62     let val input' = Symtab.map_default (thread_name, Queue.empty) (Queue.enqueue msg) input;
    47     (Symtab.map_default (thread_name, Queue.empty) (Queue.enqueue msg));
    63     in (threads, input') end));
       
    64 
       
    65 fun register_thread thread_name =
       
    66   Synchronized.change global_state (map_state (fn (threads, input) =>
       
    67     let
       
    68       val threads' = Symtab.update_new (thread_name, Thread.self ()) threads
       
    69         handle Symtab.DUP _ => threads;
       
    70     in (threads', input) end));
       
    71 
    48 
    72 fun get_input thread_name =
    49 fun get_input thread_name =
    73   Synchronized.guarded_access global_state (fn State {threads, input} =>
    50   Synchronized.guarded_access thread_input (fn input =>
    74     (case Symtab.lookup input thread_name of
    51     (case Symtab.lookup input thread_name of
    75       NONE => NONE
    52       NONE => NONE
    76     | SOME queue =>
    53     | SOME queue =>
    77         let
    54         let
    78           val (msg, queue') = Queue.dequeue queue;
    55           val (msg, queue') = Queue.dequeue queue;
    79           val input' =
    56           val input' =
    80             if Queue.is_empty queue' then Symtab.delete_safe thread_name input
    57             if Queue.is_empty queue' then Symtab.delete_safe thread_name input
    81             else Symtab.update (thread_name, queue') input;
    58             else Symtab.update (thread_name, queue') input;
    82         in SOME (msg, make_state (threads, input')) end));
    59         in SOME (msg, input') end));
    83 
    60 
    84 
    61 
    85 
    62 
    86 (** thread state **)
    63 (** thread state **)
    87 
    64 
   224     (SOME (fn (_, break) =>
   201     (SOME (fn (_, break) =>
   225       if not (is_debugging ()) andalso (! break orelse is_stepping ()) andalso
   202       if not (is_debugging ()) andalso (! break orelse is_stepping ()) andalso
   226         Options.default_bool @{system_option ML_debugger_active}
   203         Options.default_bool @{system_option ML_debugger_active}
   227       then
   204       then
   228         (case Simple_Thread.get_name () of
   205         (case Simple_Thread.get_name () of
   229           SOME thread_name => (register_thread thread_name; debugger_loop thread_name)
   206           SOME thread_name => debugger_loop thread_name
   230         | NONE => ())
   207         | NONE => ())
   231       else ()));
   208       else ()));
   232 
   209 
   233 end;
   210 end;
   234 
   211 
   265             else err ()
   242             else err ()
   266         | NONE => err ())
   243         | NONE => err ())
   267       end);
   244       end);
   268 
   245 
   269 val _ =
   246 val _ =
   270   Isabelle_Process.protocol_command "Debugger.cancel"
       
   271     (fn [thread_name] => cancel thread_name);
       
   272 
       
   273 val _ =
       
   274   Isabelle_Process.protocol_command "Debugger.input"
   247   Isabelle_Process.protocol_command "Debugger.input"
   275     (fn thread_name :: msg => input thread_name msg);
   248     (fn thread_name :: msg => input thread_name msg);
   276 
   249 
   277 end;
   250 end;