summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2020-08-16 01:34:46 +0200
committerAki <please@ignore.pl>2020-08-16 01:34:46 +0200
commit67671f75955eaeb5f44bcd8717417f7ba7007c4b (patch)
treeec578dcf3371e6b7f865802eadadb5210593bc93
parent8704dabe2d6f1129787266dfab089aea23d92f15 (diff)
downloadplop-67671f75955eaeb5f44bcd8717417f7ba7007c4b.zip
plop-67671f75955eaeb5f44bcd8717417f7ba7007c4b.tar.gz
plop-67671f75955eaeb5f44bcd8717417f7ba7007c4b.tar.bz2
Switched to epoll
-rw-r--r--main.c54
-rw-r--r--plop.c73
-rw-r--r--plop.h6
-rw-r--r--request.h1
4 files changed, 74 insertions, 60 deletions
diff --git a/main.c b/main.c
index 06f44d4..ebe6bfe 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,5 @@
-#include <poll.h>
#include <string.h>
+#include <sys/epoll.h>
#include <lauxlib.h>
#include <lua.h>
@@ -26,33 +26,51 @@ int main(int argc, char ** argv)
return 2; // TODO: Document error codes/print usage information
}
- static const int max_clients = 200;
+ const int efd = epoll_create1(0);
- int fdc = 0;
- struct request * requests[max_clients];
- struct pollfd fdv[max_clients];
-
- memset(requests, 0, sizeof(requests));
- memset(fdv, 0, sizeof(fdv));
+ if (-1 == efd)
+ {
+ return 3; // TODO: Handle errors properly
+ }
- fdv[0].fd = make_server(NULL, argv[1]);
- fdv[0].events = POLLIN;
- fdc++;
+ struct epoll_event e;
+ e.events = EPOLLIN;
+ e.data.ptr = NULL; // TODO: Consider putting server's Lua state in here?
+ const int server = make_server(NULL, argv[1]); // TODO: Check server's fd before ctl?
- if (-1 == fdv[0].fd)
+ if (-1 == epoll_ctl(efd, EPOLL_CTL_ADD, server, &e))
{
- return 1; // TODO: Document error codes/print usage information
+ return 4; // TODO: Handle errors properly
}
- while (0 < fdc && -1 != poll(fdv, fdc, -1))
+ static const int MAX_EVENTS = 20;
+ struct epoll_event events[MAX_EVENTS];
+
+ while (1)
{
- int shift_by = 0;
+ int evc = epoll_wait(efd, events, MAX_EVENTS, -1);
- for (int i = 1; i < fdc; ++i)
+ if (-1 == evc)
{
- shift_by = handle_client(L, &fdv[i], &requests[i], shift_by);
+ return 5; // TODO: Handle errors properly
}
- fdc = handle_server(fdv, fdc - shift_by, max_clients);
+ for (int i = 0; i < evc; ++i)
+ {
+ if (NULL == events[i].data.ptr)
+ {
+ if (-1 == handle_server(L, efd, server))
+ {
+ return 6; // TODO: Handle errors properly
+ }
+ }
+ else
+ {
+ if (-1 == handle_client(L, &events[i]))
+ {
+ return 7; // TODO: Handle errors properly
+ }
+ }
+ }
}
}
diff --git a/plop.c b/plop.c
index 54e64ff..f24b7ab 100644
--- a/plop.c
+++ b/plop.c
@@ -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;
}
diff --git a/plop.h b/plop.h
index c12b43b..1aeec7f 100644
--- a/plop.h
+++ b/plop.h
@@ -1,6 +1,6 @@
#pragma once
-#include <poll.h>
+#include <sys/epoll.h>
#include <lua.h>
@@ -9,5 +9,5 @@
int make_server(const char *, const char *);
int load_handler(lua_State *, const char *);
-int handle_client(lua_State *, struct pollfd *, struct request **, const int);
-int handle_server(struct pollfd *, int, const int);
+int handle_client(lua_State *, struct epoll_event *);
+int handle_server(lua_State *, const int, const int);
diff --git a/request.h b/request.h
index e406711..b08236c 100644
--- a/request.h
+++ b/request.h
@@ -18,6 +18,7 @@ struct request
int reference;
struct span temp;
int expected_data_length;
+ int fd;
};
struct request * new_request(lua_State *);