mirror of
https://github.com/urbit/shrub.git
synced 2024-11-27 10:26:14 +03:00
Merge pull request #1243 from urbit/ccr-signal-reform
cc-release: cleanup of signal handling
This commit is contained in:
commit
62e7c8272b
@ -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");
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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)));
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user