From 087ca79bdb153eabd267cf224b22a1dd9cc5d068 Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Mon, 27 Jul 2020 19:16:53 +0200 Subject: [PATCH] daemon: handle epoll callback pointers sensibly The event can now carry userdata to point to the needed structure directly. No more "keep fd_entity in front of the struct" or offset calculating nonsense. Change-Id: I9d7d565d86538931f26a63ce35b6d0bb5947f228 Signed-off-by: Michal Bloch --- src/logger/logger.c | 37 ++++++++++++++++++++----------------- src/logger/logger_internal.h | 3 ++- src/tests/logger.c | 21 +++++++++++++-------- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/logger/logger.c b/src/logger/logger.c index 8382b46..b922c64 100644 --- a/src/logger/logger.c +++ b/src/logger/logger.c @@ -38,10 +38,10 @@ int service_writer_kmsg(struct logger* server, struct writer* wr, struct epoll_e int service_writer_syslog(struct logger* server, struct writer* wr, struct epoll_event* event); static int service_writer_handle_req_ctrl(struct logger *server, struct writer *wr, struct dlog_control_msg *msg); static int service_writer_handle_req_pipe(struct logger *server, struct writer *wr, struct dlog_control_msg *msg); -void dispatch_event_writer(struct logger *server, struct epoll_event *event); -void dispatch_event_sock(struct logger *server, struct epoll_event *event); -static void dispatch_event_reader_sink(struct logger *server, struct epoll_event *event); -static void dispatch_event_reader_source(struct logger *server, struct epoll_event *event); +void dispatch_event_writer(struct logger *server, struct epoll_event *event, void *userdata); +void dispatch_event_sock(struct logger *server, struct epoll_event *event, void *userdata); +static void dispatch_event_reader_sink(struct logger *server, struct epoll_event *event, void *userdata); +static void dispatch_event_reader_source(struct logger *server, struct epoll_event *event, void *userdata); void reader_free(struct reader* reader); static void logger_free(struct logger* l); int socket_initialize(struct sock_data *sock, struct log_buffer *buffer, service_socket_t service_socket, struct socket_config_data *data); @@ -309,8 +309,9 @@ void init_fd_entity(struct fd_entity *fd_entity, dispatch_event_t dispatch_event assert(fd_entity); *fd_entity = (struct fd_entity) { .dispatch_event = dispatch_event, + .dispatch_data = user_data, .event = (struct epoll_event) { - .data = (epoll_data_t) { .ptr = user_data }, + .data = (epoll_data_t) { .ptr = fd_entity }, .events = 0 }, .fd = -1 @@ -1728,10 +1729,11 @@ static bool cond_service_reader(void *ptr, void *user_data) * @param[in] event The received event * @param[in] offset The offset of the event fd entity into the reader struct */ -static void dispatch_event_reader_common(struct logger *server, struct epoll_event *event, size_t offset) +static void dispatch_event_reader_common(struct logger *server, struct epoll_event *event, void *userdata) { assert(event); - struct reader *reader = (struct reader *)(((char *)event->data.ptr) - offset); + struct reader *reader = (struct reader *) userdata; + assert(reader); if (event->events & (EPOLLHUP | EPOLLERR)) { if (reader->buf_ptr) @@ -1759,14 +1761,14 @@ static void dispatch_event_reader_common(struct logger *server, struct epoll_eve } } -static void dispatch_event_reader_sink(struct logger *server, struct epoll_event *event) +static void dispatch_event_reader_sink(struct logger *server, struct epoll_event *event, void *userdata) { - dispatch_event_reader_common(server, event, offsetof(struct reader, fd_entity_sink)); + dispatch_event_reader_common(server, event, userdata); } -static void dispatch_event_reader_source(struct logger *server, struct epoll_event *event) +static void dispatch_event_reader_source(struct logger *server, struct epoll_event *event, void *userdata) { - dispatch_event_reader_common(server, event, offsetof(struct reader, fd_entity_source)); + dispatch_event_reader_common(server, event, userdata); } /** @@ -1982,11 +1984,12 @@ static void logger_free(struct logger *l) * @param[in] server The logger server * @param[in] event The received event */ -void dispatch_event_writer(struct logger *server, struct epoll_event *event) +void dispatch_event_writer(struct logger *server, struct epoll_event *event, void *userdata) { assert(server); assert(event); - struct writer *writer = (struct writer*)event->data.ptr; + struct writer *writer = (struct writer*) userdata; + assert(writer); assert(writer->service_writer); int r = writer->service_writer(server, writer, event); @@ -2002,12 +2005,12 @@ void dispatch_event_writer(struct logger *server, struct epoll_event *event) * @param[in] server The logger server * @param[in] event The received event */ -void dispatch_event_sock(struct logger *server, struct epoll_event *event) +void dispatch_event_sock(struct logger *server, struct epoll_event *event, void *userdata) { assert(event); - struct sock_data const * const sock = (struct sock_data const * const) event->data.ptr; - + struct sock_data const *const sock = (struct sock_data const * const) userdata; assert(sock); + int sock_pipe = accept4(sock->fd_entity.fd, NULL, NULL, SOCK_NONBLOCK); if (sock_pipe < 0) { check_if_fd_limit_reached(server, errno); @@ -2070,7 +2073,7 @@ void dispatch_epoll_event(struct logger *server, struct epoll_event *event) { struct fd_entity *const entity = (struct fd_entity *) event->data.ptr; assert(entity->dispatch_event); - entity->dispatch_event(server, event); + entity->dispatch_event(server, event, entity->dispatch_data); } int handle_epoll_events(struct logger *server, struct epoll_metadata *metadata, int timeout) diff --git a/src/logger/logger_internal.h b/src/logger/logger_internal.h index 68150d4..5dcadb2 100644 --- a/src/logger/logger_internal.h +++ b/src/logger/logger_internal.h @@ -90,10 +90,11 @@ struct log_buffer; * @param[in] server The logger server * @param[in] event The received event */ -typedef void (*dispatch_event_t)(struct logger *server, struct epoll_event *event); +typedef void (*dispatch_event_t)(struct logger *server, struct epoll_event *event, void *userdata); struct fd_entity { dispatch_event_t dispatch_event; + void *dispatch_data; struct epoll_event event; int fd; }; diff --git a/src/tests/logger.c b/src/tests/logger.c index 0293221..eea9339 100644 --- a/src/tests/logger.c +++ b/src/tests/logger.c @@ -20,14 +20,14 @@ void init_fd_entity(struct fd_entity *fd_entity, dispatch_event_t dispatch_event void set_read_fd_entity(struct fd_entity *fd_entity, int fd); void set_write_fd_entity(struct fd_entity *fd_entity, int fd); int writer_create(struct writer **writer, int fd, struct log_buffer *log_buffer, service_writer_t service_writer, service_socket_t service_socket); -void dispatch_event_writer(struct logger *server, struct epoll_event *event); +void dispatch_event_writer(struct logger *server, struct epoll_event *event, void *userdata); int create_kmsg_writer(struct writer **writer, struct log_buffer *log_buffer); int service_writer_kmsg(struct logger *server, struct writer *wr, struct epoll_event *event); int create_syslog_writer(struct writer **writer, struct log_buffer *log_buffer); int service_writer_syslog(struct logger *server, struct writer *wr, struct epoll_event *event); int service_socket_dummy(struct logger *server, struct writer *wr, struct dlog_control_msg *msg); int socket_initialize(struct sock_data *sock, struct log_buffer *buffer, service_socket_t service_socket, struct socket_config_data *data); -void dispatch_event_sock(struct logger *server, struct epoll_event *event); +void dispatch_event_sock(struct logger *server, struct epoll_event *event, void *userdata); void socket_close(struct sock_data *sock); uint64_t reader_buffered_space(const struct reader *reader); int reader_is_bufferable(const struct reader *reader); @@ -616,7 +616,8 @@ int main() struct fd_entity ent; init_fd_entity(&ent, (dispatch_event_t)0xD159A7C8, (void *)0xDA7A); assert(ent.dispatch_event == (dispatch_event_t)0xD159A7C8); - assert(ent.event.data.ptr == (void *)0xDA7A); + assert(ent.dispatch_data == (void *)0xDA7A); + assert(ent.event.data.ptr == &ent); assert(ent.event.events == 0); assert(ent.fd == -1); @@ -643,7 +644,7 @@ int main() epoll_ctl_op_correct = EPOLL_CTL_ADD; epoll_ctl_fd_correct = 2; epoll_ctl_events_correct = EPOLLHUP; - epoll_ctl_data_correct = (void *)0xDA7A; + epoll_ctl_data_correct = &ent; epoll_ctl_errno = ELOOP; assert(add_fd_entity(&logger, &ent) == -ELOOP); assert(logger.epoll_common.cnt == 0); @@ -691,7 +692,8 @@ int main() closed[2] = false; assert(writer_create(&writer, 3, (struct log_buffer *)0xBU, (service_writer_t)17, (service_socket_t)18) == 0); assert(writer->fd_entity.dispatch_event == dispatch_event_writer); - assert(writer->fd_entity.event.data.ptr == writer); + assert(writer->fd_entity.dispatch_data == writer); + assert(writer->fd_entity.event.data.ptr == &writer->fd_entity); assert(writer->fd_entity.event.events == EPOLLIN); assert(writer->fd_entity.fd == 3); assert(writer->buf_ptr == (struct log_buffer *)0xBU); @@ -720,7 +722,8 @@ int main() closed[36] = false; assert(create_kmsg_writer(&writer, (struct log_buffer *)0x2BU) == 0); assert(writer->fd_entity.dispatch_event == dispatch_event_writer); - assert(writer->fd_entity.event.data.ptr == writer); + assert(writer->fd_entity.dispatch_data == writer); + assert(writer->fd_entity.event.data.ptr == &writer->fd_entity); assert(writer->fd_entity.event.events == EPOLLIN); assert(writer->fd_entity.fd == 37); assert(writer->buf_ptr == (struct log_buffer *)0x2BU); @@ -758,7 +761,8 @@ int main() closed[3] = false; assert(create_syslog_writer(&writer, (struct log_buffer *)0x3BU) == 0); assert(writer->fd_entity.dispatch_event == dispatch_event_writer); - assert(writer->fd_entity.event.data.ptr == writer); + assert(writer->fd_entity.dispatch_data == writer); + assert(writer->fd_entity.event.data.ptr == &writer->fd_entity); assert(writer->fd_entity.event.events == EPOLLIN); assert(writer->fd_entity.fd == 4); assert(writer->buf_ptr == (struct log_buffer *)0x3BU); @@ -784,7 +788,8 @@ int main() assert(socket_initialize(&sock, (struct log_buffer *)0x4BU, (service_socket_t)0x5E, &data) == 0); assert(!closed[11]); assert(sock.fd_entity.dispatch_event == dispatch_event_sock); - assert(sock.fd_entity.event.data.ptr == &sock); + assert(sock.fd_entity.dispatch_data == &sock); + assert(sock.fd_entity.event.data.ptr == &sock.fd_entity); assert(sock.fd_entity.event.events == EPOLLIN); assert(sock.fd_entity.fd == 12); assert(sock.buf_ptr == (struct log_buffer *)0x4BU); -- 2.7.4