diff options
author | Egor Tensin <Egor.Tensin@gmail.com> | 2023-06-13 03:31:05 +0200 |
---|---|---|
committer | Egor Tensin <Egor.Tensin@gmail.com> | 2023-06-13 03:31:05 +0200 |
commit | 1c0481869fc680ea19627d8babec6de9a6784eb7 (patch) | |
tree | 47e75f13811f8dd943e82a30864b09faf1b6e2e4 | |
parent | README: update (diff) | |
download | cimple-1c0481869fc680ea19627d8babec6de9a6784eb7.tar.gz cimple-1c0481869fc680ea19627d8babec6de9a6784eb7.zip |
event_loop: add event_loop_add_once
-rw-r--r-- | src/command.c | 10 | ||||
-rw-r--r-- | src/command.h | 5 | ||||
-rw-r--r-- | src/event_loop.c | 45 | ||||
-rw-r--r-- | src/event_loop.h | 3 | ||||
-rw-r--r-- | src/worker.c | 9 |
5 files changed, 36 insertions, 36 deletions
diff --git a/src/command.c b/src/command.c index e3a7773..5d6aa19 100644 --- a/src/command.c +++ b/src/command.c @@ -181,8 +181,8 @@ free_ctx: return ret; } -static int cmd_dispatcher_handle_event(UNUSED struct event_loop *loop, int fd, short revents, - void *_dispatcher) +int cmd_dispatcher_handle_event(UNUSED struct event_loop *loop, int fd, short revents, + void *_dispatcher) { struct cmd_dispatcher *dispatcher = (struct cmd_dispatcher *)_dispatcher; struct msg *request = NULL, *response = NULL; @@ -222,9 +222,3 @@ free_ctx: return ret; } - -int cmd_dispatcher_add_to_event_loop(struct cmd_dispatcher *dispatcher, struct event_loop *loop, - int fd) -{ - return event_loop_add(loop, fd, POLLIN, cmd_dispatcher_handle_event, dispatcher); -} diff --git a/src/command.h b/src/command.h index 4ef245f..8daa912 100644 --- a/src/command.h +++ b/src/command.h @@ -29,8 +29,6 @@ void cmd_dispatcher_destroy(struct cmd_dispatcher *); int cmd_dispatcher_handle(const struct cmd_dispatcher *, const struct msg *command, struct msg **response); -int cmd_dispatcher_add_to_event_loop(struct cmd_dispatcher *, struct event_loop *, int fd); - struct cmd_conn_ctx { int fd; void *arg; @@ -39,4 +37,7 @@ struct cmd_conn_ctx { /* This is supposed to be used as an argument to tcp_server_accept. */ int cmd_dispatcher_handle_conn(int conn_fd, void *dispatcher); +/* This is supposed to be used as an argument to event_loop_add. */ +int cmd_dispatcher_handle_event(struct event_loop *, int fd, short revents, void *arg); + #endif diff --git a/src/event_loop.c b/src/event_loop.c index 1400235..b26d424 100644 --- a/src/event_loop.c +++ b/src/event_loop.c @@ -22,6 +22,7 @@ struct event_fd { short events; event_handler handler; void *arg; + int once; SIMPLEQ_ENTRY(event_fd) entries; }; @@ -38,6 +39,7 @@ static struct event_fd *event_fd_create(int fd, short events, event_handler hand res->events = events; res->handler = handler; res->arg = arg; + res->once = 0; return res; } @@ -90,18 +92,32 @@ void event_loop_destroy(struct event_loop *loop) free(loop); } -int event_loop_add(struct event_loop *loop, int fd, short events, event_handler handler, void *arg) +static void event_loop_add_internal(struct event_loop *loop, struct event_fd *entry) { - log("Adding descriptor %d to event loop\n", fd); - - struct event_fd *entry = event_fd_create(fd, events, handler, arg); - if (!entry) - return -1; + log("Adding descriptor %d to event loop\n", entry->fd); nfds_t nfds = loop->nfds + 1; SIMPLEQ_INSERT_TAIL(&loop->entries, entry, entries); loop->nfds = nfds; +} + +int event_loop_add(struct event_loop *loop, int fd, short events, event_handler handler, void *arg) +{ + struct event_fd *entry = event_fd_create(fd, events, handler, arg); + if (!entry) + return -1; + event_loop_add_internal(loop, entry); + return 0; +} +int event_loop_add_once(struct event_loop *loop, int fd, short events, event_handler handler, + void *arg) +{ + struct event_fd *entry = event_fd_create(fd, events, handler, arg); + if (!entry) + return -1; + entry->once = 1; + event_loop_add_internal(loop, entry); return 0; } @@ -195,18 +211,11 @@ int event_loop_run(struct event_loop *loop) /* Execute all handlers but notice if any of them fail. */ const int handler_ret = entry->handler(loop, fds[i].fd, fds[i].revents, entry->arg); - switch (handler_ret) { - case 0: - goto next; - case EVENT_LOOP_REMOVE: - goto remove; - default: - break; - } - - remove: - event_loop_remove(loop, entry); - goto next; + if (handler_ret < 0) + ret = handler_ret; + + if (entry->once) + event_loop_remove(loop, entry); next: entry = next; diff --git a/src/event_loop.h b/src/event_loop.h index 0e13b48..c08e84d 100644 --- a/src/event_loop.h +++ b/src/event_loop.h @@ -15,10 +15,9 @@ void event_loop_destroy(struct event_loop *); int event_loop_run(struct event_loop *); -#define EVENT_LOOP_REMOVE 1 - typedef int (*event_handler)(struct event_loop *, int fd, short revents, void *arg); int event_loop_add(struct event_loop *, int fd, short events, event_handler, void *arg); +int event_loop_add_once(struct event_loop *, int fd, short events, event_handler, void *arg); #endif diff --git a/src/worker.c b/src/worker.c index 8b2af56..725fad7 100644 --- a/src/worker.c +++ b/src/worker.c @@ -19,6 +19,7 @@ #include "run_queue.h" #include "signal.h" +#include <poll.h> #include <stdlib.h> #include <string.h> @@ -107,10 +108,6 @@ static int worker_handle_run(const struct msg *request, UNUSED struct msg **resp if (ret < 0) goto free_output; - /* Close the descriptor and remove it from the event loop. - * poll(2) is too confusing, honestly. */ - ret = EVENT_LOOP_REMOVE; - free_output: proc_output_free(&result); @@ -214,8 +211,8 @@ int worker_main(struct worker *worker) if (ret < 0) return ret; - ret = cmd_dispatcher_add_to_event_loop(worker->cmd_dispatcher, worker->event_loop, - fd); + ret = event_loop_add_once(worker->event_loop, fd, POLLIN, + cmd_dispatcher_handle_event, worker->cmd_dispatcher); if (ret < 0) return ret; |