0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-13 22:58:42 +00:00

Fixed a race condition in channel aux table cleanup

This commit is contained in:
Maria Matejka 2021-12-07 12:47:42 +01:00
parent 4f43d326b4
commit a9efce68b5
2 changed files with 33 additions and 8 deletions

View File

@ -667,9 +667,14 @@ static void
channel_aux_stopped(void *data) channel_aux_stopped(void *data)
{ {
struct channel_aux_table *cat; struct channel_aux_table *cat;
RT_LOCKED((rtable *) data, t) RT_LOCKED((rtable *) data, t)
cat = t->config->owner; cat = t->config->owner;
ASSERT_DIE(cat->push.hook == NULL);
ASSERT_DIE(cat->get.hook == NULL);
ASSERT_DIE(cat->stop_pending);
struct channel *c = cat->c; struct channel *c = cat->c;
if (channel_aux_imex(cat)) if (channel_aux_imex(cat))
@ -685,7 +690,15 @@ static void
channel_aux_import_stopped(void *_cat) channel_aux_import_stopped(void *_cat)
{ {
struct channel_aux_table *cat = _cat; struct channel_aux_table *cat = _cat;
cat->push.hook = NULL; cat->push.hook = NULL;
if (!cat->get.hook)
RT_LOCKED(cat->tab, t)
{
t->delete = channel_aux_stopped;
rt_unlock_table(t);
}
} }
static void static void
@ -694,23 +707,31 @@ channel_aux_export_stopped(struct rt_export_request *req)
struct channel_aux_table *cat = SKIP_BACK(struct channel_aux_table, get, req); struct channel_aux_table *cat = SKIP_BACK(struct channel_aux_table, get, req);
req->hook = NULL; req->hook = NULL;
int del; if (cat->refeed_pending && !cat->stop_pending)
RT_LOCKED(cat->tab, t) {
del = !!t->delete;
if (del)
return;
ASSERT_DIE(cat->refeed_pending);
cat->refeed_pending = 0; cat->refeed_pending = 0;
rt_request_export(cat->tab, req); rt_request_export(cat->tab, req);
return;
}
if (!cat->push.hook)
RT_LOCKED(cat->tab, t)
{
t->delete = channel_aux_stopped;
rt_unlock_table(t);
}
} }
static void static void
channel_aux_stop(struct channel_aux_table *cat) channel_aux_stop(struct channel_aux_table *cat)
{ {
ASSERT_DIE(!cat->stop_pending);
cat->stop_pending = 1;
RT_LOCKED(cat->tab, t) RT_LOCKED(cat->tab, t)
t->delete = channel_aux_stopped; rt_lock_table(t);
cat->push_stopped = (event) { cat->push_stopped = (event) {
.hook = channel_aux_import_stopped, .hook = channel_aux_import_stopped,
@ -966,6 +987,9 @@ channel_setup_out_table(struct channel *c)
static void static void
channel_aux_request_refeed(struct channel_aux_table *cat) channel_aux_request_refeed(struct channel_aux_table *cat)
{ {
if (cat->stop_pending)
return;
cat->refeed_pending = 1; cat->refeed_pending = 1;
rt_stop_export(&cat->get, channel_aux_export_stopped); rt_stop_export(&cat->get, channel_aux_export_stopped);
} }

View File

@ -572,6 +572,7 @@ struct channel_aux_table {
rtable *tab; rtable *tab;
event *stop; event *stop;
u8 refeed_pending; u8 refeed_pending;
u8 stop_pending;
}; };
/* /*