From: Maria Matejka Date: Fri, 24 Nov 2023 11:19:44 +0000 (+0100) Subject: Channels now can have external obstacles temporarily blocking their shutdown X-Git-Tag: v3.0.0~317 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f0da632b3c406c6c39a582e7a353737d90d16117;p=thirdparty%2Fbird.git Channels now can have external obstacles temporarily blocking their shutdown --- diff --git a/nest/proto.c b/nest/proto.c index 72d94a282..6427afcd2 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -745,7 +745,7 @@ channel_check_stopped(struct channel *c) switch (c->channel_state) { case CS_STOP: - if (!EMPTY_LIST(c->roa_subscriptions) || c->out_req.hook || c->refeed_req.hook || c->in_req.hook || c->reload_req.hook) + if (c->obstacles || !EMPTY_LIST(c->roa_subscriptions) || c->out_req.hook || c->refeed_req.hook || c->in_req.hook || c->reload_req.hook) return; channel_set_state(c, CS_DOWN); @@ -753,7 +753,7 @@ channel_check_stopped(struct channel *c) break; case CS_PAUSE: - if (!EMPTY_LIST(c->roa_subscriptions) || c->out_req.hook || c->refeed_req.hook || c->reload_req.hook) + if (c->obstacles || !EMPTY_LIST(c->roa_subscriptions) || c->out_req.hook || c->refeed_req.hook || c->reload_req.hook) return; channel_set_state(c, CS_START); @@ -763,6 +763,19 @@ channel_check_stopped(struct channel *c) DBG("%s.%s: Channel requests/hooks stopped (in state %s)\n", c->proto->name, c->name, c_states[c->channel_state]); } +void +channel_add_obstacle(struct channel *c) +{ + c->obstacles++; +} + +void +channel_del_obstacle(struct channel *c) +{ + if (!--c->obstacles) + channel_check_stopped(c); +} + void channel_import_stopped(struct rt_import_request *req) { diff --git a/nest/protocol.h b/nest/protocol.h index 9b8b837d1..4c983ffc9 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -605,6 +605,8 @@ struct channel { u8 gr_lock; /* Graceful restart mechanism should wait for this channel */ u8 gr_wait; /* Route export to channel is postponed until graceful restart */ + u32 obstacles; /* External obstacles remaining before cleanup */ + btime last_state_change; /* Time of last state transition */ struct rt_export_request reload_req; /* Feeder for import reload */ @@ -692,6 +694,9 @@ void channel_set_state(struct channel *c, uint state); void channel_schedule_reload(struct channel *c, struct channel_import_request *cir); int channel_import_request_prefilter(struct channel_import_request *cir_head, const net_addr *n); +void channel_add_obstacle(struct channel *c); +void channel_del_obstacle(struct channel *c); + static inline void channel_init(struct channel *c) { channel_set_state(c, CS_START); } static inline void channel_open(struct channel *c) { channel_set_state(c, CS_UP); } static inline void channel_close(struct channel *c) { channel_set_state(c, CS_STOP); }