summaryrefslogtreecommitdiff
path: root/nest/proto.c
diff options
context:
space:
mode:
Diffstat (limited to 'nest/proto.c')
-rw-r--r--nest/proto.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/nest/proto.c b/nest/proto.c
index a18d9332..341581ab 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -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);
}