diff options
author | Martin Mares <mj@ucw.cz> | 1999-02-13 21:15:36 +0100 |
---|---|---|
committer | Martin Mares <mj@ucw.cz> | 1999-02-13 21:15:36 +0100 |
commit | f4aabcee62890b7c3e999e188ab72752fbb20b79 (patch) | |
tree | 99daddcfbae637f7801f8b70b42ee2b5c9e91178 /nest/proto.c | |
parent | 7f3d1a0850ff7f240b2f240db6d44b3a5dee6d48 (diff) | |
download | bird-f4aabcee62890b7c3e999e188ab72752fbb20b79.tar bird-f4aabcee62890b7c3e999e188ab72752fbb20b79.zip |
Perform gracious shutdown upon receipt of SIGTERM. Finally we can
test the whole protocol shutdown code... :)
Diffstat (limited to 'nest/proto.c')
-rw-r--r-- | nest/proto.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/nest/proto.c b/nest/proto.c index 76422e3..f96d37d 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -28,6 +28,8 @@ static list inactive_proto_list; static list initial_proto_list; static list flush_proto_list; +static int proto_shutdown_counter; + static event *proto_flush_event; static char *p_states[] = { "DOWN", "START", "UP", "STOP" }; @@ -178,7 +180,7 @@ proto_rethink_goal(struct proto *p) static void proto_set_goal(struct proto *p, unsigned goal) { - if (p->disabled) + if (p->disabled || shutting_down) goal = FS_HUNGRY; p->core_goal = goal; proto_rethink_goal(p); @@ -195,6 +197,25 @@ protos_start(void) } void +protos_shutdown(void) +{ + struct proto *p, *n; + + debug("Protocol shutdown\n"); + WALK_LIST_DELSAFE(p, n, inactive_proto_list) + if (p->core_state != FS_HUNGRY || p->proto_state != PS_DOWN) + { + proto_shutdown_counter++; + proto_set_goal(p, FS_HUNGRY); + } + WALK_LIST_DELSAFE(p, n, proto_list) + { + proto_shutdown_counter++; + proto_set_goal(p, FS_HUNGRY); + } +} + +void protos_dump_all(void) { struct proto *p; @@ -235,6 +256,8 @@ static void proto_fell_down(struct proto *p) { DBG("Protocol %s down\n", p->name); + if (!--proto_shutdown_counter) + protos_shutdown_notify(); proto_rethink_goal(p); } @@ -291,6 +314,7 @@ proto_notify_state(struct proto *p, unsigned ps) cs = FS_FLUSHING; ev_schedule(proto_flush_event); } + break; default: error: bug("Invalid state transition for %s from %s/%s to */%s", p->name, c_states[cs], p_states[ops], p_states[ps]); @@ -313,6 +337,6 @@ proto_flush_all(void *unused) p->pool = NULL; p->core_state = FS_HUNGRY; proto_relink(p); - proto_rethink_goal(p); + proto_fell_down(p); } } |