From 7eeda65cd9357d65c4f2b78464cbeaa238621adc Mon Sep 17 00:00:00 2001 From: Karchnu Date: Mon, 3 Aug 2020 00:42:34 +0200 Subject: [PATCH] libipc now allows buffered readings in switched context. --- src/communication.c | 23 +++++++++++++++++++---- src/ipc.h | 9 +++++---- src/network.c | 22 +++++++++++++--------- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/communication.c b/src/communication.c index eb20dc5..148a8bc 100644 --- a/src/communication.c +++ b/src/communication.c @@ -496,7 +496,7 @@ struct ipc_error ipc_wait_event (struct ipc_ctx *ctx, struct ipc_event *event, i IPC_EVENT_CLEAN (event); - int32_t n; + int32_t n = 0; for (size_t i = 0; i < ctx->size; i++) { // We assume that any fd in the list has to be listen to. @@ -519,7 +519,18 @@ struct ipc_error ipc_wait_event (struct ipc_ctx *ctx, struct ipc_event *event, i gettimeofday(&tv_1, NULL); - if ((n = poll(ctx->pollfd, ctx->size, *timer)) < 0) { + int timer_ = *timer; + + /* In case there is a file descriptor that requires more to read. */ + for (size_t i = 0; i <= ctx->size; i++) { + if (ctx->cinfos[i].more_to_read == 1) { + // printf ("There is more to read for _at least_ fd %d\n", ctx->pollfd[i].fd); + timer_ = 0; + break; + } + } + + if ((n = poll(ctx->pollfd, ctx->size, timer_)) < 0) { IPC_RETURN_ERROR (IPC_ERROR_WAIT_EVENT__POLL); } @@ -538,14 +549,18 @@ struct ipc_error ipc_wait_event (struct ipc_ctx *ctx, struct ipc_event *event, i } // Timeout. - if (n == 0) { + if (n == 0 && timer_ != 0) { IPC_EVENT_SET (event, IPC_EVENT_TYPE_TIMER, 0, 0, NULL); IPC_RETURN_NO_ERROR; } for (size_t i = 0; i <= ctx->size; i++) { // Something to read or connection. - if (ctx->pollfd[i].revents & POLLIN) { + if (ctx->pollfd[i].revents & POLLIN || ctx->cinfos[i].more_to_read == 1) { + + // Avoiding loops. + ctx->cinfos[i].more_to_read = 0; + // In case there is something to read for the server socket: new client. if (ctx->cinfos[i].type == IPC_CONNECTION_TYPE_SERVER) { return ipc_accept_add (event, ctx, i); diff --git a/src/ipc.h b/src/ipc.h index 05ab2f9..e9863fc 100644 --- a/src/ipc.h +++ b/src/ipc.h @@ -231,6 +231,7 @@ enum ipc_connection_type { struct ipc_connection_info { enum ipc_connection_type type; + short int more_to_read; char *spath; // max size: PATH_MAX }; @@ -250,9 +251,9 @@ struct ipc_messages { struct ipc_switching { int orig; int dest; - enum ipccb (*orig_in) (int origin_fd, struct ipc_message *m); + enum ipccb (*orig_in) (int origin_fd, struct ipc_message *m, short int *more_to_read); enum ipccb (*orig_out) (int origin_fd, struct ipc_message *m); - enum ipccb (*dest_in) (int origin_fd, struct ipc_message *m); + enum ipccb (*dest_in) (int origin_fd, struct ipc_message *m, short int *more_to_read); enum ipccb (*dest_out) (int origin_fd, struct ipc_message *m); }; @@ -404,11 +405,11 @@ int ipc_switching_del (struct ipc_switchings *is, int fd); int ipc_switching_get (struct ipc_switchings *is, int fd); void ipc_switching_free (struct ipc_switchings *is); void ipc_switching_callbacks_ (struct ipc_ctx *ctx, int fd - , enum ipccb (*cb_in )(int fd, struct ipc_message *m)); + , enum ipccb (*cb_in )(int fd, struct ipc_message *m, short int *more_to_read)); void ipc_switching_callbacks ( struct ipc_ctx *ctx , int fd - , enum ipccb (*cb_in )(int fd, struct ipc_message *m) + , enum ipccb (*cb_in )(int fd, struct ipc_message *m, short int *more_to_read) , enum ipccb (*cb_out)(int fd, struct ipc_message *m)); int ipc_ctx_fd_type (struct ipc_ctx *ctx, int fd, enum ipc_connection_type type); diff --git a/src/network.c b/src/network.c index 60aee61..bca2fe2 100644 --- a/src/network.c +++ b/src/network.c @@ -197,9 +197,10 @@ void ipc_switching_free (struct ipc_switchings *is) } enum ipccb -default_cb_in(int fd, struct ipc_message *m) +default_cb_in(int fd, struct ipc_message *m, short int *more_to_read) { - // TODO: fix buffer size for switching messages + *more_to_read = 0; + size_t msize = IPC_MAX_MESSAGE_SIZE; SECURE_BUFFER_DECLARATION (char, buf, msize); char *pbuf = buf; @@ -251,7 +252,7 @@ default_cb_out(int fd, struct ipc_message *m) } void ipc_switching_callbacks_ (struct ipc_ctx *ctx, int fd - , enum ipccb (*cb_in )(int fd, struct ipc_message *m)) + , enum ipccb (*cb_in )(int fd, struct ipc_message *m, short int *more_to_read)) { ipc_switching_callbacks (ctx, fd, cb_in, NULL); } @@ -259,7 +260,7 @@ void ipc_switching_callbacks_ (struct ipc_ctx *ctx, int fd void ipc_switching_callbacks ( struct ipc_ctx *ctx , int fd - , enum ipccb (*cb_in )(int fd, struct ipc_message *m) + , enum ipccb (*cb_in )(int fd, struct ipc_message *m, short int *more_to_read) , enum ipccb (*cb_out)(int fd, struct ipc_message *m)) { struct ipc_switching *sw = NULL; @@ -297,6 +298,7 @@ struct ipc_error fd_switching_read (struct ipc_event *event, struct ipc_ctx *ctx enum ipccb r; int is_valid = 0; + short int more_to_read = 0; is_valid = ipc_switching_get_ (&ctx->switchdb, talkingfd, &sw); @@ -305,22 +307,24 @@ struct ipc_error fd_switching_read (struct ipc_event *event, struct ipc_ctx *ctx if (sw->orig == talkingfd) { dest_fd = sw->dest; if (sw->orig_in == NULL) { - r = default_cb_in (talkingfd, &m); + r = default_cb_in (talkingfd, &m, &more_to_read); } else { - r = (*sw->orig_in)(talkingfd, &m); + r = (*sw->orig_in)(talkingfd, &m, &more_to_read); } } else { dest_fd = sw->orig; if (sw->dest_in == NULL) { - r = default_cb_in (talkingfd, &m); + r = default_cb_in (talkingfd, &m, &more_to_read); } else { - r = (*sw->dest_in)(talkingfd, &m); + r = (*sw->dest_in)(talkingfd, &m, &more_to_read); } } + ctx->cinfos[index].more_to_read = more_to_read; + // Message reception OK: reading the message and put it in the list of messages to send. if (r == IPC_CB_NO_ERROR) { // In case of message reception: @@ -339,7 +343,7 @@ struct ipc_error fd_switching_read (struct ipc_event *event, struct ipc_ctx *ctx // This is applied to protocol-specific messages, for example when the client // has to communicate with the proxy, not the service. if (r == IPC_CB_IGNORE) { - printf ("IGNORING REQUEST\n"); + // printf ("IGNORING REQUEST\n"); // In case of message reception: // 1. set event IPC_EVENT_TYPE_SWITCH, inform ipcd of a successful reception. IPC_EVENT_SET (event, IPC_EVENT_TYPE_SWITCH, index, ctx->pollfd[index].fd, NULL);