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:
parent
4f43d326b4
commit
a9efce68b5
42
nest/proto.c
42
nest/proto.c
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user