From 7bb3515bc303a2a35fe859bcdba2795fbe06643d Mon Sep 17 00:00:00 2001 From: Guangxiong Lin Date: Sat, 17 Dec 2022 09:33:30 +0800 Subject: Make server as a library --- src/acceptor.c | 34 +++++++++++++++++++-------- src/acceptor.h | 5 +++- src/evloop.c | 12 +++++++--- src/evloop.h | 3 ++- src/server.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++----------- src/server.h | 11 +++++++++ 6 files changed, 110 insertions(+), 28 deletions(-) create mode 100644 src/server.h (limited to 'src') diff --git a/src/acceptor.c b/src/acceptor.c index 1f28fcc..ca7bfb4 100644 --- a/src/acceptor.c +++ b/src/acceptor.c @@ -7,12 +7,26 @@ #include "util.h" #include "connection.h" #include "evloop.h" +#include "server.h" struct conn_acceptor { - struct tsocket *sock; - evloop_t *el; + tsocket_t *sock; + evloop_t **evloops; + int nevloops; }; -typedef struct conn_acceptor conn_acceptor_t; + +conn_acceptor_t *conn_acceptor_create(tsocket_t *sock, evloop_t **evloops, int nevloops) +{ + conn_acceptor_t *acceptor = malloc(sizeof(*acceptor)); + if (!acceptor) + return NULL; + + acceptor->sock = sock; + acceptor->evloops = evloops; + acceptor->nevloops = nevloops; + + return acceptor; +} static void conn_acceptor_accept(conn_acceptor_t *ca) { @@ -30,7 +44,9 @@ static void conn_acceptor_accept(conn_acceptor_t *ca) event_t *conn_ev = connection_create_event(conn_sock); - if (evloop_add(ca->el, conn_ev, EPOLLIN | EPOLLET) == -1) { + // TODO: Use a better way to decide which sub reactor to use. + int ind = conn_sock->fd % ca->nevloops; + if (evloop_add(ca->evloops[ind], conn_ev, EPOLLIN | EPOLLET) == -1) { perror("eventloop add fd: conn_sock"); return; } @@ -45,14 +61,12 @@ static void conn_acceptor_destroy(conn_acceptor_t *ca) free(ca); } -event_t *conn_acceptor_create_event(struct tsocket *sock, evloop_t *el) +event_t *conn_acceptor_event_create(struct tsocket *sock, evloop_t **evloops, int nevloops) { - conn_acceptor_t *ca = malloc(sizeof(*ca)); - ca->sock = sock; - ca->el = el; - - struct event *ev = event_create(ca, sock->fd, + conn_acceptor_t *acceptor = conn_acceptor_create(sock, evloops, nevloops); + event_t *ev = event_create(acceptor, sock->fd, (evloop_process_func_t) conn_acceptor_accept, (evloop_destroy_func_t) conn_acceptor_destroy); + return ev; } diff --git a/src/acceptor.h b/src/acceptor.h index f4c9284..2d16a13 100644 --- a/src/acceptor.h +++ b/src/acceptor.h @@ -4,6 +4,9 @@ #ifndef __ACCEPTOR_H #define __ACCEPTOR_H -struct event *conn_acceptor_create_event(struct tsocket *sock, evloop_t *el); +struct conn_acceptor; +typedef struct conn_acceptor conn_acceptor_t; + +event_t *conn_acceptor_event_create(struct tsocket *sock, evloop_t **evloops, int nevloops); #endif diff --git a/src/evloop.c b/src/evloop.c index 5bed1e9..5002b24 100644 --- a/src/evloop.c +++ b/src/evloop.c @@ -1,5 +1,6 @@ #include #include +#include #include "evloop.h" #include "util.h" @@ -25,6 +26,12 @@ evloop_t *evloop_create() return eventLoop; } +void evloop_destroy(evloop_t *evloop) +{ + close(evloop->epollfd); + free(evloop); +} + int evloop_wait(evloop_t *el, int timeout) { return epoll_wait(el->epollfd, el->events, el->size, timeout); @@ -56,9 +63,8 @@ void evloop_loop(evloop_t *el) for (int i = 0; i < nevents; i++) { ev = evloop_get(el, i); - // TODO: detect if there is any issue of the handle function - // and delete the event when issues happen - tpool_add_work(tpool, ev->process, ev->data); + if (ev->process(ev->data) == -1) + evloop_remove(el, ev); } } } diff --git a/src/evloop.h b/src/evloop.h index f0d4f72..f11c8df 100644 --- a/src/evloop.h +++ b/src/evloop.h @@ -8,7 +8,7 @@ struct evloop; typedef struct evloop evloop_t; -typedef void (*evloop_process_func_t)(void *data); +typedef int (*evloop_process_func_t)(void *data); typedef void (*evloop_destroy_func_t)(void *data); struct event { @@ -20,6 +20,7 @@ struct event { typedef struct event event_t; evloop_t *evloop_create(); +void evloop_destroy(evloop_t *evloop); int evloop_wait(evloop_t *el, int timeout); int evloop_add(evloop_t *el, event_t *ev, int flag); int evloop_remove(evloop_t *el, event_t *ev); diff --git a/src/server.c b/src/server.c index 8525689..a13d525 100644 --- a/src/server.c +++ b/src/server.c @@ -9,32 +9,79 @@ #include #include #include +#include #include "evloop.h" #include "tsocket.h" #include "util.h" #include "acceptor.h" #include "tpool.h" +#include "server.h" -int main() +struct server { + tpool_t *tpool; + evloop_t *evloop; + evloop_t **subevloops; +}; + +server_t *server_create(void) { - evloop_t *el = evloop_create(); - if (el == NULL) - panic("eventloop creation"); + int nprocs = get_nprocs(); + server_t *serv = (server_t *)malloc(sizeof(*serv)); + tsocket_t *sock; + event_t *acceptor_event; - struct tsocket *sock = tsocket_create(); - if (sock == NULL + if (!(sock = tsocket_create()) || tsocket_bind(sock, "127.0.0.1", 8888) == -1 || tsocket_listen(sock) == -1) panic("socket creation"); - tpool = tpool_create(0); - if (!tpool) - panic("tpool_create"); + serv = (server_t *)malloc(sizeof(*serv)); + if (!serv) + return NULL; + + serv->tpool = tpool_create(nprocs); + serv->evloop = evloop_create(); + serv->subevloops = calloc(nprocs, sizeof(evloop_t*)); + for (int i = 0; i < nprocs; i++) + serv->subevloops[i] = evloop_create(); + + if (!(acceptor_event = conn_acceptor_event_create(sock, serv->subevloops, nprocs))) + return NULL; + if (evloop_add(serv->evloop, acceptor_event, EPOLLIN) == -1) + panic("evloop add fd"); + + for (int i = 0; i < nprocs; i++) + tpool_add_work(serv->tpool, (thread_func_t) evloop_loop, + serv->subevloops[i]); + + return serv; +} + +void server_destroy(server_t *serv) +{ + int nprocs = get_nprocs(); + + if (!serv) + return; + + evloop_destroy(serv->evloop); + tpool_destroy(serv->tpool); - event_t *acceptEvent = conn_acceptor_create_event(sock, el); - if (evloop_add(el, acceptEvent, EPOLLIN) == -1) - panic("eventloop add fd"); + for (int i = 0; i < nprocs; i++) + evloop_destroy(serv->subevloops[i]); - evloop_loop(el); + free(serv->subevloops); + free(serv); +} + +void server_run(server_t *serv) +{ + evloop_loop(serv->evloop); +} + +int main() +{ + server_t *serv = server_create(); + server_run(serv); } diff --git a/src/server.h b/src/server.h new file mode 100644 index 0000000..44c5434 --- /dev/null +++ b/src/server.h @@ -0,0 +1,11 @@ +#ifndef __SERVER_H +#define __SERVER_H + +struct server; +typedef struct server server_t; + +server_t *server_create(void); + +void server_run(server_t *serv); + +#endif -- cgit v1.2.3