2004-01-23 02:23:51 +00:00
|
|
|
/*************************************************************************
|
|
|
|
* *
|
|
|
|
* YAP Prolog *
|
|
|
|
* *
|
|
|
|
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
|
|
|
* *
|
|
|
|
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
|
|
|
|
* *
|
|
|
|
**************************************************************************
|
|
|
|
* *
|
|
|
|
* File: signals.pl *
|
|
|
|
* Last rev: *
|
|
|
|
* mods: *
|
|
|
|
* comments: signal handling in YAP *
|
|
|
|
* *
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
:- meta_predicate on_signal(+,?,:), alarm(+,:,-).
|
|
|
|
|
|
|
|
'$creep'(G) :-
|
|
|
|
% get the first signal from the mask
|
|
|
|
'$first_signal'(Sig), !,
|
|
|
|
% process it
|
|
|
|
'$do_signal'(Sig, G).
|
|
|
|
'$creep'([M|G]) :-
|
|
|
|
% noise, just go on with our life.
|
|
|
|
'$execute'(M:G).
|
|
|
|
|
|
|
|
'$do_signal'(sig_wake_up, G) :-
|
2004-06-05 04:37:01 +01:00
|
|
|
'$awoken_goals'(LG),
|
2004-01-23 02:23:51 +00:00
|
|
|
% if more signals alive, set creep flag
|
|
|
|
'$continue_signals',
|
|
|
|
'$wake_up_goal'(G, LG).
|
2005-02-08 04:05:39 +00:00
|
|
|
'$do_signal'(sig_creep, [M|G]) :-
|
2006-12-13 16:10:26 +00:00
|
|
|
'$start_creep'([M|G]).
|
2004-12-05 05:01:45 +00:00
|
|
|
'$do_signal'(sig_delay_creep, [M|G]) :-
|
|
|
|
'$execute'(M:G),
|
|
|
|
'$creep'.
|
2006-03-24 16:26:31 +00:00
|
|
|
'$do_signal'(sig_iti, [M|G]) :-
|
2004-02-05 16:57:02 +00:00
|
|
|
'$thread_gfetch'(Goal),
|
|
|
|
% if more signals alive, set creep flag
|
|
|
|
'$continue_signals',
|
|
|
|
'$current_module'(M0),
|
2006-03-24 16:26:31 +00:00
|
|
|
'$execute0'(Goal,M0),
|
|
|
|
'$execute'(M:G).
|
2005-11-09 18:02:53 +00:00
|
|
|
'$do_signal'(sig_trace, [M|G]) :-
|
2004-10-08 18:20:03 +01:00
|
|
|
'$continue_signals',
|
2005-11-09 18:02:53 +00:00
|
|
|
trace,
|
|
|
|
'$execute'(M:G).
|
|
|
|
'$do_signal'(sig_debug, [M|G]) :-
|
2004-10-08 18:20:03 +01:00
|
|
|
'$continue_signals',
|
|
|
|
debug,
|
2005-11-09 18:02:53 +00:00
|
|
|
'$execute'(M:G).
|
|
|
|
'$do_signal'(sig_break, [M|G]) :-
|
2004-10-08 18:20:03 +01:00
|
|
|
'$continue_signals',
|
|
|
|
break,
|
2005-11-09 18:02:53 +00:00
|
|
|
'$execute0'(G,M).
|
|
|
|
'$do_signal'(sig_statistics, [M|G]) :-
|
2004-10-08 18:20:03 +01:00
|
|
|
'$continue_signals',
|
|
|
|
statistics,
|
2005-11-09 18:02:53 +00:00
|
|
|
'$execute0'(G,M).
|
|
|
|
'$do_signal'(sig_stack_dump, [M|G]) :-
|
2004-10-08 18:20:03 +01:00
|
|
|
'$continue_signals',
|
|
|
|
'$stack_dump',
|
2005-11-09 18:02:53 +00:00
|
|
|
'$execute0'(G,M).
|
2004-01-23 02:23:51 +00:00
|
|
|
% Unix signals
|
|
|
|
'$do_signal'(sig_alarm, G) :-
|
|
|
|
'$signal_handler'(sig_alarm, G).
|
|
|
|
'$do_signal'(sig_hup, G) :-
|
|
|
|
'$signal_handler'(sig_hup, G).
|
|
|
|
'$do_signal'(sig_usr1, G) :-
|
|
|
|
'$signal_handler'(sig_usr1, G).
|
|
|
|
'$do_signal'(sig_usr2, G) :-
|
|
|
|
'$signal_handler'(sig_usr2, G).
|
|
|
|
|
|
|
|
'$signal_handler'(Sig, [M|G]) :-
|
|
|
|
'$signal_do'(Sig, Goal),
|
|
|
|
% if more signals alive, set creep flag
|
|
|
|
'$continue_signals',
|
|
|
|
'$current_module'(M0),
|
|
|
|
'$execute0'((Goal,M:G),M0).
|
|
|
|
|
2006-12-13 16:10:26 +00:00
|
|
|
% do not debug if we are not in debug mode.
|
|
|
|
'$start_creep'([Mod|G]) :-
|
|
|
|
nb_getval('$debug',off), !,
|
|
|
|
'$execute_nonstop'(G,Mod).
|
|
|
|
'$start_creep'([Mod|G]) :-
|
|
|
|
nb_getval('$system_mode',on), !,
|
|
|
|
'$execute_nonstop'(G,Mod).
|
2004-01-23 02:23:51 +00:00
|
|
|
% notice that the last signal to be processed must always be creep
|
|
|
|
'$start_creep'([_|'$cut_by'(CP)]) :- !,
|
2006-12-30 03:25:47 +00:00
|
|
|
'$$cut_by'(CP),
|
2004-01-23 02:23:51 +00:00
|
|
|
'$creep'.
|
|
|
|
'$start_creep'([_|true]) :- !,
|
|
|
|
'$creep'.
|
|
|
|
'$start_creep'([Mod|G]) :-
|
|
|
|
'$hidden_predicate'(G,Mod), !,
|
|
|
|
'$creep',
|
2004-05-13 21:54:58 +01:00
|
|
|
'$execute_nonstop'(G,Mod).
|
2004-01-23 02:23:51 +00:00
|
|
|
'$start_creep'([Mod|G]) :-
|
2006-12-13 16:10:26 +00:00
|
|
|
'$system_predicate'(G, Mod),
|
|
|
|
'$protected_env', !,
|
|
|
|
'$creep',
|
|
|
|
'$execute_nonstop'(G,Mod).
|
|
|
|
% do not debug if we are zipping through.
|
|
|
|
'$start_creep'([Mod|G]) :-
|
|
|
|
nb_getval('$debug_zip',on),
|
|
|
|
'$zip'(-1, G, Mod), !,
|
|
|
|
'$creep',
|
|
|
|
'$execute_nonstop'(G,Mod).
|
|
|
|
'$start_creep'([Mod|G]) :-
|
2004-01-23 02:23:51 +00:00
|
|
|
CP is '$last_choice_pt',
|
2004-07-15 16:47:08 +01:00
|
|
|
'$do_spy'(G, Mod, CP, yes).
|
2004-01-23 02:23:51 +00:00
|
|
|
|
|
|
|
'$signal_do'(Sig, Goal) :-
|
|
|
|
recorded('$signal_handler', action(Sig,Goal), _), !.
|
|
|
|
'$signal_do'(Sig, Goal) :-
|
|
|
|
'$signal_def'(Sig, Goal).
|
|
|
|
|
|
|
|
% reconsult init files.
|
|
|
|
'$signal_def'(sig_hup, (( exists('~/.yaprc') -> [-'~/.yaprc'] ; true ),
|
|
|
|
( exists('~/.prologrc') -> [-'~/.prologrc'] ; true ),
|
|
|
|
( exists('~/prolog.ini') -> [-'~/prolog.ini'] ; true ))).
|
|
|
|
% die on signal default.
|
|
|
|
'$signal_def'(sig_usr1, (print_message(error, 'Received user signal 1'),halt)).
|
|
|
|
'$signal_def'(sig_usr2, (print_message(error, 'Received user signal 2'),halt)).
|
|
|
|
% ignore sig_alarm by default
|
|
|
|
'$signal_def'(sig_alarm, true).
|
|
|
|
|
|
|
|
|
|
|
|
on_signal(Signal,OldAction,default) :-
|
|
|
|
'$reset_signal'(Signal, OldAction).
|
|
|
|
on_signal(Signal,OldAction,Action) :-
|
2004-05-13 21:54:58 +01:00
|
|
|
var(Action), !,
|
2006-03-24 16:26:31 +00:00
|
|
|
'$check_signal'(Signal, OldAction),
|
2004-01-23 02:23:51 +00:00
|
|
|
Action = OldAction.
|
|
|
|
on_signal(Signal,OldAction,Action) :-
|
|
|
|
'$reset_signal'(Signal, OldAction),
|
|
|
|
'$current_module'(M),
|
2005-01-07 06:29:20 +00:00
|
|
|
recordz('$signal_handler', action(Signal,M:Action), _).
|
2004-01-23 02:23:51 +00:00
|
|
|
|
|
|
|
'$reset_signal'(Signal, OldAction) :-
|
2005-01-07 06:29:20 +00:00
|
|
|
recorded('$signal_handler', action(Signal,OldAction), Ref), !,
|
2004-01-23 02:23:51 +00:00
|
|
|
erase(Ref).
|
|
|
|
'$reset_signal'(_, default).
|
|
|
|
|
|
|
|
'$check_signal'(Signal, OldAction) :-
|
2005-01-07 06:29:20 +00:00
|
|
|
recorded('$signal_handler', action(Signal,OldAction), _), !.
|
2006-03-24 16:26:31 +00:00
|
|
|
'$check_signal'(_, default).
|
2004-01-23 02:23:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
alarm(Interval, Goal, Left) :-
|
|
|
|
on_signal(sig_alarm, _, Goal),
|
|
|
|
'$alarm'(Interval, Left).
|
|
|
|
|
|
|
|
raise_exception(Ball) :- throw(Ball).
|
|
|
|
|
|
|
|
on_exception(Pat, G, H) :- catch(G, Pat, H).
|
|
|
|
|
2004-12-08 04:45:04 +00:00
|
|
|
read_sig :-
|
2005-01-07 06:29:20 +00:00
|
|
|
recorded('$signal_handler',X,_),
|
2004-12-08 04:45:04 +00:00
|
|
|
writeq(X),nl,
|
|
|
|
fail.
|
|
|
|
read_sig.
|
|
|
|
|
|
|
|
|
2006-12-13 16:10:26 +00:00
|
|
|
'$protected_env' :-
|
|
|
|
'$all_envs'(Envs),
|
|
|
|
%'$envs'(Envs),
|
|
|
|
'$skim_envs'(Envs,Mod,Name,Arity),
|
|
|
|
\+ '$external_call_seen'(Mod,Name,Arity).
|
|
|
|
|
|
|
|
|
|
|
|
% '$envs'([Env|Envs]) :-
|
|
|
|
% '$env_info'(Env,Mod0,Name0,Arity0),
|
|
|
|
% format(user_error,'~a:~w/~w~n',[Mod0,Name0,Arity0]),
|
|
|
|
% '$envs'(Envs).
|
|
|
|
% '$envs'([]).
|
|
|
|
|
|
|
|
|
|
|
|
'$skim_envs'([Env|Envs],Mod,Name,Arity) :-
|
|
|
|
'$env_info'(Env,Mod0,Name0,Arity0),
|
|
|
|
'$debugger_env'(Mod0,Name0,Arity0), !,
|
|
|
|
'$skim_envs'(Envs,Mod,Name,Arity).
|
|
|
|
'$skim_envs'([Env|Envs],Mod,Name,Arity) :-
|
|
|
|
'$env_info'(Env,Mod,Name,Arity).
|
|
|
|
|
|
|
|
'$debugger_env'(prolog,'$start_creep',1).
|
|
|
|
|
|
|
|
'$external_call_seen'(prolog,Name,Arity) :- !,
|
|
|
|
'$allowed'(Name,Arity).
|
|
|
|
'$external_call_seen'(_,_,_).
|
|
|
|
|
|
|
|
'$allowed'('$spycall',3).
|
|
|
|
'$allowed'('$query',2).
|
|
|
|
|