diff options
author | David Härdeman <david@hardeman.nu> | 2020-06-10 22:53:42 +0200 |
---|---|---|
committer | David Härdeman <david@hardeman.nu> | 2020-06-10 22:53:42 +0200 |
commit | fd80ac9b3ea3c6e213236e27ae8b73856d2a5158 (patch) | |
tree | 427ab05ca9d0e50099787d89aedb98a374f2d217 | |
parent | 5e314fd0ebe500d3ba396a09c8984627beff2f37 (diff) |
Improve refcounting
-rw-r--r-- | announce.c | 5 | ||||
-rw-r--r-- | cfgdir.c | 4 | ||||
-rw-r--r-- | idle.c | 6 | ||||
-rw-r--r-- | main.c | 12 | ||||
-rw-r--r-- | main.h | 12 | ||||
-rw-r--r-- | proxy.c | 12 | ||||
-rw-r--r-- | rcon.c | 29 | ||||
-rw-r--r-- | server.c | 9 | ||||
-rw-r--r-- | uring.c | 53 | ||||
-rw-r--r-- | uring.h | 4 |
10 files changed, 99 insertions, 47 deletions
@@ -78,7 +78,6 @@ announce_cb(struct cfg *cfg, struct uring_task *task, int res) if (task->dead) { fprintf(stderr, "%s: task is dead\n", __func__); - uring_task_put(cfg, task); return; } @@ -118,8 +117,8 @@ announce_delete(struct cfg *cfg) } fprintf(stderr, "%s called, closing fd %i\n", __func__, cfg->aev->task.fd); - uring_cancel(cfg, &cfg->aev->task); - uring_task_put(cfg, &cfg->aev->mcast_task); + uring_task_destroy(cfg, &cfg->aev->mcast_task); + uring_task_destroy(cfg, &cfg->aev->task); cfg->aev = NULL; } @@ -289,7 +289,6 @@ inotify_free(struct uring_task *task) xfree(iev); cfg->iev = NULL; - uring_task_put(cfg, &cfg->task); } static void @@ -346,7 +345,6 @@ inotify_cb(struct cfg *cfg, struct uring_task *task, int res) if (task->dead) { fprintf(stderr, "%s: task is dead\n", __func__); - uring_task_put(cfg, task); return; } @@ -398,7 +396,7 @@ cfgdir_delete(struct cfg *cfg) } fprintf(stderr, "%s called, closing fd %i\n", __func__, cfg->iev->task.fd); - uring_cancel(cfg, &cfg->iev->task); + uring_task_destroy(cfg, &cfg->iev->task); cfg->iev = NULL; } @@ -376,7 +376,6 @@ idle_cb(struct cfg *cfg, struct uring_task *task, int res) if (task->dead) { fprintf(stderr, "%s: task is dead\n", __func__); - uring_task_put(cfg, task); return; } @@ -422,9 +421,8 @@ idle_delete(struct cfg *cfg, struct server *server) return; fprintf(stderr, "%s called, closing fd %i\n", __func__, idle->task.fd); - uring_cancel(cfg, &idle->task); - uring_task_put(cfg, &idle->task); - uring_task_put(cfg, &idle->idlecheck); + uring_task_destroy(cfg, &idle->idlecheck); + uring_task_destroy(cfg, &idle->task); server->idle = NULL; } @@ -184,6 +184,11 @@ signalfd_read(struct cfg *cfg, struct uring_task *task, int res) struct server *server, *stmp; static int count = 0; + if (task->dead) { + fprintf(stderr, "%s: task dead\n", __func__); + return; + } + count++; if (count > 5) exit(EXIT_FAILURE); @@ -197,14 +202,17 @@ signalfd_read(struct cfg *cfg, struct uring_task *task, int res) } else { fprintf(stderr, "Got a signal to dump tree\n"); dump_tree(cfg); + uring_task_put(cfg, &sev->task); announce_delete(cfg); cfgdir_delete(cfg); list_for_each_entry_safe(server, stmp, &cfg->servers, list) server_delete(cfg, server); fprintf(stderr, "%s: putting sev task 0x%p\n", __func__, &sev->task); - uring_task_put(cfg, &sev->task); - //uring_read(cfg, &sev->task, &sev->buf, sizeof(sev->buf), signalfd_read); + uring_delete(cfg); + return; } + + uring_read(cfg, &sev->task, &sev->buf, sizeof(sev->buf), signalfd_read); } static int hack_efd = -1; @@ -34,15 +34,15 @@ struct uring_task_buf { struct uring_task { const char *name; - unsigned refcount; + unsigned refcount; int fd; - void *parent; - void (*free)(struct uring_task *); + struct uring_task *parent; + void (*free)(struct uring_task *); bool dead; struct uring_task_buf *tbuf; - callback_t callback; - rcallback_t complete_callback; /* to check if tbuf processing is done */ - callback_t final_callback; /* once tbuf processing is done */ + callback_t callback; + rcallback_t complete_callback; /* to check if tbuf processing is done */ + callback_t final_callback; /* once tbuf processing is done */ }; struct cfg { @@ -103,15 +103,9 @@ proxy_delete(struct cfg *cfg, struct server_proxy *proxy) fprintf(stderr, "%s: shutting down proxy 0x%p\n", __func__, proxy); /* FIXME: review half-open proxy situation */ - if (proxy->servertask.fd >= 0) - uring_cancel(cfg, &proxy->servertask); - - if (proxy->clienttask.fd >= 0) - uring_cancel(cfg, &proxy->clienttask); - - uring_task_put(cfg, &proxy->servertask); - uring_task_put(cfg, &proxy->clienttask); - uring_task_put(cfg, &proxy->task); + uring_task_destroy(cfg, &proxy->servertask); + uring_task_destroy(cfg, &proxy->clienttask); + uring_task_destroy(cfg, &proxy->task); } static void proxy_client_data_in(struct cfg *cfg, struct uring_task *task, int res); @@ -52,9 +52,7 @@ rcon_delete(struct cfg *cfg, struct server *server) return; fprintf(stderr, "%s called, closing fd %i\n", __func__, rcon->task.fd); - uring_cancel(cfg, &rcon->task); - /* FIXME: Won't the refcount be wrong? */ - uring_task_put(cfg, &rcon->task); + uring_task_destroy(cfg, &rcon->task); server->rcon = NULL; } @@ -213,6 +211,11 @@ rcon_stop_reply(struct cfg *cfg, struct uring_task *task, int res) char *msg; fprintf(stderr, "%s: result %i\n", __func__, res); + if (task->dead) { + fprintf(stderr, "%s: task dead\n", __func__); + return; + } + if (res < 0) goto out; @@ -237,6 +240,11 @@ rcon_stop_sent(struct cfg *cfg, struct uring_task *task, int res) struct rcon *rcon = container_of(task, struct rcon, task); fprintf(stderr, "%s: result %i\n", __func__, res); + if (task->dead) { + fprintf(stderr, "%s: task dead\n", __func__); + return; + } + if (res < 0) { uring_task_put(cfg, &rcon->task); return; @@ -255,6 +263,11 @@ rcon_login_reply(struct cfg *cfg, struct uring_task *task, int res) char *msg; fprintf(stderr, "%s: result %i\n", __func__, res); + if (task->dead) { + fprintf(stderr, "%s: task dead\n", __func__); + return; + } + if (res < 0) goto out; @@ -286,6 +299,11 @@ rcon_login_sent(struct cfg *cfg, struct uring_task *task, int res) struct rcon *rcon = container_of(task, struct rcon, task); fprintf(stderr, "%s: result %i\n", __func__, res); + if (task->dead) { + fprintf(stderr, "%s: task dead\n", __func__); + return; + } + if (res < 0) { uring_task_put(cfg, &rcon->task); return; @@ -303,6 +321,11 @@ rcon_connected(struct cfg *cfg, struct uring_task *task, int res) struct rcon *rcon = container_of(task, struct rcon, task); fprintf(stderr, "%s: connected %i\n", __func__, res); + if (task->dead) { + fprintf(stderr, "%s: task dead\n", __func__); + return; + } + if (res < 0) { rcon_connect_next_rcon(cfg, rcon); return; @@ -89,7 +89,7 @@ server_delete(struct cfg *cfg, struct server *scfg) rcon_delete(cfg, scfg); list_for_each_entry_safe(local, ltmp, &scfg->locals, list) - uring_cancel(cfg, &local->task); + uring_task_destroy(cfg, &local->task); list_for_each_entry_safe(proxy, ptmp, &scfg->proxys, list) proxy_delete(cfg, proxy); @@ -106,7 +106,7 @@ server_delete(struct cfg *cfg, struct server *scfg) uring_poll_cancel(cfg, &scfg->exec_task); uring_task_put(cfg, &scfg->exec_task); - uring_task_put(cfg, &scfg->task); + uring_task_destroy(cfg, &scfg->task); } void @@ -183,7 +183,6 @@ server_local_accept(struct cfg *cfg, struct uring_task *task, int res) if (task->dead) { fprintf(stderr, "Task dead!\n"); - uring_task_put(cfg, task); return; } @@ -269,8 +268,10 @@ server_exec_done(struct cfg *cfg, struct uring_task *task, int res) int r; siginfo_t info; - if (task->dead) + if (task->dead) { + /* Should we leave child processes running? */ goto out; + } if (!(res & POLLIN)) { fprintf(stderr, "%s: unexpected result: %i\n", __func__, res); @@ -64,6 +64,32 @@ uring_task_refdump(struct uring_task *task) task->refcount); } +static void +uring_cancel(struct cfg *cfg, struct uring_task *task) +{ + struct io_uring_sqe *sqe = get_sqe(cfg); + + io_uring_prep_cancel(sqe, task, 0); + io_uring_sqe_set_data(sqe, NULL); +} + +/* + * Similar to uring_task_put, but can be called from other tasks + * while the task is active. + */ +void +uring_task_destroy(struct cfg *cfg, struct uring_task *task) +{ + fprintf(stderr, "%s: called with task %s (%p), fd %i and refcount %u\n", + __func__, task->name, task, task->fd, task->refcount); + + if (task->fd >= 0) + uring_cancel(cfg, task); + + task->dead = true; + uring_task_put(cfg, task); +} + void uring_task_put(struct cfg *cfg, struct uring_task *task) { @@ -85,6 +111,10 @@ uring_task_put(struct cfg *cfg, struct uring_task *task) return; } + if (parent) + fprintf(stderr, "%s: task %s (%p) putting parent %s (%p)\n", + __func__, task->name, task, task->parent->name, task->parent); + if (task->free) task->free(task); @@ -163,8 +193,11 @@ uring_task_init(struct uring_task *task, const char *name, task->name = name; task->tbuf = NULL; - if (task->parent) + if (task->parent) { + fprintf(stderr, "%s: task %s (%p) getting parent %s (%p)\n", + __func__, task->name, task, task->parent->name, task->parent); uring_task_get(NULL, task->parent); + } } void @@ -432,7 +465,7 @@ uring_poll_cancel(struct cfg *cfg, struct uring_task *task) struct io_uring_sqe *sqe; if (task->fd < 0) { - error("uring_poll_cancel called with no fd set\n"); + fprintf(stderr, "uring_poll_cancel called with no fd set\n"); return; } @@ -442,16 +475,6 @@ uring_poll_cancel(struct cfg *cfg, struct uring_task *task) io_uring_sqe_set_data(sqe, NULL); } -void -uring_cancel(struct cfg *cfg, struct uring_task *task) -{ - struct io_uring_sqe *sqe = get_sqe(cfg); - - task->dead = true; - io_uring_prep_cancel(sqe, task, 0); - io_uring_sqe_set_data(sqe, NULL); -} - static void uring_free(struct uring_task *task) { @@ -471,6 +494,12 @@ uring_refdump(struct uring_ev *uev) } void +uring_delete(struct cfg *cfg) +{ + uring_task_put(cfg, &cfg->uev->task); +} + +void uring_init(struct cfg *cfg) { struct uring_ev *uev; @@ -3,6 +3,8 @@ void uring_task_refdump(struct uring_task *task); +void uring_task_destroy(struct cfg *cfg, struct uring_task *task); + void uring_task_put(struct cfg *cfg, struct uring_task *task); void uring_task_get(struct cfg *cfg, struct uring_task *task); @@ -61,7 +63,7 @@ void uring_poll(struct cfg *cfg, struct uring_task *task, short poll_mask, void uring_poll_cancel(struct cfg *cfg, struct uring_task *task); -void uring_cancel(struct cfg *cfg, struct uring_task *task); +void uring_delete(struct cfg *cfg); void uring_refdump(struct uring_ev *uev); |