diff options
Diffstat (limited to 'src/server.c')
-rw-r--r-- | src/server.c | 53 |
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; } |