X-Git-Url: http://git.madism.org/?a=blobdiff_plain;f=common%2Fserver.c;h=13de7836feb5e78e583704e5f2f8148b88271759;hb=6deab7a7086ccb592daa0c41e12759ec0b9c7aa0;hp=6ea1a9ad2ccf4bd5179a1226334eacc51a7f6ac1;hpb=bcd90daa5d3d303afe13832249fa20cad7303f8c;p=apps%2Fpfixtools.git diff --git a/common/server.c b/common/server.c index 6ea1a9a..13de783 100644 --- a/common/server.c +++ b/common/server.c @@ -35,40 +35,63 @@ #include "server.h" #include "epoll.h" +#include "common.h" -static server_t *listeners[1024]; -static int listener_count = 0; - +static PA(server_t) listeners = ARRAY_INIT; +static PA(server_t) server_pool = ARRAY_INIT; static server_t* server_new(void) { server_t* server = p_new(server_t, 1); - server->fd = -1; + server->fd = -1; return server; } +static void server_wipe(server_t *server) +{ + server->listener = false; + if (server->fd >= 0) { + epoll_unregister(server->fd); + close(server->fd); + server->fd = -1; + } + if (server->data && server->clear_data) { + server->clear_data(&server->data); + } +} + static void server_delete(server_t **server) { if (*server) { - if ((*server)->fd >= 0) { - close((*server)->fd); - } - if ((*server)->data && (*server)->clear_data) { - (*server)->clear_data(&(*server)->data); - } buffer_wipe(&(*server)->ibuf); buffer_wipe(&(*server)->obuf); + server_wipe(*server); p_delete(server); } } -static void server_shutdown(void) +static server_t* server_acquire(void) { - for (int i = 0 ; i < listener_count ; ++i) { - server_delete(&listeners[i]); + if (server_pool.len != 0) { + return array_elt(server_pool, --server_pool.len); + } else { + return server_new(); } } +void server_release(server_t *server) +{ + server_wipe(server); + array_add(server_pool, server); +} + +static void server_shutdown(void) +{ + printf("Server shutdown"); + array_deep_wipe(listeners, server_delete); + array_deep_wipe(server_pool, server_delete); +} + module_exit(server_shutdown); int start_server(int port, start_listener_t starter, delete_client_t deleter) @@ -95,18 +118,19 @@ int start_server(int port, start_listener_t starter, delete_client_t deleter) } } - tmp = server_new(); + tmp = server_acquire(); tmp->fd = sock; tmp->listener = true; tmp->data = data; + tmp->run = NULL; tmp->clear_data = deleter; epoll_register(sock, EPOLLIN, tmp); - listeners[listener_count++] = tmp; + array_add(listeners, tmp); return 0; } static int start_client(server_t *server, start_client_t starter, - delete_client_t deleter) + run_client_t runner, delete_client_t deleter) { server_t *tmp; void* data = NULL; @@ -126,25 +150,48 @@ static int start_client(server_t *server, start_client_t starter, } } - tmp = server_new(); + tmp = server_acquire(); + tmp->listener = false; tmp->fd = sock; tmp->data = data; + tmp->run = runner; tmp->clear_data = deleter; epoll_register(sock, EPOLLIN, tmp); return 0; } +server_t *server_register(int fd, run_client_t runner, void *data) +{ + if (fd < 0) { + return NULL; + } + + server_t *tmp = server_acquire(); + tmp->listener = false; + tmp->fd = fd; + tmp->data = data; + tmp->run = runner; + tmp->clear_data = NULL; + epoll_register(fd, EPOLLIN, tmp); + return tmp; +} + int server_loop(start_client_t starter, delete_client_t deleter, - run_client_t runner, refresh_t refresh, void* config) { + run_client_t runner, refresh_t refresh, void* config) +{ + info("entering processing loop"); while (!sigint) { struct epoll_event evts[1024]; int n; if (sighup && refresh) { + sighup = false; + info("refreshing..."); if (!refresh(config)) { - syslog(LOG_ERR, "error while refreshing configuration"); + crit("error while refreshing configuration"); return EXIT_FAILURE; } + info("refresh done, processing loop restarts"); } n = epoll_select(evts, countof(evts), -1); @@ -160,20 +207,20 @@ int server_loop(start_client_t starter, delete_client_t deleter, server_t *d = evts[n].data.ptr; if (d->listener) { - (void)start_client(d, starter, deleter); + (void)start_client(d, starter, runner, deleter); continue; } if (evts[n].events & EPOLLIN) { - if (runner(d, config) < 0) { - server_delete(&d); + if (d->run(d, config) < 0) { + server_release(d); continue; } } if ((evts[n].events & EPOLLOUT) && d->obuf.len) { if (buffer_write(&d->obuf, d->fd) < 0) { - server_delete(&d); + server_release(d); continue; } if (!d->obuf.len) { @@ -182,5 +229,6 @@ int server_loop(start_client_t starter, delete_client_t deleter, } } } + info("exit requested"); return EXIT_SUCCESS; }