aboutsummaryrefslogtreecommitdiff
path: root/src/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/server.c')
-rw-r--r--src/server.c53
1 files changed, 47 insertions, 6 deletions
diff --git a/src/server.c b/src/server.c
index 6c32a85..f4e49aa 100644
--- a/src/server.c
+++ b/src/server.c
@@ -2,6 +2,7 @@
#include <unistd.h>
#include <string.h>
#include <sys/epoll.h>
+#include <pthread.h>
#include <assert.h>
#include "server.h"
@@ -9,8 +10,10 @@
#include "log.h"
typedef struct client_thread_args {
+ pthread_t self;
int client_fd;
- server_ctx *server_ctx;
+ struct sockaddr_in clientaddr;
+ const server_ctx *server_ctx;
} client_thread_args;
static int server_accept_client(const server_ctx ctx[],
@@ -45,8 +48,7 @@ int server_validate_ctx(const server_ctx *ctx)
int server_setup_epoll(const server_ctx ctx[], size_t siz)
{
- int s;
- int fd = epoll_create1(0); /* flags == 0 -> obsolete size arg is dropped */
+ int s, fd = epoll_create1(0); /* flags == 0 -> obsolete size arg is dropped */
struct epoll_event ev;
assert(ctx);
@@ -122,9 +124,23 @@ static int server_accept_client(const server_ctx ctx[],
client_fd = socket_accept_in(&ctx[i].sock, &clientaddr);
if (client_fd < 0) {
E_STRERR("Could not accept client connection");
- } else {
- return 1;
+ return 0;
+ }
+
+ client_thread_args *args =
+ (client_thread_args *) malloc(sizeof(client_thread_args));
+ args->client_fd = client_fd;
+ args->clientaddr = clientaddr;
+ args->server_ctx = &ctx[i];
+ if (pthread_create(&args->self, NULL,
+ client_mainloop_epoll, args))
+ {
+ E_STRERR("Thread creation");
+ free(args);
+ return 0;
}
+
+ return 1;
}
}
@@ -134,6 +150,31 @@ static int server_accept_client(const server_ctx ctx[],
static void *
client_mainloop_epoll(void *arg)
{
- (void) arg;
+ client_thread_args *args;
+ int s, epoll_fd;
+ struct epoll_event event;
+ struct epoll_event *events;
+
+ assert(arg);
+ args = (client_thread_args *) arg;
+ events = (struct epoll_event *) calloc(POTD_MAXEVENTS, sizeof(*events));
+ assert(events);
+
+ epoll_fd = epoll_create1(0);
+ if (epoll_fd < 0)
+ goto finish;
+
+ event.data.fd = args->client_fd;
+ event.events = EPOLLIN | EPOLLOUT | EPOLLET;
+ memset(&event, 0, sizeof(event));
+ s = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, args->client_fd, &event);
+ if (s)
+ goto finish;
+
+finish:
+ close(epoll_fd);
+ close(args->client_fd);
+ free(events);
+ free(args);
return NULL;
}