diff options
author | Guangxiong Lin <[email protected]> | 2022-12-02 01:04:51 +0800 |
---|---|---|
committer | Guangxiong Lin <[email protected]> | 2022-12-02 01:04:51 +0800 |
commit | 14eb75c7f5e90f3c1174cdf700753d74bbd358a8 (patch) | |
tree | 33954c3ad8e10ac381f4b5d48c5bf541e061199d | |
parent | 9bed42bfcdb548c2f097a7536d3fa6a4117b57e9 (diff) | |
download | tinyserver-14eb75c7f5e90f3c1174cdf700753d74bbd358a8.tar.gz tinyserver-14eb75c7f5e90f3c1174cdf700753d74bbd358a8.tar.bz2 tinyserver-14eb75c7f5e90f3c1174cdf700753d74bbd358a8.zip |
Abstract accept and handle as event
-rw-r--r-- | eventloop.c | 57 | ||||
-rw-r--r-- | eventloop.h | 14 | ||||
-rw-r--r-- | server.c | 102 | ||||
-rw-r--r-- | util.h | 2 |
4 files changed, 126 insertions, 49 deletions
diff --git a/eventloop.c b/eventloop.c index 9a26b98..970a521 100644 --- a/eventloop.c +++ b/eventloop.c @@ -1,6 +1,8 @@ #include <stdlib.h> #include <sys/epoll.h> + #include "eventloop.h" +#include "util.h" struct eventLoop *eventLoopNew() { @@ -15,15 +17,6 @@ struct eventLoop *eventLoopNew() return eventLoop; } -int eventLoopAddSocket(struct eventLoop *el, struct tsocket *sock, int flag) -{ - struct epoll_event ev; - ev.events = flag; - ev.data.ptr = sock; - - return epoll_ctl(el->epollfd, EPOLL_CTL_ADD, sock->fd, &ev); -} - int eventLoopWait(struct eventLoop *el, int timeout) { return epoll_wait(el->epollfd, el->events, el->size, timeout); @@ -33,3 +26,49 @@ struct tsocket *eventLoopGetSocket(struct eventLoop *el, int index) { return (struct tsocket *)el->events[index].data.ptr; } + +int eventLoopAdd(struct eventLoop *el, struct event *ev, int flag) +{ + struct epoll_event epev; + epev.events = flag; + epev.data.ptr = ev; + + ev->el = el; + + return epoll_ctl(el->epollfd, EPOLL_CTL_ADD, ev->fd, &epev); +} + +struct event *eventLoopGet(struct eventLoop *el, int index) +{ + return (struct event *)el->events[index].data.ptr; +} + +void eventLoopLoop(struct eventLoop *el) +{ + int nevents; + struct event *ev; + + for (;;) { + nevents = eventLoopWait(el, -1); + if (nevents == -1) + panic("eventloop wait"); + + for (int i = 0; i < nevents; i++) { + ev = eventLoopGet(el, i); + ev->handle(ev); + } + } +} + +int eventLoopDel(struct eventLoop *el, struct event *ev) +{ + if (epoll_ctl(el->epollfd, EPOLL_CTL_DEL, ev->fd, NULL) == -1) + return ERROR; + + if (ev->delete) + ev->delete(ev); + else + free(ev); + + return OK; +} diff --git a/eventloop.h b/eventloop.h index 4dd7f6e..490d515 100644 --- a/eventloop.h +++ b/eventloop.h @@ -13,9 +13,19 @@ struct eventLoop { int size; }; +struct event { + int fd; + struct eventLoop *el; + void *data; + void (*handle)(struct event *ev); + void (*delete)(struct event *ev); +}; + struct eventLoop *eventLoopNew(); -int eventLoopAddSocket(struct eventLoop *el, struct tsocket *sock, int flag); int eventLoopWait(struct eventLoop *el, int timeout); -struct tsocket *eventLoopGetSocket(struct eventLoop *el, int index); +int eventLoopAdd(struct eventLoop *el, struct event *ev, int flag); +int eventLoopDel(struct eventLoop *el, struct event *ev); +struct event *eventLoopGet(struct eventLoop *el, int index); +void eventLoopLoop(struct eventLoop *el); #endif @@ -16,11 +16,13 @@ #define READ_BUFFER_SIZE 1024 -void handleEvent(struct tsocket *sock) +void handleReadEvent(struct event *ev) { char buf[READ_BUFFER_SIZE]; ssize_t n_read_bytes; + struct tsocket *sock = (struct tsocket *)ev->data; + for (;;) { n_read_bytes = read(sock->fd, buf, sizeof(buf)); if (n_read_bytes > 0) { @@ -28,7 +30,7 @@ void handleEvent(struct tsocket *sock) write(sock->fd, buf, sizeof(buf)); } else if (n_read_bytes == 0) { printf("conn %d disconnected\n", sock->fd); - tsocketDelete(sock); + eventLoopDel(ev->el, ev); break; } else if (n_read_bytes == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) @@ -37,51 +39,75 @@ void handleEvent(struct tsocket *sock) } } -int main() +void serverDeleteReadEvent(struct event *ev) +{ + tsocketDelete(ev->data); + free(ev); +} + +struct event *serverNewReadEvent(struct tsocket *sock) +{ + struct event *ev = malloc(sizeof(*ev)); + ev->data = sock; + ev->handle = handleReadEvent; + ev->fd = sock->fd; + ev->delete = serverDeleteReadEvent; + + return ev; +} + +void handleNewClientConnection(struct event *ev) +{ + struct tsocket *conn_sock = tsocketAccept(ev->data); + if (conn_sock == NULL) { + perror("socket accept"); + return; + } + + if (setblocking(conn_sock->fd, false) == -1) { + perror("setblocking"); + tsocketDelete(conn_sock); + return; + } + + struct event *read_ev = serverNewReadEvent(conn_sock); + if (eventLoopAdd(ev->el, read_ev, EPOLLIN | EPOLLET) == -1) { + perror("eventloop add fd: conn_sock"); + return; + } + + printf("New client fd %d, ip: %s, port: %d\n", + conn_sock->fd, conn_sock->addr, conn_sock->port); +} + +struct event *serverNewAcceptEvent(const char *addr, int port) { struct tsocket *sock = tsocketNew(); - if (sock == NULL) - panic("socket creation error"); + if (sock == NULL + || tsocketBind(sock, addr, port) == -1 + || tsocketListen(sock) == -1) + return NULL; - if (tsocketBind(sock, "127.0.0.1", 8888) == -1) - panic("socket bind error"); + struct event *ev = malloc(sizeof(*ev)); + ev->handle = handleNewClientConnection; + ev->data = sock; + ev->fd = sock->fd; - if (tsocketListen(sock) == -1) - panic("socket listen error"); + return ev; +} +int main() +{ struct eventLoop *el = eventLoopNew(); if (el == NULL) panic("eventloop creation"); - if (eventLoopAddSocket(el, sock, EPOLLIN) == -1) + struct event *acceptEvent = serverNewAcceptEvent("127.0.0.1", 8888); + if (acceptEvent == NULL) + panic("server client connection event"); + + if (eventLoopAdd(el, acceptEvent, EPOLLIN) == -1) panic("eventloop add fd"); - int nfds; - struct tsocket *conn_sock; - for (;;) { - nfds = eventLoopWait(el, -1); - if (nfds == -1) - panic("eventloop wait"); - - for (int i = 0; i < nfds; i++) { - if (eventLoopGetSocket(el, i) == sock) { - conn_sock = tsocketAccept(sock); - if (conn_sock == NULL) - panic("socket accept error"); - - if (setblocking(conn_sock->fd, false) == -1) { - tsocketDelete(conn_sock); - continue; - } - - if (eventLoopAddSocket(el, conn_sock, EPOLLIN | EPOLLET) == -1) - panic("eventloop add fd: conn_sockfd"); - - printf("New client fd %d, ip: %s, port: %d\n", - conn_sock->fd, conn_sock->addr, conn_sock->port); - } else { - handleEvent(eventLoopGetSocket(el, i)); - } - } - } + eventLoopLoop(el); } @@ -1,3 +1,5 @@ +#include <stdbool.h> + #ifndef __UTIL_H #define __UTIL_H |