mirror of
https://github.com/urbit/shrub.git
synced 2024-12-20 09:21:42 +03:00
vere: refactors king/pier/lord shutdown
This commit is contained in:
parent
98040ffa2d
commit
4a48e16f41
@ -483,7 +483,7 @@ _stop_signal(c3_i int_i)
|
||||
{
|
||||
// if we have a pier, unmap the event log before dumping core
|
||||
//
|
||||
u3_pier_halt();
|
||||
u3_king_halt();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -581,7 +581,7 @@ _fork_into_background_process()
|
||||
static void
|
||||
_stop_on_boot_completed_cb()
|
||||
{
|
||||
u3_pier_exit(u3_pier_stub());
|
||||
u3_king_exit();
|
||||
}
|
||||
|
||||
c3_i
|
||||
|
@ -413,7 +413,6 @@
|
||||
u3_peek* pek_u; // peek
|
||||
u3_info fon_u; // recompute
|
||||
c3_d eve_d; // save/pack at
|
||||
c3_w xit_w; // exit code
|
||||
};
|
||||
} u3_writ;
|
||||
|
||||
@ -431,7 +430,8 @@
|
||||
void (*work_bail_f)(void*, u3_ovum*, u3_noun lud);
|
||||
void (*save_f)(void*);
|
||||
void (*pack_f)(void*);
|
||||
void (*exit_f)(void*, c3_o);
|
||||
void (*bail_f)(void*);
|
||||
void (*exit_f)(void*);
|
||||
} u3_lord_cb;
|
||||
|
||||
/* u3_lord: serf controller.
|
||||
@ -600,15 +600,14 @@
|
||||
// XX remove
|
||||
c3_s por_s; // UDP port
|
||||
u3_save* sav_u; // autosave
|
||||
struct _u3_pier* nex_u; // next in list
|
||||
} u3_pier;
|
||||
|
||||
/* u3_king: all executing piers.
|
||||
*/
|
||||
typedef struct _u3_king {
|
||||
c3_c* certs_c; // ssl certificate dump
|
||||
c3_w len_w; // number used
|
||||
c3_w all_w; // number allocated
|
||||
u3_pier** tab_u; // pier table
|
||||
u3_pier* pir_u; // pier list
|
||||
uv_timer_t tim_u; // gc timer
|
||||
} u3_king;
|
||||
|
||||
@ -885,7 +884,17 @@
|
||||
/* u3_lord_exit(): shutdown gracefully.
|
||||
*/
|
||||
void
|
||||
u3_lord_exit(u3_lord* god_u, c3_w cod_w);
|
||||
u3_lord_exit(u3_lord* god_u);
|
||||
|
||||
/* u3_lord_stall(): send SIGINT
|
||||
*/
|
||||
void
|
||||
u3_lord_stall(u3_lord* god_u);
|
||||
|
||||
/* u3_lord_halt(): shutdown immediately
|
||||
*/
|
||||
void
|
||||
u3_lord_halt(u3_lord* god_u);
|
||||
|
||||
/* u3_lord_save(): save a snapshot.
|
||||
*/
|
||||
@ -1204,12 +1213,12 @@
|
||||
/* u3_pier_bail(): immediately shutdown..
|
||||
*/
|
||||
void
|
||||
u3_pier_bail(void);
|
||||
u3_pier_bail(u3_pier* pir_u);
|
||||
|
||||
/* u3_pier_halt(): emergency release.
|
||||
/* u3_pier_halt(): emergency resource release (ie, on SIGABRT).
|
||||
*/
|
||||
void
|
||||
u3_pier_halt(void);
|
||||
u3_pier_halt(u3_pier* pir_u);
|
||||
|
||||
/* u3_pier_save(): request checkpoint.
|
||||
*/
|
||||
@ -1221,14 +1230,9 @@
|
||||
c3_o
|
||||
u3_pier_pack(u3_pier* pir_u);
|
||||
|
||||
/* u3_pier_stub(): get the One Pier for unreconstructed code.
|
||||
*/
|
||||
u3_pier*
|
||||
u3_pier_stub(void);
|
||||
|
||||
/* u3_pier_boot(): start the new pier system.
|
||||
*/
|
||||
void
|
||||
u3_pier*
|
||||
u3_pier_boot(c3_w wag_w, // config flags
|
||||
u3_noun who, // identity
|
||||
u3_noun ven, // boot event
|
||||
@ -1237,7 +1241,7 @@
|
||||
|
||||
/* u3_pier_stay(): restart the new pier system.
|
||||
*/
|
||||
void
|
||||
u3_pier*
|
||||
u3_pier_stay(c3_w wag_w, u3_noun pax);
|
||||
|
||||
/* u3_pier_tank(): dump single tank.
|
||||
@ -1285,6 +1289,26 @@
|
||||
void
|
||||
u3_king_commence();
|
||||
|
||||
/* u3_king_stub(): get the One Pier for unreconstructed code.
|
||||
*/
|
||||
u3_pier*
|
||||
u3_king_stub(void);
|
||||
|
||||
/* u3_king_done(): all piers closed
|
||||
*/
|
||||
void
|
||||
u3_king_done(void);
|
||||
|
||||
/* u3_king_exit(): shutdown gracefully
|
||||
*/
|
||||
void
|
||||
u3_king_exit(void);
|
||||
|
||||
/* u3_king_halt(): emergency release.
|
||||
*/
|
||||
void
|
||||
u3_king_halt(void);
|
||||
|
||||
/* u3_king_bail(): immediately shutdown.
|
||||
*/
|
||||
void
|
||||
|
@ -463,7 +463,7 @@ _ames_io_start(u3_ames* sam_u)
|
||||
|
||||
// XX revise
|
||||
//
|
||||
u3_pier_exit(u3_pier_stub());
|
||||
u3_pier_bail(u3_king_stub());
|
||||
}
|
||||
|
||||
uv_udp_getsockname(&sam_u->wax_u, (struct sockaddr *)&add_u, &add_i);
|
||||
|
@ -737,7 +737,10 @@ _term_suck(u3_utty* uty_u, const c3_y* buf, ssize_t siz_i)
|
||||
// then corrupts the event log), so we force shutdown.
|
||||
//
|
||||
u3l_log("term: hangup (EOF)\r\n");
|
||||
u3_pier_exit(u3_pier_stub());
|
||||
|
||||
// XX revise
|
||||
//
|
||||
u3_pier_bail(u3_king_stub());
|
||||
}
|
||||
else if ( siz_i < 0 ) {
|
||||
u3l_log("term %d: read: %s\n", uty_u->tid_l, uv_strerror(siz_i));
|
||||
|
@ -168,7 +168,10 @@ _daemon_boot(u3_noun bul)
|
||||
void
|
||||
_daemon_fake(u3_noun ship, u3_noun pill, u3_noun path)
|
||||
{
|
||||
u3_pier_boot(sag_w, ship, u3nc(c3__fake, u3k(ship)), pill, path);
|
||||
// XX link properly
|
||||
//
|
||||
u3_noun vent = u3nc(c3__fake, u3k(ship));
|
||||
u3K.pir_u = u3_pier_boot(sag_w, ship, vent, pill, path);
|
||||
}
|
||||
|
||||
/* _daemon_come(): mine a comet under star (unit)
|
||||
@ -197,7 +200,10 @@ _daemon_dawn(u3_noun seed, u3_noun pill, u3_noun path)
|
||||
//
|
||||
u3C.slog_f = _daemon_slog;
|
||||
|
||||
u3_pier_boot(sag_w, u3k(u3h(seed)), u3_dawn_vent(seed), pill, path);
|
||||
// XX link properly
|
||||
//
|
||||
u3_noun vent = u3_dawn_vent(seed);
|
||||
u3K.pir_u = u3_pier_boot(sag_w, u3k(u3h(seed)), vent, pill, path);
|
||||
|
||||
// disable ivory slog printfs
|
||||
//
|
||||
@ -215,7 +221,7 @@ _daemon_pier(u3_noun pier)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
u3_pier_stay(sag_w, u3k(u3t(pier)));
|
||||
u3K.pir_u = u3_pier_stay(sag_w, u3k(u3t(pier)));
|
||||
u3z(pier);
|
||||
}
|
||||
|
||||
@ -574,7 +580,7 @@ _daemon_sign_cb(uv_signal_t* sil_u, c3_i num_i)
|
||||
}
|
||||
|
||||
case SIGTERM: {
|
||||
u3_pier_exit(u3_pier_stub());
|
||||
u3_king_exit();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -722,13 +728,104 @@ u3_king_commence()
|
||||
_daemon_loop_exit();
|
||||
}
|
||||
|
||||
/* u3_king_stub(): get the One Pier for unreconstructed code.
|
||||
*/
|
||||
u3_pier*
|
||||
u3_king_stub(void)
|
||||
{
|
||||
if ( !u3K.pir_u ) {
|
||||
c3_assert(!"king: no pier");
|
||||
}
|
||||
else {
|
||||
return u3K.pir_u;
|
||||
}
|
||||
}
|
||||
|
||||
/* _king_forall(): run on all piers
|
||||
*/
|
||||
static void
|
||||
_king_forall(void (*pir_f)(u3_pier*))
|
||||
{
|
||||
u3_pier* pir_u = u3K.pir_u;
|
||||
|
||||
while ( pir_u ) {
|
||||
pir_f(pir_u);
|
||||
pir_u = pir_u->nex_u;
|
||||
}
|
||||
}
|
||||
|
||||
/* _king_forall_unlink(): run on all piers, unlinking from king.
|
||||
*/
|
||||
static void
|
||||
_king_forall_unlink(void (*pir_f)(u3_pier*))
|
||||
{
|
||||
u3_pier* pir_u = u3K.pir_u;
|
||||
|
||||
while ( u3K.pir_u ) {
|
||||
u3_pier* pir_u = u3K.pir_u;
|
||||
u3K.pir_u = pir_u->nex_u;
|
||||
pir_f(pir_u);
|
||||
}
|
||||
}
|
||||
|
||||
/* _king_done_cb():
|
||||
*/
|
||||
static void
|
||||
_king_done_cb(uv_handle_t* han_u)
|
||||
{
|
||||
if( UV_EBUSY == uv_loop_close(u3L) ) {
|
||||
// XX uncomment to debug
|
||||
//
|
||||
// fprintf(stderr, "\r\nking: open libuv handles\r\n");
|
||||
// uv_print_all_handles(u3L, stderr);
|
||||
// fprintf(stderr, "\r\nking: force shutdown\r\n");
|
||||
|
||||
uv_stop(u3L);
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_king_done(): all piers closed. s/b callback
|
||||
*/
|
||||
void
|
||||
u3_king_done(void)
|
||||
{
|
||||
uv_handle_t* han_u = (uv_handle_t*)&u3K.tim_u;
|
||||
|
||||
// XX hack, if pier's are still linked, we're not actually done
|
||||
//
|
||||
if ( !u3K.pir_u && !uv_is_closing(han_u) ) {
|
||||
uv_close((uv_handle_t*)&u3K.tim_u, _king_done_cb);
|
||||
_daemon_sign_close();
|
||||
|
||||
u3_term_log_exit();
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_king_exit(): shutdown gracefully
|
||||
*/
|
||||
void
|
||||
u3_king_exit(void)
|
||||
{
|
||||
_king_forall(u3_pier_exit);
|
||||
}
|
||||
|
||||
/* u3_king_halt(): emergency release
|
||||
*/
|
||||
void
|
||||
u3_king_halt(void)
|
||||
{
|
||||
_king_forall_unlink(u3_pier_halt);
|
||||
}
|
||||
|
||||
/* u3_king_bail(): immediately shutdown.
|
||||
*/
|
||||
void
|
||||
u3_king_bail(void)
|
||||
{
|
||||
_king_forall_unlink(u3_pier_bail);
|
||||
_daemon_loop_exit();
|
||||
u3_pier_bail();
|
||||
u3_king_done();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -750,7 +847,7 @@ u3_king_grab(void* vod_p)
|
||||
c3_c* wen_c = u3r_string(wen);
|
||||
|
||||
c3_c nam_c[2048];
|
||||
snprintf(nam_c, 2048, "%s/.urb/put/mass", u3_pier_stub()->pax_c);
|
||||
snprintf(nam_c, 2048, "%s/.urb/put/mass", u3_king_stub()->pax_c);
|
||||
|
||||
struct stat st;
|
||||
if ( -1 == stat(nam_c, &st) ) {
|
||||
|
@ -53,6 +53,112 @@
|
||||
--
|
||||
*/
|
||||
|
||||
/* _lord_stop_cb(): finally all done.
|
||||
*/
|
||||
static void
|
||||
_lord_stop_cb(void* ptr_v,
|
||||
const c3_c* err_c)
|
||||
{
|
||||
u3_lord* god_u = ptr_v;
|
||||
|
||||
void (*exit_f)(void*) = god_u->cb_u.exit_f;
|
||||
void* exit_v = god_u->cb_u.vod_p;
|
||||
|
||||
c3_free(god_u);
|
||||
|
||||
if ( exit_f ) {
|
||||
exit_f(exit_v);
|
||||
}
|
||||
}
|
||||
|
||||
/* _lord_writ_free(): dispose of pending writ.
|
||||
*/
|
||||
static void
|
||||
_lord_writ_free(u3_writ* wit_u)
|
||||
{
|
||||
switch ( wit_u->typ_e ) {
|
||||
default: c3_assert(0);
|
||||
|
||||
case u3_writ_work: {
|
||||
// XX confirm
|
||||
//
|
||||
u3_ovum* egg_u = wit_u->wok_u.egg_u;
|
||||
u3_auto_drop(egg_u->car_u, egg_u);
|
||||
u3z(wit_u->wok_u.job);
|
||||
} break;
|
||||
|
||||
case u3_writ_peek: {
|
||||
u3z(wit_u->pek_u->now);
|
||||
u3z(wit_u->pek_u->gan);
|
||||
u3z(wit_u->pek_u->ful);
|
||||
} break;
|
||||
|
||||
case u3_writ_play: {
|
||||
u3_fact* tac_u = wit_u->fon_u.ext_u;
|
||||
u3_fact* nex_u;
|
||||
|
||||
while ( tac_u ) {
|
||||
nex_u = tac_u->nex_u;
|
||||
u3_fact_free(tac_u);
|
||||
tac_u = nex_u;
|
||||
}
|
||||
} break;
|
||||
|
||||
case u3_writ_save:
|
||||
case u3_writ_pack:
|
||||
case u3_writ_exit: {
|
||||
} break;
|
||||
}
|
||||
|
||||
c3_free(wit_u);
|
||||
}
|
||||
|
||||
/* _lord_bail_noop(): ignore subprocess error on shutdown
|
||||
*/
|
||||
static void
|
||||
_lord_bail_noop(void* ptr_v,
|
||||
const c3_c* err_c)
|
||||
{
|
||||
}
|
||||
|
||||
/* _lord_stop(): close and dispose all resources.
|
||||
*/
|
||||
static void
|
||||
_lord_stop(u3_lord* god_u)
|
||||
{
|
||||
// dispose outstanding writs
|
||||
//
|
||||
{
|
||||
u3_writ* wit_u = god_u->ext_u;
|
||||
u3_writ* nex_u;
|
||||
|
||||
while ( wit_u ) {
|
||||
nex_u = wit_u->nex_u;
|
||||
_lord_writ_free(wit_u);
|
||||
wit_u = nex_u;
|
||||
}
|
||||
|
||||
god_u->ent_u = god_u->ext_u = 0;
|
||||
}
|
||||
|
||||
u3_newt_moat_stop(&god_u->out_u, _lord_stop_cb);
|
||||
u3_newt_mojo_stop(&god_u->inn_u, _lord_bail_noop);
|
||||
|
||||
uv_close((uv_handle_t*)&god_u->cub_u, 0);
|
||||
}
|
||||
|
||||
/* _lord_bail(): serf/lord error.
|
||||
*/
|
||||
static void
|
||||
_lord_bail(u3_lord* god_u)
|
||||
{
|
||||
void (*bail_f)(void*) = god_u->cb_u.bail_f;
|
||||
void* bail_v = god_u->cb_u.vod_p;
|
||||
|
||||
u3_lord_halt(god_u);
|
||||
bail_f(bail_v);
|
||||
}
|
||||
|
||||
/* _lord_writ_pop(): pop the writ stack.
|
||||
*/
|
||||
static u3_writ*
|
||||
@ -103,58 +209,13 @@ _lord_writ_need(u3_lord* god_u, u3_writ_type typ_e)
|
||||
fprintf(stderr, "lord: unexpected %%%s, expected %%%s\r\n",
|
||||
_lord_writ_str(typ_e),
|
||||
_lord_writ_str(wit_u->typ_e));
|
||||
u3_pier_bail();
|
||||
exit(1);
|
||||
_lord_bail(god_u);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return wit_u;
|
||||
}
|
||||
|
||||
/* _lord_on_k(): handle subprocess exit.
|
||||
*/
|
||||
static void
|
||||
_lord_on_exit(uv_process_t* req_u,
|
||||
c3_ds sas_i,
|
||||
c3_i sig_i)
|
||||
{
|
||||
u3_lord* god_u = (void*)req_u;
|
||||
|
||||
{
|
||||
void (*exit_f)(void*, c3_o) = god_u->cb_u.exit_f;
|
||||
void* vod_p = god_u->cb_u.vod_p;
|
||||
|
||||
// XX correct comparison?
|
||||
//
|
||||
c3_o ret_o = ( u3_writ_exit != god_u->ext_u->typ_e )
|
||||
? c3n
|
||||
: ( god_u->ext_u->xit_w == sas_i )
|
||||
? c3y : c3n;
|
||||
|
||||
// XX dispose god_u
|
||||
//
|
||||
exit_f(vod_p, c3y);
|
||||
}
|
||||
}
|
||||
|
||||
/* _lord_bail_noop(): ignore subprocess error on shutdown
|
||||
*/
|
||||
static void
|
||||
_lord_bail_noop(void* vod_p,
|
||||
const c3_c* err_c)
|
||||
{
|
||||
}
|
||||
|
||||
/* _lord_bail(): handle subprocess error.
|
||||
*/
|
||||
static void
|
||||
_lord_bail(void* vod_p,
|
||||
const c3_c* err_c)
|
||||
{
|
||||
// XX exit?
|
||||
//
|
||||
fprintf(stderr, "\rpier: work error: %s\r\n", err_c);
|
||||
}
|
||||
|
||||
/* _lord_plea_foul():
|
||||
*/
|
||||
static void
|
||||
@ -167,9 +228,11 @@ _lord_plea_foul(u3_lord* god_u, c3_m mot_m, u3_noun dat)
|
||||
fprintf(stderr, "lord: received invalid %%%.4s $plea\r\n", (c3_c*)&mot_m);
|
||||
}
|
||||
|
||||
u3m_p("plea", dat);
|
||||
u3_pier_bail();
|
||||
exit(1);
|
||||
// XX can't unconditionally print
|
||||
//
|
||||
// u3m_p("plea", dat);
|
||||
|
||||
_lord_bail(god_u);
|
||||
}
|
||||
|
||||
/* _lord_plea_live(): hear serf %live ack
|
||||
@ -207,8 +270,8 @@ _lord_plea_ripe(u3_lord* god_u, u3_noun dat)
|
||||
{
|
||||
if ( c3y == god_u->liv_o ) {
|
||||
fprintf(stderr, "lord: received unexpected %%ripe\n");
|
||||
u3_pier_bail();
|
||||
exit(1);
|
||||
_lord_bail(god_u);
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
@ -230,8 +293,8 @@ _lord_plea_ripe(u3_lord* god_u, u3_noun dat)
|
||||
|
||||
if ( 1 != pro_y ) {
|
||||
fprintf(stderr, "pier: unsupported ipc protocol version %u\r\n", pro_y);
|
||||
u3_pier_bail();
|
||||
exit(1);
|
||||
_lord_bail(god_u);
|
||||
return;
|
||||
}
|
||||
|
||||
god_u->eve_d = eve_d;
|
||||
@ -276,6 +339,7 @@ _lord_plea_peek(u3_lord* god_u, u3_noun dat)
|
||||
{
|
||||
u3_writ* wit_u = _lord_writ_need(god_u, u3_writ_peek);
|
||||
pek_u = wit_u->pek_u;
|
||||
c3_free(wit_u);
|
||||
}
|
||||
|
||||
// XX cache [dat] (unless last)
|
||||
@ -533,12 +597,12 @@ _lord_plea_work(u3_lord* god_u, u3_noun dat)
|
||||
u3z(dat);
|
||||
}
|
||||
|
||||
/* _lord_plea(): handle plea from serf.
|
||||
/* _lord_on_plea(): handle plea from serf.
|
||||
*/
|
||||
static void
|
||||
_lord_plea(void* vod_p, u3_noun mat)
|
||||
_lord_on_plea(void* ptr_v, u3_noun mat)
|
||||
{
|
||||
u3_lord* god_u = vod_p;
|
||||
u3_lord* god_u = ptr_v;
|
||||
u3_noun jar = u3ke_cue(mat);
|
||||
u3_noun tag, dat;
|
||||
|
||||
@ -634,9 +698,9 @@ _lord_writ_jam(u3_lord* god_u, u3_writ* wit_u)
|
||||
} break;
|
||||
|
||||
case u3_writ_exit: {
|
||||
// XX u3_newt_close on send
|
||||
// requested exit code is always 0
|
||||
//
|
||||
msg = u3nt(c3__live, c3__exit, u3i_words(1, &wit_u->xit_w));
|
||||
msg = u3nt(c3__live, c3__exit, 0);
|
||||
} break;
|
||||
}
|
||||
|
||||
@ -649,16 +713,16 @@ _lord_writ_jam(u3_lord* god_u, u3_writ* wit_u)
|
||||
static void
|
||||
_lord_writ_send(u3_lord* god_u, u3_writ* wit_u)
|
||||
{
|
||||
_lord_writ_jam(god_u, wit_u);
|
||||
u3_newt_write(&god_u->inn_u, wit_u->mat);
|
||||
wit_u->mat = 0;
|
||||
|
||||
// ignore subprocess error on shutdown
|
||||
// exit expected
|
||||
//
|
||||
if ( u3_writ_exit == wit_u->typ_e ) {
|
||||
god_u->out_u.bal_f = _lord_bail_noop;
|
||||
god_u->inn_u.bal_f = _lord_bail_noop;
|
||||
}
|
||||
|
||||
_lord_writ_jam(god_u, wit_u);
|
||||
u3_newt_write(&god_u->inn_u, wit_u->mat);
|
||||
wit_u->mat = 0;
|
||||
}
|
||||
|
||||
/* _lord_writ_plan(): enqueue a writ and send.
|
||||
@ -848,12 +912,67 @@ u3_lord_pack(u3_lord* god_u)
|
||||
/* u3_lord_exit(): shutdown gracefully.
|
||||
*/
|
||||
void
|
||||
u3_lord_exit(u3_lord* god_u, c3_w cod_w)
|
||||
u3_lord_exit(u3_lord* god_u)
|
||||
{
|
||||
u3_writ* wit_u = _lord_writ_new(god_u);
|
||||
wit_u->typ_e = u3_writ_exit;
|
||||
wit_u->xit_w = cod_w;
|
||||
_lord_writ_plan(god_u, wit_u);
|
||||
|
||||
// XX set timer, then halt
|
||||
}
|
||||
|
||||
/* u3_lord_stall(): send SIGINT
|
||||
*/
|
||||
void
|
||||
u3_lord_stall(u3_lord* god_u)
|
||||
{
|
||||
uv_process_kill(&god_u->cub_u, SIGINT);
|
||||
}
|
||||
|
||||
/* u3_lord_halt(): shutdown immediately
|
||||
*/
|
||||
void
|
||||
u3_lord_halt(u3_lord* god_u)
|
||||
{
|
||||
// no exit callback on halt
|
||||
//
|
||||
god_u->cb_u.exit_f = 0;
|
||||
|
||||
uv_process_kill(&god_u->cub_u, SIGKILL);
|
||||
_lord_stop(god_u);
|
||||
}
|
||||
|
||||
/* _lord_on_serf_exit(): handle subprocess exit.
|
||||
*/
|
||||
static void
|
||||
_lord_on_serf_exit(uv_process_t* req_u,
|
||||
c3_ds sas_i,
|
||||
c3_i sig_i)
|
||||
{
|
||||
|
||||
u3_lord* god_u = (void*)req_u;
|
||||
|
||||
if ( !god_u->ext_u
|
||||
|| !(u3_writ_exit == god_u->ext_u->typ_e) )
|
||||
{
|
||||
fprintf(stderr, "pier: work exit: status %" PRId64 ", signal %d\r\n",
|
||||
sas_i, sig_i);
|
||||
_lord_bail(god_u);
|
||||
}
|
||||
else {
|
||||
_lord_stop(god_u);
|
||||
}
|
||||
}
|
||||
|
||||
/* _lord_on_serf_bail(): handle subprocess error.
|
||||
*/
|
||||
static void
|
||||
_lord_on_serf_bail(void* ptr_v,
|
||||
const c3_c* err_c)
|
||||
{
|
||||
u3_lord* god_u = ptr_v;
|
||||
u3l_log("pier: serf error: %s\r\n", err_c);
|
||||
_lord_bail(god_u);
|
||||
}
|
||||
|
||||
/* u3_lord_init(): instantiate child process.
|
||||
@ -921,7 +1040,7 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u)
|
||||
god_u->ops_u.stdio = god_u->cod_u;
|
||||
god_u->ops_u.stdio_count = 3;
|
||||
|
||||
god_u->ops_u.exit_cb = _lord_on_exit;
|
||||
god_u->ops_u.exit_cb = _lord_on_serf_exit;
|
||||
god_u->ops_u.file = arg_c[0];
|
||||
god_u->ops_u.args = arg_c;
|
||||
|
||||
@ -936,13 +1055,13 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u)
|
||||
//
|
||||
{
|
||||
god_u->out_u.ptr_v = god_u;
|
||||
god_u->out_u.pok_f = _lord_plea;
|
||||
god_u->out_u.bal_f = _lord_bail;
|
||||
god_u->out_u.pok_f = _lord_on_plea;
|
||||
god_u->out_u.bal_f = _lord_on_serf_bail;
|
||||
|
||||
// XX distinguish from out_u.bal_f ?
|
||||
//
|
||||
god_u->inn_u.ptr_v = god_u;
|
||||
god_u->inn_u.bal_f = _lord_bail;
|
||||
god_u->inn_u.bal_f = _lord_on_serf_bail;
|
||||
|
||||
u3_newt_read(&god_u->out_u);
|
||||
}
|
||||
|
@ -592,7 +592,7 @@ _pier_play(u3_play* pay_u)
|
||||
// // XX graceful shutdown
|
||||
// //
|
||||
// u3_lord_save(pir_u->god_u);
|
||||
// u3_pier_bail();
|
||||
// u3_pier_bail(pir_u);
|
||||
// exit(0);
|
||||
|
||||
// XX temporary hack
|
||||
@ -631,7 +631,7 @@ _pier_on_lord_play_done(void* vod_p, u3_info fon_u, c3_l mug_l)
|
||||
tac_u->eve_d,
|
||||
tac_u->mug_l,
|
||||
mug_l);
|
||||
// u3_pier_bail();
|
||||
// u3_pier_bail(pir_u);
|
||||
}
|
||||
|
||||
// dispose successful
|
||||
@ -680,7 +680,7 @@ _pier_on_lord_play_bail(void* vod_p, u3_info fon_u,
|
||||
(c3_d)(eve_d - 1ULL),
|
||||
las_l,
|
||||
mug_l);
|
||||
// u3_pier_bail();
|
||||
// u3_pier_bail(pir_u);
|
||||
}
|
||||
|
||||
// XX enable to retry
|
||||
@ -716,7 +716,7 @@ _pier_on_lord_play_bail(void* vod_p, u3_info fon_u,
|
||||
u3_pier_punt_ovum("play", u3k(wir), u3k(tag));
|
||||
}
|
||||
|
||||
u3_pier_bail();
|
||||
u3_pier_bail(pir_u);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
@ -785,7 +785,7 @@ _pier_on_disk_read_bail(void* vod_p, c3_d eve_d)
|
||||
//
|
||||
fprintf(stderr, "pier: disk read bail\r\n");
|
||||
u3_term_stop_spinner();
|
||||
u3_pier_bail();
|
||||
u3_pier_bail(pir_u);
|
||||
}
|
||||
|
||||
/* _pier_on_disk_write_done(): event log write success.
|
||||
@ -833,7 +833,7 @@ _pier_on_disk_write_bail(void* vod_p, c3_d eve_d)
|
||||
// XX
|
||||
//
|
||||
fprintf(stderr, "pier: disk write bail\r\n");
|
||||
u3_pier_bail();
|
||||
u3_pier_bail(pir_u);
|
||||
}
|
||||
|
||||
/* _pier_on_lord_slog(): debug printf from worker.
|
||||
@ -883,35 +883,56 @@ _pier_on_lord_pack(void* vod_p)
|
||||
//
|
||||
if ( u3_psat_play == pir_u->sat_e ) {
|
||||
u3l_log("pier: pack complete, shutting down\r\n");
|
||||
u3_pier_bail();
|
||||
u3_pier_bail(pir_u);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// if ( u3_psat_done == pir_u->sat_e ) {
|
||||
// fprintf(stderr, "snap cb exit\r\n");
|
||||
// u3_lord_exit(pir_u->god_u, 0);
|
||||
// u3_lord_exit(pir_u->god_u);
|
||||
// }
|
||||
// else {
|
||||
// _pier_next(pir_u);
|
||||
// }
|
||||
}
|
||||
|
||||
static void
|
||||
_pier_done(u3_pier* pir_u);
|
||||
|
||||
/* _pier_on_lord_exit(): worker shutdown.
|
||||
*/
|
||||
static void
|
||||
_pier_on_lord_exit(void* vod_p, c3_o ret_o)
|
||||
_pier_on_lord_exit(void* vod_p)
|
||||
{
|
||||
u3_pier* pir_u = vod_p;
|
||||
|
||||
if ( u3_psat_done == pir_u->sat_e ) {
|
||||
if ( c3n == ret_o ) {
|
||||
u3l_log("pier: serf shutdown dirty\r\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
// the lord has already gone
|
||||
//
|
||||
pir_u->god_u = 0;
|
||||
|
||||
if ( u3_psat_done != pir_u->sat_e ) {
|
||||
u3l_log("pier: serf shutdown unexpected\r\n");
|
||||
u3_pier_bail();
|
||||
u3_pier_bail(pir_u);
|
||||
}
|
||||
// if we made it all the way here, it's our jab to wrap up
|
||||
//
|
||||
else {
|
||||
_pier_done(pir_u);
|
||||
}
|
||||
}
|
||||
|
||||
/* _pier_on_lord_bail(): worker error.
|
||||
*/
|
||||
static void
|
||||
_pier_on_lord_bail(void* vod_p)
|
||||
{
|
||||
u3_pier* pir_u = vod_p;
|
||||
|
||||
// the lord has already gone
|
||||
//
|
||||
pir_u->god_u = 0;
|
||||
|
||||
u3_pier_bail(pir_u);
|
||||
}
|
||||
|
||||
/* _pier_on_lord_live(): worker is ready.
|
||||
@ -1031,6 +1052,7 @@ _pier_init(c3_w wag_w, c3_c* pax_c)
|
||||
.work_bail_f = _pier_on_lord_work_bail,
|
||||
.save_f = _pier_on_lord_save,
|
||||
.pack_f = _pier_on_lord_pack,
|
||||
.bail_f = _pier_on_lord_bail,
|
||||
.exit_f = _pier_on_lord_exit
|
||||
};
|
||||
|
||||
@ -1042,26 +1064,12 @@ _pier_init(c3_w wag_w, c3_c* pax_c)
|
||||
}
|
||||
}
|
||||
|
||||
// install in the pier table
|
||||
//
|
||||
// XX u3_king_plan
|
||||
//
|
||||
if ( 0 == u3K.all_w ) {
|
||||
u3K.all_w = 16;
|
||||
u3K.tab_u = c3_malloc(16 * sizeof(u3_pier*));
|
||||
}
|
||||
if ( u3K.len_w == u3K.all_w ) {
|
||||
u3K.all_w = 2 * u3K.all_w;
|
||||
u3K.tab_u = c3_realloc(u3K.tab_u, u3K.all_w * sizeof(u3_pier*));
|
||||
}
|
||||
u3K.tab_u[u3K.len_w++] = pir_u;
|
||||
|
||||
return pir_u;
|
||||
}
|
||||
|
||||
/* u3_pier_stay(): restart an existing pier.
|
||||
*/
|
||||
void
|
||||
u3_pier*
|
||||
u3_pier_stay(c3_w wag_w, u3_noun pax)
|
||||
{
|
||||
u3_pier* pir_u = _pier_init(wag_w, u3r_string(pax));
|
||||
@ -1072,11 +1080,13 @@ u3_pier_stay(c3_w wag_w, u3_noun pax)
|
||||
fprintf(stderr, "pier: disk read meta fail\r\n");
|
||||
// XX dispose
|
||||
//
|
||||
u3_pier_bail();
|
||||
u3_pier_bail(pir_u);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
u3z(pax);
|
||||
|
||||
return pir_u;
|
||||
}
|
||||
|
||||
/* _pier_pill_parse(): extract boot formulas and module/userspace ova from pill
|
||||
@ -1265,7 +1275,7 @@ _pier_boot_plan(u3_pier* pir_u, u3_noun who, u3_noun ven, u3_noun pil)
|
||||
|
||||
/* u3_pier_boot(): start a new pier.
|
||||
*/
|
||||
void
|
||||
u3_pier*
|
||||
u3_pier_boot(c3_w wag_w, // config flags
|
||||
u3_noun who, // identity
|
||||
u3_noun ven, // boot event
|
||||
@ -1278,11 +1288,13 @@ u3_pier_boot(c3_w wag_w, // config flags
|
||||
fprintf(stderr, "pier: boot plan fail\r\n");
|
||||
// XX dispose
|
||||
//
|
||||
u3_pier_bail();
|
||||
u3_pier_bail(pir_u);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
u3z(pax);
|
||||
|
||||
return pir_u;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1353,29 +1365,51 @@ u3_pier_pack(u3_pier* pir_u)
|
||||
}
|
||||
|
||||
static void
|
||||
_pier_exit_work_cb(uv_handle_t* idl_u)
|
||||
_pier_work_close_cb(uv_handle_t* idl_u)
|
||||
{
|
||||
u3_work* wok_u = idl_u->data;
|
||||
c3_free(wok_u);
|
||||
}
|
||||
|
||||
/* _pier_exit_cb(): synchronous shutdown.
|
||||
static void
|
||||
_pier_work_close(u3_work* wok_u)
|
||||
{
|
||||
u3_auto_exit(wok_u->car_u);
|
||||
|
||||
// free pending effects
|
||||
//
|
||||
{
|
||||
u3_gift* gif_u = wok_u->fec_u.ext_u;
|
||||
u3_gift* nex_u;
|
||||
|
||||
while ( gif_u ) {
|
||||
nex_u = gif_u->nex_u;
|
||||
u3_gift_free(gif_u);
|
||||
gif_u = nex_u;
|
||||
}
|
||||
}
|
||||
|
||||
uv_close((uv_handle_t*)&wok_u->pep_u, _pier_work_close_cb);
|
||||
uv_close((uv_handle_t*)&wok_u->cek_u, 0);
|
||||
uv_close((uv_handle_t*)&wok_u->idl_u, 0);
|
||||
wok_u->pep_u.data = wok_u;
|
||||
}
|
||||
|
||||
static void
|
||||
_pier_done(u3_pier* pir_u)
|
||||
{
|
||||
// XX unlink properly
|
||||
//
|
||||
u3K.pir_u = 0;
|
||||
u3_king_done();
|
||||
}
|
||||
|
||||
/* _pier_exit(): synchronous shutdown.
|
||||
*/
|
||||
static void
|
||||
_pier_exit_cb(void* vod_p, c3_d eve_d)
|
||||
_pier_exit(u3_pier* pir_u)
|
||||
{
|
||||
u3_pier* pir_u = vod_p;
|
||||
|
||||
if ( pir_u->wok_u ) {
|
||||
u3_work* wok_u = pir_u->wok_u;
|
||||
u3_auto_exit(wok_u->car_u);
|
||||
// XX confirm, libuv close callback are fired with a stack discipline
|
||||
//
|
||||
uv_close((uv_handle_t*)&wok_u->pep_u, _pier_exit_work_cb);
|
||||
uv_close((uv_handle_t*)&wok_u->cek_u, 0);
|
||||
uv_close((uv_handle_t*)&wok_u->idl_u, 0);
|
||||
pir_u->wok_u = 0;
|
||||
}
|
||||
c3_assert( u3_psat_done == pir_u->sat_e );
|
||||
|
||||
if ( pir_u->log_u ) {
|
||||
u3_disk_exit(pir_u->log_u);
|
||||
@ -1383,17 +1417,46 @@ _pier_exit_cb(void* vod_p, c3_d eve_d)
|
||||
}
|
||||
|
||||
if ( pir_u->god_u ) {
|
||||
u3_lord_exit(pir_u->god_u, 0);
|
||||
u3_lord_exit(pir_u->god_u);
|
||||
pir_u->god_u = 0;
|
||||
}
|
||||
else {
|
||||
// otherwise called in _pier_on_lord_exit()
|
||||
//
|
||||
_pier_done(pir_u);
|
||||
}
|
||||
}
|
||||
|
||||
u3_term_log_exit();
|
||||
/* _pier_work_exit(): commence graceful shutdown.
|
||||
*/
|
||||
static void
|
||||
_pier_work_exit_cb(void* vod_p, c3_d eve_d)
|
||||
{
|
||||
u3_pier* pir_u = vod_p;
|
||||
|
||||
// XX uninstall pier from u3K.tab_u, dispose
|
||||
_pier_work_close(pir_u->wok_u);
|
||||
pir_u->wok_u = 0;
|
||||
|
||||
// XX no can do
|
||||
_pier_exit(pir_u);
|
||||
}
|
||||
|
||||
/* _pier_work_exit(): setup graceful shutdown callbacks.
|
||||
*/
|
||||
static void
|
||||
_pier_work_exit(u3_pier* pir_u)
|
||||
{
|
||||
_pier_wall_plan(pir_u, 0, pir_u, _pier_save_cb);
|
||||
_pier_wall_plan(pir_u, 0, pir_u, _pier_work_exit_cb);
|
||||
|
||||
// XX moveme, XX bails if not started
|
||||
//
|
||||
uv_stop(u3L);
|
||||
{
|
||||
c3_l cod_l = u3a_lush(c3__save);
|
||||
u3_save_io_exit(pir_u);
|
||||
u3a_lop(cod_l);
|
||||
}
|
||||
|
||||
pir_u->sat_e = u3_psat_done;
|
||||
}
|
||||
|
||||
/* u3_pier_exit(): graceful shutdown.
|
||||
@ -1401,60 +1464,21 @@ _pier_exit_cb(void* vod_p, c3_d eve_d)
|
||||
void
|
||||
u3_pier_exit(u3_pier* pir_u)
|
||||
{
|
||||
// fprintf(stderr, "pier: exit\r\n");
|
||||
|
||||
switch ( pir_u->sat_e ) {
|
||||
// XX specifically handle init/done?
|
||||
//
|
||||
default: {
|
||||
fprintf(stderr, "pier: unexpected exit: %u\r\n", pir_u->sat_e);
|
||||
fprintf(stderr, "pier: unknown exit: %u\r\n", pir_u->sat_e);
|
||||
c3_assert(0);
|
||||
}
|
||||
|
||||
case u3_psat_boot: {
|
||||
// XX properly dispose boot
|
||||
//
|
||||
c3_free(pir_u->bot_u);
|
||||
pir_u->bot_u = 0;
|
||||
_pier_exit_cb(pir_u, 0);
|
||||
} break;
|
||||
case u3_psat_done: return;
|
||||
|
||||
case u3_psat_play: {
|
||||
// XX dispose play q
|
||||
//
|
||||
c3_free(pir_u->pay_u);
|
||||
pir_u->pay_u = 0;
|
||||
_pier_exit_cb(pir_u, 0);
|
||||
} break;
|
||||
case u3_psat_work: return _pier_work_exit(pir_u);
|
||||
|
||||
case u3_psat_work: {
|
||||
_pier_wall_plan(pir_u, 0, pir_u, _pier_save_cb);
|
||||
_pier_wall_plan(pir_u, 0, pir_u, _pier_exit_cb);
|
||||
|
||||
// XX moveme
|
||||
//
|
||||
{
|
||||
c3_l cod_l = u3a_lush(c3__save);
|
||||
u3_save_io_exit(pir_u);
|
||||
u3a_lop(cod_l);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
u3K.len_w = 0;
|
||||
pir_u->sat_e = u3_psat_done;
|
||||
}
|
||||
|
||||
/* _pier_exit_done(): force synchronous shut down.
|
||||
*/
|
||||
static void
|
||||
_pier_exit_done(u3_pier* pir_u)
|
||||
{
|
||||
switch ( pir_u->sat_e ) {
|
||||
default: break;
|
||||
case u3_psat_init: break;
|
||||
|
||||
case u3_psat_boot: {
|
||||
// XX properly dispose boot
|
||||
// XX also on actual boot
|
||||
//
|
||||
c3_free(pir_u->bot_u);
|
||||
pir_u->bot_u = 0;
|
||||
@ -1466,47 +1490,54 @@ _pier_exit_done(u3_pier* pir_u)
|
||||
c3_free(pir_u->pay_u);
|
||||
pir_u->pay_u = 0;
|
||||
} break;
|
||||
|
||||
case u3_psat_work: {
|
||||
// XX moveme
|
||||
//
|
||||
{
|
||||
c3_l cod_l = u3a_lush(c3__save);
|
||||
u3_save_io_exit(pir_u);
|
||||
u3a_lop(cod_l);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
u3K.len_w = 0;
|
||||
pir_u->sat_e = u3_psat_done;
|
||||
_pier_exit_cb(pir_u, 0);
|
||||
_pier_exit(pir_u);
|
||||
}
|
||||
|
||||
/* u3_pier_bail(): immediately shutdown.
|
||||
/* u3_pier_bail(): immediately shutdown due to error.
|
||||
*/
|
||||
void
|
||||
u3_pier_bail(void)
|
||||
u3_pier_bail(u3_pier* pir_u)
|
||||
{
|
||||
if ( 0 != u3K.len_w ) {
|
||||
_pier_exit_done(u3_pier_stub());
|
||||
pir_u->sat_e = u3_psat_done;
|
||||
|
||||
//
|
||||
if ( pir_u->god_u ) {
|
||||
u3_lord_halt(pir_u->god_u);
|
||||
pir_u->god_u = 0;
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
exit(1);
|
||||
// exig i/o drivers
|
||||
//
|
||||
if ( pir_u->wok_u ) {
|
||||
_pier_work_close(pir_u->wok_u);
|
||||
pir_u->wok_u = 0;
|
||||
}
|
||||
|
||||
// close db
|
||||
//
|
||||
if ( pir_u->log_u ) {
|
||||
u3_disk_exit(pir_u->log_u);
|
||||
pir_u->log_u = 0;
|
||||
}
|
||||
|
||||
_pier_done(pir_u);
|
||||
}
|
||||
|
||||
/* u3_pier_halt(): emergency release.
|
||||
/* u3_pier_halt(): emergency resource release (ie, on SIGABRT).
|
||||
*/
|
||||
void
|
||||
u3_pier_halt(void)
|
||||
u3_pier_halt(u3_pier* pir_u)
|
||||
{
|
||||
if ( 0 != u3K.len_w ) {
|
||||
u3_disk_exit(u3_pier_stub()->log_u);
|
||||
|
||||
// we should only ever try this trick once
|
||||
//
|
||||
u3K.len_w = 0;
|
||||
// unmap disk if present
|
||||
//
|
||||
// XX maybe skip close/cancel/free. and just unmap
|
||||
//
|
||||
if ( pir_u->log_u ) {
|
||||
u3_disk_exit(pir_u->log_u);
|
||||
pir_u->log_u = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1519,7 +1550,7 @@ c3_rand(c3_w* rad_w)
|
||||
fprintf(stderr, "c3_rand getentropy: %s\n", strerror(errno));
|
||||
// XX review
|
||||
//
|
||||
u3_pier_bail();
|
||||
u3_king_bail();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1691,19 +1722,6 @@ u3_pier_sway(c3_l tab_l, u3_noun tax)
|
||||
u3z(mok);
|
||||
}
|
||||
|
||||
/* u3_pier_stub(): get the One Pier for unreconstructed code.
|
||||
*/
|
||||
u3_pier*
|
||||
u3_pier_stub(void)
|
||||
{
|
||||
if ( 0 == u3K.len_w ) {
|
||||
c3_assert(!"plan: no pier");
|
||||
}
|
||||
else {
|
||||
return u3K.tab_u[0];
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_pier_mark(): mark all Loom allocations in all u3_pier structs.
|
||||
*/
|
||||
c3_w
|
||||
|
Loading…
Reference in New Issue
Block a user