summaryrefslogtreecommitdiff
path: root/sysdep/unix/io-loop.c
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2021-11-30 18:16:49 +0100
committerMaria Matejka <mq@ucw.cz>2021-11-30 21:38:25 +0100
commit385b3ea3956aefc2868cdd838fc0a90f1d8a7857 (patch)
treed954b853724153e4a2411d57be5f29e5b9236251 /sysdep/unix/io-loop.c
parentab0994a10c26bd76b4154a675267d96d19dfb509 (diff)
For safer memory allocations, resources are bound to loops.
Also all loops have their basic resource pool for allocations which are auto-freed when the loop is stopping.
Diffstat (limited to 'sysdep/unix/io-loop.c')
-rw-r--r--sysdep/unix/io-loop.c72
1 files changed, 58 insertions, 14 deletions
diff --git a/sysdep/unix/io-loop.c b/sysdep/unix/io-loop.c
index c7cf4ad2..769f01ba 100644
--- a/sysdep/unix/io-loop.c
+++ b/sysdep/unix/io-loop.c
@@ -48,6 +48,12 @@ birdloop_time_loop(struct birdloop *loop)
return &loop->time;
}
+pool *
+birdloop_pool(struct birdloop *loop)
+{
+ return loop->pool;
+}
+
_Bool
birdloop_inside(struct birdloop *loop)
{
@@ -333,31 +339,59 @@ birdloop_init(void)
times_update();
timers_init(&main_birdloop.time, &root_pool);
+ root_pool.loop = &main_birdloop;
+
birdloop_enter_locked(&main_birdloop);
}
static void birdloop_main(void *arg);
+void
+birdloop_free(resource *r)
+{
+ struct birdloop *loop = (void *) r;
+
+ ASSERT_DIE(loop->links == 0);
+ domain_free(loop->time.domain);
+}
+
+void
+birdloop_dump(resource *r)
+{
+ struct birdloop *loop = (void *) r;
+
+ debug("%s\n", loop->pool->name);
+}
+
+struct resclass birdloop_class = {
+ .name = "IO Loop",
+ .size = sizeof(struct birdloop),
+ .free = birdloop_free,
+ .dump = birdloop_dump,
+};
+
struct birdloop *
birdloop_new(pool *pp, uint order, const char *name)
{
struct domain_generic *dg = domain_new(name, order);
- pool *p = rp_new(pp, name);
- struct birdloop *loop = mb_allocz(p, sizeof(struct birdloop));
- loop->pool = p;
+ struct birdloop *loop = ralloc(pp, &birdloop_class);
loop->time.domain = dg;
loop->time.loop = loop;
birdloop_enter(loop);
+ loop->pool = rp_new(pp, loop, name);
+ loop->parent = pp;
+ rmove(&loop->r, loop->pool);
+
wakeup_init(loop);
ev_init_list(&loop->event_list, loop, name);
- timers_init(&loop->time, p);
+ timers_init(&loop->time, loop->pool);
sockets_init(loop);
- loop->time.coro = coro_run(p, birdloop_main, loop);
+ loop->time.coro = coro_run(loop->pool, birdloop_main, loop);
birdloop_leave(loop);
@@ -389,14 +423,6 @@ birdloop_stop_self(struct birdloop *loop, void (*stopped)(void *data), void *dat
birdloop_do_stop(loop, stopped, data);
}
-void
-birdloop_free(struct birdloop *loop)
-{
- ASSERT_DIE(loop->links == 0);
- domain_free(loop->time.domain);
- rfree(loop->pool);
-}
-
static void
birdloop_enter_locked(struct birdloop *loop)
{
@@ -529,7 +555,25 @@ birdloop_main(void *arg)
ASSERT_DIE(loop->sock_num == 0);
birdloop_leave(loop);
+
+ /* Lock parent loop */
+ pool *parent = loop->parent;
+ birdloop_enter(parent->loop);
+
+ /* Move the loop temporarily to parent pool */
+ birdloop_enter(loop);
+ rmove(&loop->r, parent);
+ birdloop_leave(loop);
+
+ /* Announce loop stop */
loop->stopped(loop->stop_data);
-}
+ /* Free the pool and loop */
+ birdloop_enter(loop);
+ rp_free(loop->pool, parent);
+ birdloop_leave(loop);
+ rfree(&loop->r);
+ /* And finally leave the parent loop before finishing */
+ birdloop_leave(parent->loop);
+}