Merge pull request #1243 from urbit/ccr-signal-reform

cc-release: cleanup of signal handling
This commit is contained in:
Joe Bryan 2019-04-24 12:52:26 -07:00 committed by GitHub
commit 62e7c8272b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 160 additions and 170 deletions

View File

@ -438,82 +438,6 @@ u3_ve_sysopt()
u3_Local = strdup(u3_Host.dir_c);
}
#if 0
static jmp_buf Signal_buf;
#ifndef SIGSTKSZ
# define SIGSTKSZ 16384
#endif
static uint8_t Sigstk[SIGSTKSZ];
volatile enum { sig_none, sig_overflow, sig_interrupt } Sigcause;
static void _main_cont(void *arg1, void *arg2, void *arg3)
{
(void)(arg1);
(void)(arg2);
(void)(arg3);
siglongjmp(Signal_buf, 1);
}
static void
overflow_handler(int emergency, stackoverflow_context_t scp)
{
if ( 1 == emergency ) {
write(2, "stack emergency\n", strlen("stack emergency" + 2));
exit(1);
} else {
Sigcause = sig_overflow;
sigsegv_leave_handler(_main_cont, NULL, NULL, NULL);
}
}
// Install signal handlers and set buffers.
//
// Note that we use the sigmask-restoring variant. Essentially, when
// we get a signal, we force the system back into the just-booted state.
// If anything goes wrong during boot (above), it's curtains.
{
if ( 0 != sigsetjmp(Signal_buf, 1) ) {
switch ( Sigcause ) {
case sig_overflow: printf("[stack overflow]\r\n"); break;
case sig_interrupt: printf("[interrupt]\r\n"); break;
default: printf("[signal error!]\r\n"); break;
}
Sigcause = sig_none;
signal(SIGINT, SIG_DFL);
stackoverflow_deinstall_handler();
// Print the trace, do a GC, etc.
//
// This is half-assed at present, so we exit.
//
u3_lo_sway(0, u3k(u3_wire_tax(u3_Wire)));
u3_pier_exit(u3A);
exit(1);
}
if ( -1 == stackoverflow_install_handler
(overflow_handler, Sigstk, SIGSTKSZ) )
{
fprintf(stderr, "overflow_handler: install failed\n");
exit(1);
}
signal(SIGINT, interrupt_handler);
signal(SIGIO, SIG_IGN);
}
static void
interrupt_handler(int x)
{
Sigcause = sig_interrupt;
longjmp(Signal_buf, 1);
}
#endif
#define GRAB
static void
report(void)
{
@ -531,13 +455,13 @@ report(void)
H2O_LIBRARY_VERSION_PATCH);
}
void
static void
_stop_exit(c3_i int_i)
{
u3l_log("\r\n[received keyboard stop signal, exiting]\r\n");
// XX crashes if we haven't started a pier yet
// explicit fprintf to avoid allocation in u3l_log
//
u3_pier_exit(u3_pier_stub());
fprintf(stderr, "\r\n[received keyboard stop signal, exiting]\r\n");
u3_daemon_bail();
}
/*
@ -669,7 +593,9 @@ main(c3_i argc,
#endif
u3_ve_sysopt();
// Block profiling signal, which should be delievered to exactly one thread.
// Block profiling signal, which should be delivered to exactly one thread.
//
// XX review, may be unnecessary due to similar in u3m_init()
//
if ( _(u3_Host.ops_u.pro) ) {
sigset_t set;
@ -684,6 +610,8 @@ main(c3_i argc,
// Handle SIGTSTP as if it was SIGTERM.
//
// Configured here using signal() so as to be immediately available.
//
signal(SIGTSTP, _stop_exit);
printf("~\n");

View File

@ -12,6 +12,8 @@
c3_w wag_w; // flags (both ways)
void (*stderr_log_f)(c3_c*); // errors from c code
void (*slog_f)(u3_noun); // function pointer for slog
void (*sign_hold_f)(void); // suspend system signal regime
void (*sign_move_f)(void); // restore system signal regime
} u3o_config;
/* u3o_flag: process/system flags.

View File

@ -1260,7 +1260,7 @@
void
u3_pier_exit(u3_pier* pir_u);
/* u3_pier_bail(): clean up all event state.
/* u3_pier_bail(): immediately shutdown..
*/
void
u3_pier_bail(void);
@ -1334,6 +1334,11 @@
void
u3_daemon_commence();
/* u3_daemon_bail(): immediately shutdown.
*/
void
u3_daemon_bail(void);
/* u3_king_grab(): gc the daemon area
*/
void

View File

@ -41,7 +41,7 @@
void
u3m_leap(c3_w pad_w);
/* u3m_golf(): record cap length for u3_flog().
/* u3m_golf(): record cap length for u3m_flog().
*/
c3_w
u3m_golf(void);
@ -80,9 +80,6 @@ static sigjmp_buf u3_Signal;
static uint8_t Sigstk[SIGSTKSZ];
#endif
void u3_unix_ef_hold(void); // suspend system signal regime
void u3_unix_ef_move(void); // restore system signal regime
#if 0
/* _cm_punt(): crudely print trace.
*/
@ -319,7 +316,11 @@ _cm_signal_recover(c3_l sig_l, u3_noun arg)
static void
_cm_signal_deep(c3_w sec_w)
{
u3_unix_ef_hold();
// disable outer system signal handling
//
if ( 0 != u3C.sign_hold_f ) {
u3C.sign_hold_f();
}
#ifndef NO_OVERFLOW
stackoverflow_install_handler(_cm_signal_handle_over, Sigstk, SIGSTKSZ);
@ -353,7 +354,7 @@ _cm_signal_deep(c3_w sec_w)
static void
_cm_signal_done()
{
// signal(SIGINT, SIG_IGN);
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
signal(SIGVTALRM, SIG_IGN);
@ -366,7 +367,13 @@ _cm_signal_done()
setitimer(ITIMER_VIRTUAL, &itm_u, 0);
}
u3_unix_ef_move();
// restore outer system signal handling
//
if ( 0 != u3C.sign_move_f ) {
u3C.sign_move_f();
}
u3t_boff();
}
@ -834,7 +841,7 @@ u3m_love(u3_noun pro)
return pro;
}
/* u3m_golf(): record cap_p length for u3_flog().
/* u3m_golf(): record cap_p length for u3m_flog().
*/
c3_w
u3m_golf(void)
@ -1877,6 +1884,8 @@ u3m_boot_new(c3_c* dir_c)
/* Activate tracing.
*/
u3C.slog_f = 0;
u3C.sign_hold_f = 0;
u3C.sign_move_f = 0;
u3t_init();
/* Construct or activate the allocator.
@ -1921,6 +1930,8 @@ u3m_boot_pier(void)
/* Activate tracing.
*/
u3C.slog_f = 0;
u3C.sign_hold_f = 0;
u3C.sign_move_f = 0;
u3t_init();
/* Construct or activate the allocator.

View File

@ -401,7 +401,7 @@ _cv_mole(u3_noun fot,
if ( (c3n == u3r_qual(uco, &p_uco, &q_uco, &r_uco, &s_uco)) ||
(0 != p_uco) ||
(0 != q_uco) ||
(c3n == u3_sing(fot, r_uco)) )
(c3n == u3r_sing(fot, r_uco)) )
{
u3l_log("strange mole %s\n", u3r_string(san)));

View File

@ -674,6 +674,104 @@ _boothack_doom(void)
return u3nq(c3__boot, bot, _boothack_pill(), pax);
}
/* _daemon_sign_init(): initialize daemon signal handlers
*/
static void
_daemon_sign_init(void)
{
// gracefully shutdown on SIGTERM
//
{
u3_usig* sig_u;
sig_u = c3_malloc(sizeof(u3_usig));
uv_signal_init(u3L, &sig_u->sil_u);
sig_u->num_i = SIGTERM;
sig_u->nex_u = u3_Host.sig_u;
u3_Host.sig_u = sig_u;
}
// forward SIGINT to worker
//
{
u3_usig* sig_u;
sig_u = c3_malloc(sizeof(u3_usig));
uv_signal_init(u3L, &sig_u->sil_u);
sig_u->num_i = SIGINT;
sig_u->nex_u = u3_Host.sig_u;
u3_Host.sig_u = sig_u;
}
// inject new dimensions after terminal resize
//
{
u3_usig* sig_u;
sig_u = c3_malloc(sizeof(u3_usig));
uv_signal_init(u3L, &sig_u->sil_u);
sig_u->num_i = SIGWINCH;
sig_u->nex_u = u3_Host.sig_u;
u3_Host.sig_u = sig_u;
}
}
/* _daemon_sign_cb: signal callback.
*/
static void
_daemon_sign_cb(uv_signal_t* sil_u, c3_i num_i)
{
switch ( num_i ) {
default: {
u3l_log("\r\nmysterious signal %d\r\n", num_i);
break;
}
case SIGTERM: {
u3_pier_exit(u3_pier_stub());
break;
}
case SIGINT: {
u3l_log("\r\ninterrupt\r\n");
u3_term_ef_ctlc();
break;
}
case SIGWINCH: {
u3_term_ef_winc();
break;
}
}
}
/* _daemon_sign_move(): enable daemon signal handlers
*/
static void
_daemon_sign_move(void)
{
u3_usig* sig_u;
for ( sig_u = u3_Host.sig_u; sig_u; sig_u = sig_u->nex_u ) {
uv_signal_start(&sig_u->sil_u, _daemon_sign_cb, sig_u->num_i);
}
}
/* _daemon_sign_hold(): disable daemon signal handlers
*/
static void
_daemon_sign_hold(void)
{
u3_usig* sig_u;
for ( sig_u = u3_Host.sig_u; sig_u; sig_u = sig_u->nex_u ) {
uv_signal_stop(&sig_u->sil_u);
}
}
/* _boothack_cb(): callback for the boothack self-connection
** (as if we were a client process)
*/
@ -693,37 +791,8 @@ _boothack_cb(uv_connect_t *conn, int status)
void
_daemon_loop_init()
{
/* move signals out of unix.c */
{
u3_usig* sig_u;
sig_u = c3_malloc(sizeof(u3_usig));
uv_signal_init(u3L, &sig_u->sil_u);
sig_u->num_i = SIGTERM;
sig_u->nex_u = u3_Host.sig_u;
u3_Host.sig_u = sig_u;
}
{
u3_usig* sig_u;
sig_u = c3_malloc(sizeof(u3_usig));
uv_signal_init(u3L, &sig_u->sil_u);
sig_u->num_i = SIGINT;
sig_u->nex_u = u3_Host.sig_u;
u3_Host.sig_u = sig_u;
}
{
u3_usig* sig_u;
sig_u = c3_malloc(sizeof(u3_usig));
uv_signal_init(u3L, &sig_u->sil_u);
sig_u->num_i = SIGWINCH;
sig_u->nex_u = u3_Host.sig_u;
u3_Host.sig_u = sig_u;
}
_daemon_sign_init();
_daemon_sign_move();
/* boot hack */
{
@ -757,6 +826,14 @@ u3_daemon_commence()
u3C.wag_w |= u3o_hashless;
u3m_boot_pier();
// wire up signal controls
//
u3C.sign_hold_f = _daemon_sign_hold;
u3C.sign_move_f = _daemon_sign_move;
// boot the ivory pill
//
{
u3_noun lit;
@ -796,6 +873,16 @@ u3_daemon_commence()
exit(0);
}
/* u3_daemon_bail(): immediately shutdown.
*/
void
u3_daemon_bail(void)
{
_daemon_loop_exit();
u3_pier_bail();
exit(1);
}
/* u3_daemon_grab(): gc the daemon area
*/
void

View File

@ -1985,14 +1985,16 @@ c3_rand(c3_w* rad_w)
}
}
/* u3_pier_bail(): clean up all event state.
/* u3_pier_bail(): immediately shutdown.
*/
void
u3_pier_bail(void)
{
fflush(stdout);
u3_pier_exit(u3_pier_stub());
if ( 0 != u3K.len_w ) {
_pier_exit_done(u3_pier_stub());
}
fflush(stdout);
exit(1);
}

View File

@ -1001,26 +1001,6 @@ u3_unix_initial_into_card(c3_c* arv_c)
u3nq(c3__into, u3_nul, c3y, can));
}
/* _unix_sign_cb: signal callback.
*/
static void
_unix_sign_cb(uv_signal_t* sil_u, c3_i num_i)
{
{
switch ( num_i ) {
default: u3l_log("\r\nmysterious signal %d\r\n", num_i); break;
case SIGTERM:
u3_pier_exit(u3_pier_stub());
break;
case SIGINT:
u3l_log("\r\ninterrupt\r\n");
u3_term_ef_ctlc();
break;
case SIGWINCH: u3_term_ef_winc(); break;
}
}
}
/* _unix_sync_file(): sync file to unix
*/
static void
@ -1291,18 +1271,6 @@ u3_unix_release(c3_c* pax_c)
free(paf_c);
}
/* u3_unix_ef_hold()
*/
void
u3_unix_ef_hold(void)
{
u3_usig* sig_u;
for ( sig_u = u3_Host.sig_u; sig_u; sig_u = sig_u->nex_u ) {
uv_signal_stop(&sig_u->sil_u);
}
}
/* u3_unix_ef_bake(): initial effects for new process.
*/
void
@ -1313,18 +1281,6 @@ u3_unix_ef_bake(u3_pier *pir_u)
u3nc(c3__boat, u3_nul));
}
/* u3_unix_ef_move()
*/
void
u3_unix_ef_move(void)
{
u3_usig* sig_u;
for ( sig_u = u3_Host.sig_u; sig_u; sig_u = sig_u->nex_u ) {
uv_signal_start(&sig_u->sil_u, _unix_sign_cb, sig_u->num_i);
}
}
/* u3_unix_ef_look(): update the root.
*/
void
@ -1346,7 +1302,6 @@ void
u3_unix_io_talk(u3_pier *pir_u)
{
u3_unix_acquire(pir_u->pax_c);
u3_unix_ef_move();
}
/* u3_unix_io_exit(): terminate unix I/O.