0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-10 05:08: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)
{
struct channel_aux_table *cat;
RT_LOCKED((rtable *) data, t)
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;
if (channel_aux_imex(cat))
@ -685,7 +690,15 @@ static void
channel_aux_import_stopped(void *_cat)
{
struct channel_aux_table *cat = _cat;
cat->push.hook = NULL;
if (!cat->get.hook)
RT_LOCKED(cat->tab, t)
{
t->delete = channel_aux_stopped;
rt_unlock_table(t);
}
}
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);
req->hook = NULL;
int del;
RT_LOCKED(cat->tab, t)
del = !!t->delete;
if (cat->refeed_pending && !cat->stop_pending)
{
cat->refeed_pending = 0;
rt_request_export(cat->tab, req);
if (del)
return;
}
ASSERT_DIE(cat->refeed_pending);
cat->refeed_pending = 0;
rt_request_export(cat->tab, req);
if (!cat->push.hook)
RT_LOCKED(cat->tab, t)
{
t->delete = channel_aux_stopped;
rt_unlock_table(t);
}
}
static void
channel_aux_stop(struct channel_aux_table *cat)
{
ASSERT_DIE(!cat->stop_pending);
cat->stop_pending = 1;
RT_LOCKED(cat->tab, t)
t->delete = channel_aux_stopped;
rt_lock_table(t);
cat->push_stopped = (event) {
.hook = channel_aux_import_stopped,
@ -966,6 +987,9 @@ channel_setup_out_table(struct channel *c)
static void
channel_aux_request_refeed(struct channel_aux_table *cat)
{
if (cat->stop_pending)
return;
cat->refeed_pending = 1;
rt_stop_export(&cat->get, channel_aux_export_stopped);
}

View File

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