signal handling made more generic

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@290 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
stasinos 2002-01-11 15:54:17 +00:00
parent 2d51021df7
commit 6951619ae2
8 changed files with 69 additions and 64 deletions

View File

@ -874,7 +874,7 @@ InitCodes(void)
AtomArrow = LookupAtom("->"); AtomArrow = LookupAtom("->");
heap_regs->atom_assert = LookupAtom(":-"); heap_regs->atom_assert = LookupAtom(":-");
heap_regs->atom_alarm = LookupAtom("$alarm"); heap_regs->atom_alarm = LookupAtom("$alarm");
#if USE_SIGACTION #if HAVE_SIGACTION
heap_regs->atom_sig_pending = LookupAtom("$sig_pending"); heap_regs->atom_sig_pending = LookupAtom("$sig_pending");
#endif #endif
AtomBraces = LookupAtom("{}"); AtomBraces = LookupAtom("{}");

View File

@ -1050,7 +1050,7 @@ restore_codes(void)
heap_regs->atom_read = AtomAdjust(heap_regs->atom_read); heap_regs->atom_read = AtomAdjust(heap_regs->atom_read);
heap_regs->atom_repeat = AtomAdjust(heap_regs->atom_repeat); heap_regs->atom_repeat = AtomAdjust(heap_regs->atom_repeat);
heap_regs->atom_restore_regs = AtomAdjust(heap_regs->atom_restore_regs); heap_regs->atom_restore_regs = AtomAdjust(heap_regs->atom_restore_regs);
#if USE_SIGACTION #if HAVE_SIGACTION
heap_regs->atom_sig_pending = AtomAdjust(heap_regs->atom_sig_pending); heap_regs->atom_sig_pending = AtomAdjust(heap_regs->atom_sig_pending);
#endif #endif
heap_regs->atom_stack_free = AtomAdjust(heap_regs->atom_stack_free); heap_regs->atom_stack_free = AtomAdjust(heap_regs->atom_stack_free);

View File

@ -823,7 +823,6 @@ STATIC_PROTO (void InitSignals, (void));
STATIC_PROTO (void HandleSIGSEGV, (int, siginfo_t *, ucontext_t *)); STATIC_PROTO (void HandleSIGSEGV, (int, siginfo_t *, ucontext_t *));
STATIC_PROTO (void HandleMatherr, (int, siginfo_t *, ucontext_t *)); STATIC_PROTO (void HandleMatherr, (int, siginfo_t *, ucontext_t *));
STATIC_PROTO (void HandleSIGUSER, (int, siginfo_t *, ucontext_t *));
STATIC_PROTO (void my_signal_info, (int, void (*)(int, siginfo_t *, ucontext_t *))); STATIC_PROTO (void my_signal_info, (int, void (*)(int, siginfo_t *, ucontext_t *)));
STATIC_PROTO (void my_signal, (int, void (*)(int, siginfo_t *, ucontext_t *))); STATIC_PROTO (void my_signal, (int, void (*)(int, siginfo_t *, ucontext_t *)));
@ -906,7 +905,6 @@ my_signal(int sig, void (*handler)(int, siginfo_t *, ucontext_t *))
STATIC_PROTO (RETSIGTYPE HandleMatherr, (int)); STATIC_PROTO (RETSIGTYPE HandleMatherr, (int));
STATIC_PROTO (RETSIGTYPE HandleSIGSEGV, (int)); STATIC_PROTO (RETSIGTYPE HandleSIGSEGV, (int));
STATIC_PROTO (RETSIGTYPE HandleSIGUSER, (int));
STATIC_PROTO (void my_signal_info, (int, void (*)(int))); STATIC_PROTO (void my_signal_info, (int, void (*)(int)));
STATIC_PROTO (void my_signal, (int, void (*)(int))); STATIC_PROTO (void my_signal, (int, void (*)(int)));
@ -1011,7 +1009,7 @@ HandleSIGSEGV(int sig)
SearchForTrailFault(); SearchForTrailFault();
} }
#ifdef HAVE_SIGACTION #if HAVE_SIGACTION
static void static void
my_signal_info(int sig, void (*handler)(int)) my_signal_info(int sig, void (*handler)(int))
@ -1253,40 +1251,10 @@ HandleALRM(int s)
} }
#endif #endif
#if USE_SIGACTION
/* this routine is called if YAP received one of the signals that
can be handled by user code, currently SIGUSR1 and SIGUSR2 */
static RETSIGTYPE
#if (defined(__svr4__) || defined(__SVR4))
HandleSIGUSER (int s, siginfo_t *x, ucontext_t *y)
#else
HandleSIGUSER(int s)
#endif
{
/* force the system to creep */
p_creep ();
/* raise the '$sig_pending' flag */
/* NOTE: shouldn't this be a queue? */
switch (s) {
case SIGUSR1:
PutValue(AtomSigPending, MkAtomTerm(LookupAtom("sig_usr1")));
break;
case SIGUSR2:
PutValue(AtomSigPending, MkAtomTerm(LookupAtom("sig_usr2")));
break;
default:
/* should never be here, freak out and die! */
/* YapErrorWhatever(); */
;
}
}
#endif /* USE_SIGACTION */
/* /*
* This function is called after a normal interrupt had been caught It allows * This function is called after a normal interrupt had been caught.
* 6 possibilities : abort, continue, trace, debug, help, exit * It allows 6 possibilities: abort, continue, trace, debug, help, exit.
*/ */
#if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT) #if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT)
@ -1311,9 +1279,30 @@ ReceiveSignal (int s)
case SIGKILL: case SIGKILL:
exit_yap (SIGKILL, "\n\n\n[ Quit signal received ]\n\n"); exit_yap (SIGKILL, "\n\n\n[ Quit signal received ]\n\n");
#endif #endif
case SIGUSR1:
/* force the system to creep */
p_creep ();
/* raise the '$sig_pending' flag */
/* NOTE: shouldn't this be a queue? */
PutValue(AtomSigPending, MkAtomTerm(LookupAtom("sig_usr1")));
break;
case SIGUSR2:
/* force the system to creep */
p_creep ();
/* raise the '$sig_pending' flag */
/* NOTE: shouldn't this be a queue? */
PutValue(AtomSigPending, MkAtomTerm(LookupAtom("sig_usr2")));
break;
case SIGHUP:
/* force the system to creep */
p_creep ();
/* raise the '$sig_pending' flag */
/* NOTE: shouldn't this be a queue? */
PutValue(AtomSigPending, MkAtomTerm(LookupAtom("sig_hup")));
break;
default: default:
YP_fprintf(YP_stderr, "\n[ Unexpected signal ]\n"); YP_fprintf(YP_stderr, "\n[ Unexpected signal ]\n");
exit (FALSE); exit (EXIT_FAILURE);
} }
} }
#endif #endif
@ -1340,6 +1329,9 @@ InitSignals (void)
#if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT) #if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT)
my_signal (SIGQUIT, ReceiveSignal); my_signal (SIGQUIT, ReceiveSignal);
my_signal (SIGKILL, ReceiveSignal); my_signal (SIGKILL, ReceiveSignal);
my_signal (SIGUSR1, ReceiveSignal);
my_signal (SIGUSR2, ReceiveSignal);
my_signal (SIGHUP, ReceiveSignal);
my_signal (SIGALRM, HandleALRM); my_signal (SIGALRM, HandleALRM);
#endif #endif
#if _MSC_VER || defined(__MINGW32__) #if _MSC_VER || defined(__MINGW32__)
@ -1348,10 +1340,6 @@ InitSignals (void)
#else #else
my_signal (SIGINT, HandleSIGINT); my_signal (SIGINT, HandleSIGINT);
#endif #endif
#if USE_SIGACTION
my_signal (SIGUSR1, HandleSIGUSER);
my_signal (SIGUSR2, HandleSIGUSER);
#endif
#ifndef MPW #ifndef MPW
my_signal (SIGFPE, HandleMatherr); my_signal (SIGFPE, HandleMatherr);
#endif #endif

View File

@ -10,7 +10,7 @@
* File: Heap.h * * File: Heap.h *
* mods: * * mods: *
* comments: Heap Init Structure * * comments: Heap Init Structure *
* version: $Id: Heap.h,v 1.18 2002-01-09 17:19:36 stasinos Exp $ * * version: $Id: Heap.h,v 1.19 2002-01-11 15:54:17 stasinos Exp $ *
*************************************************************************/ *************************************************************************/
/* information that can be stored in Code Space */ /* information that can be stored in Code Space */
@ -196,7 +196,7 @@ typedef struct various_codes {
atom_read, atom_read,
atom_repeat, atom_repeat,
atom_restore_regs, atom_restore_regs,
#if USE_SIGACTION #if HAVE_SIGACTION
atom_sig_pending, atom_sig_pending,
#endif #endif
atom_stack_free, atom_stack_free,

View File

@ -201,8 +201,3 @@
/* Is fflush(NULL) clobbering input streams? */ /* Is fflush(NULL) clobbering input streams? */
#undef BROKEN_FFLUSH_NULL #undef BROKEN_FFLUSH_NULL
/* Should we do signal handling? */
#if HAVE_SIGNAL_H && HAVE_SIGACTION
#define USE_SIGACTION 1
#endif

View File

@ -32,6 +32,12 @@ true :- true. % otherwise, $$compile will ignore this clause.
), ),
'$system_catch'('$enter_top_level',Module,Error,user:'$Error'(Error)). '$system_catch'('$enter_top_level',Module,Error,user:'$Error'(Error)).
read_sig :-
recorded('$sig_handler',X,_),
writeq(X),nl,
fail.
read_sig.
'$init_system' :- '$init_system' :-
( (
@ -40,6 +46,27 @@ true :- true. % otherwise, $$compile will ignore this clause.
; ;
true true
), ),
% If this is not here, the following get written twice in the idb. Why?
eraseall('$sig_handler'),
% The default interrupt handlers are kept, so that it's
% possible to revert to them with on_signal(S,_,default)
'$recordz'('$sig_handler',default(sig_hup,
(( exists('~/.yaprc') -> [-'~/.yaprc'] ; true ),
( exists('~/.prologrc') -> [-'~/.prologrc'] ; true ),
( exists('~/prolog.ini') -> [-'~/prolog.ini'] ; true ))), _),
'$recordz'('$sig_handler',default(sig_usr1,
(nl,writeq('[ Received user signal 1 ]'),nl,halt)), _),
'$recordz'('$sig_handler',default(sig_usr2,
(nl,writeq('[ Received user signal 2 ]'),nl,halt)), _),
% The current interrupt handlers are also set the default values
'$recordz'('$sig_handler',action(sig_hup,
(( exists('~/.yaprc') -> [-'~/.yaprc'] ; true ),
( exists('~/.prologrc') -> [-'~/.prologrc'] ; true ),
( exists('~/prolog.ini') -> [-'~/prolog.ini'] ; true ))), _),
'$recordz'('$sig_handler',action(sig_usr1,
(nl,writeq('[ Received user signal 1 ]'),nl,halt)), _),
'$recordz'('$sig_handler',action(sig_usr2,
(nl,writeq('[ Received user signal 2 ]'),nl,halt)), _),
'$set_yap_flags'(10,0), '$set_yap_flags'(10,0),
'$set_value'('$gc',on), '$set_value'('$gc',on),
'$init_catch', '$init_catch',
@ -67,6 +94,7 @@ true :- true. % otherwise, $$compile will ignore this clause.
true true
). ).
% %
% encapsulate $cut_by because of co-routining. % encapsulate $cut_by because of co-routining.
% %
@ -94,17 +122,6 @@ true :- true. % otherwise, $$compile will ignore this clause.
'$enter_top_level' :- '$enter_top_level' :-
'$alarm'(0, _), '$alarm'(0, _),
fail. fail.
% set the default user signal handlers
'$enter_top_level' :-
( '$recorded'('$sig_handler',_,_) ->
true
;
'$recordz'('$sig_handler',
action(sig_usr1,(format('Received user signal 1~n',[]),halt)), _),
'$recordz'('$sig_handler',
action(sig_usr2,(format('Received user signal 2~n',[]),halt)), _)
),
fail.
'$enter_top_level' :- '$enter_top_level' :-
'$clean_up_dead_clauses', '$clean_up_dead_clauses',
fail. fail.

View File

@ -720,8 +720,10 @@ debugging :-
), ),
'$execute'(M:Goal). '$execute'(M:Goal).
'$creep'(G) :- '$creep'(G) :-
format( 'creeping...~n', [] ),
'$get_value'('$sig_pending', Signal), '$get_value'('$sig_pending', Signal),
\+ Signal = [], !, format( 'Signal == ~q~n', [Signal] ),
Signal \== [], !,
'$set_value'('$sig_pending', []), '$set_value'('$sig_pending', []),
( '$recorded'('$sig_handler', action(Signal,A),_) -> ( '$recorded'('$sig_handler', action(Signal,A),_) ->
'$execute'(A), '$execute'(A),

View File

@ -231,11 +231,14 @@ alarm(Interval, Goal, Left) :-
'$recordz'('$alarm_handler',M:Goal,_), '$recordz'('$alarm_handler',M:Goal,_),
'$alarm'(Interval, Left). '$alarm'(Interval, Left).
on_signal(Signal,OldAction,default) :-
recorded('$sig_handler', default(Signal,Action), Ref),
on_signal(Signal,OldAction,Action).
on_signal(Signal,OldAction,Action) :- on_signal(Signal,OldAction,Action) :-
recorded('$sig_handler', action(Signal,OldAction), Ref), recorded('$sig_handler', action(Signal,OldAction), Ref),
erase(Ref), erase(Ref),
'$current_module'(M), '$current_module'(M),
'$recordz'('$sig_handler', action(Signal,M:Action),Ref2). '$recordz'('$sig_handler', action(Signal,M:Action), _).
%%% Saving and restoring a computation %%% Saving and restoring a computation