summaryrefslogtreecommitdiffhomepage
path: root/plop.c
diff options
context:
space:
mode:
Diffstat (limited to 'plop.c')
-rw-r--r--plop.c73
1 files changed, 34 insertions, 39 deletions
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;
}