diff options
Diffstat (limited to 'src/server.c')
-rw-r--r-- | src/server.c | 79 |
1 files changed, 71 insertions, 8 deletions
diff --git a/src/server.c b/src/server.c index 6c0a7a2..6c32a85 100644 --- a/src/server.c +++ b/src/server.c @@ -5,6 +5,18 @@ #include <assert.h> #include "server.h" +#include "socket.h" +#include "log.h" + +typedef struct client_thread_args { + int client_fd; + server_ctx *server_ctx; +} client_thread_args; + +static int server_accept_client(const server_ctx ctx[], + size_t siz, struct epoll_event *event); +static void * +client_mainloop_epoll(void *arg); server_ctx * @@ -31,7 +43,7 @@ int server_validate_ctx(const server_ctx *ctx) return 0; } -int server_setup_epoll(const server_ctx *ctx[], size_t siz) +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 */ @@ -42,35 +54,86 @@ int server_setup_epoll(const server_ctx *ctx[], size_t siz) if (fd < 0) return -1; - for (int i = 0; i < siz; ++i) { + for (size_t i = 0; i < siz; ++i) { memset(&ev, 0, sizeof(ev)); - ev.data.fd = ctx[i]->sock.fd; + ev.data.fd = ctx[i].sock.fd; ev.events = EPOLLIN | EPOLLET; - s = epoll_ctl(fd, EPOLL_CTL_ADD, ctx[i]->sock.fd, &ev); + s = epoll_ctl(fd, EPOLL_CTL_ADD, ctx[i].sock.fd, &ev); if (s) { close(fd); - return -1; + return -2; } } return fd; } -int server_mainloop_epoll(int epoll_fd, const server_ctx *ctx[], size_t siz) +int server_mainloop_epoll(int epoll_fd, const server_ctx ctx[], size_t siz) { - struct epoll_event *events = calloc(POTD_MAXEVENTS, sizeof(*events)); + static struct epoll_event *events = NULL; + + if (!events) + events = (struct epoll_event *) calloc(POTD_MAXEVENTS, sizeof(*events)); assert(events); assert(ctx); assert(siz > 0 && siz < POTD_MAXFD); while (1) { - int n; + int n, i; n = epoll_wait(epoll_fd, events, POTD_MAXEVENTS, -1); + if (n < 0) + return 1; + + for (i = 0; i < n; ++i) { + if ((events[i].events & EPOLLERR) || + (events[i].events & EPOLLHUP) || + (!(events[i].events & EPOLLIN))) + { + E("Epoll for descriptor %d failed", events[i].data.fd); + E_STRERR("epoll_wait"); + close(events[i].data.fd); + continue; + } else { + if (server_accept_client(ctx, siz, &events[i])) { + /* new client connection, accept succeeded */ + continue; + } + D2("FD: %d/%lu , %d", events[i].data.fd, siz, n); + } + } } free(events); return 0; } + +static int server_accept_client(const server_ctx ctx[], + size_t siz, struct epoll_event *event) +{ + size_t i; + int client_fd; + struct sockaddr_in clientaddr; + + for (i = 0; i < siz; ++i) { + if (ctx[i].sock.fd == event->data.fd) { + 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; +} + +static void * +client_mainloop_epoll(void *arg) +{ + (void) arg; + return NULL; +} |