diff options
Diffstat (limited to 'plop.c')
-rw-r--r-- | plop.c | 73 |
1 files changed, 34 insertions, 39 deletions
@@ -3,10 +3,10 @@ #include <errno.h> #include <fcntl.h> #include <netdb.h> -#include <poll.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/epoll.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> @@ -113,29 +113,19 @@ int load_handler(lua_State * L, const char * path) return LUA_OK; } -/// Progresses the connection for a client and shifts it back in the array. -/// `pfd` must be at least `shift_by + 1`-th element of the array. +/// Handles client events. /// \param L Server's Lua state -/// \param pfd Element in array processed by poll -/// \param request Pointer to request context associated with current client -/// \param shift_by Element will be moved by in array this many indices -/// \return Shift value for next handler -/// \see poll(2) -int handle_client(lua_State * L, struct pollfd * pfd, struct request ** request, const int shift_by) +/// \param event Event for client +/// \return -1 if an error occured +int handle_client(lua_State * L, struct epoll_event * event) { - if (0 == pfd->revents) - { - return shift_by; - } - - if (~(POLLIN | POLLOUT) & pfd->revents) - { - return -1; // TODO: Handle errors properly - } + // TODO: Temporary shenanigans to avoid too much changes. + struct request * r = (struct request *) event->data.ptr; + struct request ** request = &r; - if (-1 == parse_request(L, pfd->fd, request)) + if (-1 == parse_request(L, (*request)->fd, request)) { - respond_only_status(pfd->fd, STATUS_BAD_REQUEST); + respond_only_status((*request)->fd, STATUS_BAD_REQUEST); return -1; // TODO: Handle errors properly } @@ -149,16 +139,14 @@ int handle_client(lua_State * L, struct pollfd * pfd, struct request ** request, if (NULL != body) { - respond_with_body(pfd->fd, STATUS_OK, body, (int) length); + respond_with_body((*request)->fd, STATUS_OK, body, (int) length); } else { - respond_only_status(pfd->fd, STATUS_INTERNAL_SERVER_ERROR); + respond_only_status((*request)->fd, STATUS_INTERNAL_SERVER_ERROR); } - close(pfd->fd); - (pfd - shift_by)->fd = -1; - (pfd - shift_by)->events = pfd->events; + close((*request)->fd); if (NULL != *request) { @@ -166,32 +154,39 @@ int handle_client(lua_State * L, struct pollfd * pfd, struct request ** request, *request = NULL; } - return shift_by + 1; + return 0; } /// Accepts awaiting connections if any. -/// \param fdv Array of descriptors for poll -/// \param fdc Number of valid descriptors in the array including the server -/// \param size Size limit for the array -/// \return Number of valid descriptors in the array or -1 if an error occurred. -/// \see poll(2) -int handle_server(struct pollfd * fdv, int fdc, const int size) +/// \param L Server's Lua state +/// \param efd File descriptor for epoll's context +/// \param server File descriptor for server socket +/// \return -1 if an error occured +int handle_server(lua_State * L, const int efd, const int server) { - if (0 == fdv[0].revents) + struct epoll_event e; + e.events = EPOLLIN; // TODO: Add EPOLLOUT? + + const int client = accept(server, NULL, NULL); + if (-1 == client) { - return fdc; + return -1; // TODO: Consider not crashing entire server because of one accept. } - while (size > fdc + 1 && -1 != (fdv[fdc].fd = accept(fdv[0].fd, NULL, NULL))) + // TODO: Request is not the enitre state of the client. Make them distinct along with responses. + struct request * request = new_request(L); + if (NULL == request) { - fdv[fdc].events = POLLIN | POLLOUT; - fdc++; + return -1; } - if (EWOULDBLOCK != errno && EAGAIN != errno) + request->fd = client; + e.data.ptr = request; + + if (-1 == epoll_ctl(efd, EPOLL_CTL_ADD, client, &e)) { return -1; } - return fdc; + return 0; } |