aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuangxiong Lin <[email protected]>2022-12-02 01:04:51 +0800
committerGuangxiong Lin <[email protected]>2022-12-02 01:04:51 +0800
commit14eb75c7f5e90f3c1174cdf700753d74bbd358a8 (patch)
tree33954c3ad8e10ac381f4b5d48c5bf541e061199d
parent9bed42bfcdb548c2f097a7536d3fa6a4117b57e9 (diff)
downloadtinyserver-14eb75c7f5e90f3c1174cdf700753d74bbd358a8.tar.gz
tinyserver-14eb75c7f5e90f3c1174cdf700753d74bbd358a8.tar.bz2
tinyserver-14eb75c7f5e90f3c1174cdf700753d74bbd358a8.zip
Abstract accept and handle as event
-rw-r--r--eventloop.c57
-rw-r--r--eventloop.h14
-rw-r--r--server.c102
-rw-r--r--util.h2
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
diff --git a/server.c b/server.c
index bc856f9..bab1edc 100644
--- a/server.c
+++ b/server.c
@@ -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);
}
diff --git a/util.h b/util.h
index 6e9c8cf..c0f0214 100644
--- a/util.h
+++ b/util.h
@@ -1,3 +1,5 @@
+#include <stdbool.h>
+
#ifndef __UTIL_H
#define __UTIL_H