diff --git a/src/communication.c b/src/communication.c index 6df0f17..892b807 100644 --- a/src/communication.c +++ b/src/communication.c @@ -421,3 +421,52 @@ struct ipc_error ipc_wait_event (struct ipc_ctx *ctx, struct ipc_event *event, i if ((n = poll(ctx->pollfd, ctx->size, *timer)) < 0) { IPC_RETURN_ERROR (IPC_ERROR_WAIT_EVENT__POLL); } + + gettimeofday(&tv_2, NULL); + + int nb_sec_ms = (tv_2.tv_sec - tv_1.tv_sec) * 1000; + int nb_usec_ms = (tv_2.tv_usec - tv_1.tv_usec) / 1000; + int time_elapsed_ms = (nb_sec_ms + nb_usec_ms); + + // Handle memory fuckery, 'cause low level programming is fun. + if (time_elapsed_ms >= *timer) { + *timer = 0; + } + else { + *timer -= time_elapsed_ms; + } + + // Timeout. + if (n == 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) { + // 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); + } + + return handle_new_message (event, ctx, i); + } + + // Something can be sent. + if (ctx->pollfd[i].revents & POLLOUT) { + ctx->pollfd[i].events &= ~POLLOUT; + return handle_writing_message (event, ctx, i); + } + + // Disconnection. + if (ctx->pollfd[i].revents & POLLHUP) { + /** IPC_EVENT_SET: event, type, index, fd, message */ + IPC_EVENT_SET (event, IPC_EVENT_TYPE_DISCONNECTION, i, ctx->pollfd[i].fd, NULL); + return ipc_close (ctx, i); + } + + } /** for loop: end of the message handling */ + + IPC_RETURN_NO_ERROR; +} diff --git a/src/error.c b/src/error.c index a26e7ec..7c831cc 100644 --- a/src/error.c +++ b/src/error.c @@ -140,6 +140,7 @@ static struct ipc_errors_verbose ipc_errors_verbose[] = { , {IPC_ERROR_MESSAGE_DEL__EMPTY_LIST, "IPC_ERROR_MESSAGE_DEL__EMPTY_LIST"} , {IPC_ERROR_ADD__NO_PARAM_POLLFD, "IPC_ERROR_ADD__NO_PARAM_POLLFD"} , {IPC_ERROR_WRITE__FD_NOT_FOUND, "IPC_ERROR_WRITE__FD_NOT_FOUND"} + , {IPC_ERROR_FD_SWITCHING__NO_FD_RECORD, "IPC_ERROR_FD_SWITCHING__NO_FD_RECORD"} }; const char *ipc_errors_get (enum ipc_error_code e) diff --git a/src/ipc.h b/src/ipc.h index c1922b2..231a5b1 100644 --- a/src/ipc.h +++ b/src/ipc.h @@ -194,6 +194,7 @@ enum ipc_error_code { , IPC_ERROR_WRITE__FD_NOT_FOUND = 104 , IPC_ERROR_ADD__NOT_ENOUGH_MEMORY = 105 , IPC_ERROR_WAIT_EVENT__POLL = 106 + , IPC_ERROR_FD_SWITCHING__NO_FD_RECORD = 107 }; struct ipc_error { @@ -201,20 +202,6 @@ struct ipc_error { char error_message[BUFSIZ]; }; -struct ipc_switching { - int orig; - int dest; - int (*orig_in) (int origin_fd, struct message *m); - int (*orig_out) (int origin_fd, struct message *m); - int (*dest_in) (int origin_fd, struct message *m); - int (*dest_out) (int origin_fd, struct message *m); -}; - -struct ipc_switchings { - struct ipc_switching *collection; - size_t size; -}; - // get explanation about an error // This only returns the generic error based on its code. // Library's users have a more meaningful insight on the error @@ -239,6 +226,20 @@ struct ipc_messages { size_t size; }; +struct ipc_switching { + int orig; + int dest; + int (*orig_in) (int origin_fd, struct ipc_message *m); + int (*orig_out) (int origin_fd, struct ipc_message *m); + int (*dest_in) (int origin_fd, struct ipc_message *m); + int (*dest_out) (int origin_fd, struct ipc_message *m); +}; + +struct ipc_switchings { + struct ipc_switching *collection; + size_t size; +}; + struct ipc_error ipc_messages_del (struct ipc_messages *messages, uint32_t index); /** diff --git a/src/network.c b/src/network.c index 95b47af..50a246e 100644 --- a/src/network.c +++ b/src/network.c @@ -231,4 +231,6 @@ struct ipc_error fd_switching (struct ipc_event *event, struct ipc_ctx *ctx, int IPC_EVENT_SET (event, IPC_EVENT_TYPE_DISCONNECTION, index, talkingfd, NULL); IPC_RETURN_ERROR (IPC_ERROR_CLOSED_RECIPIENT); } + + IPC_RETURN_NO_ERROR; }