diff -r 4417619a9bbd -r 450d2d5f4735 src/server/daemon/httplistener.c --- a/src/server/daemon/httplistener.c Sat Aug 18 11:39:34 2012 +0200 +++ b/src/server/daemon/httplistener.c Sat Oct 06 13:00:07 2012 +0200 @@ -47,6 +47,7 @@ #include #include "../ucx/map.h" +#include "../ucx/atomic.h" #include "httplistener.h" #include "session.h" @@ -67,8 +68,55 @@ return 0; } +HttpListener* http_listener_create(ListenerConfig *conf) { + if(listener_map == NULL) { + listener_map = ucx_map_new(16); + } + + HttpListener *fl = ucx_map_sstr_get(listener_map, conf->name); + if(fl == NULL) { + return http_listener_new(conf); + } + + HttpListener* newls = malloc(sizeof(HttpListener)); + if(newls == NULL) { + // TODO: error + } + + newls->cfg = conf->cfg; + newls->default_vs.vs_name = conf->vs.ptr; + newls->port = fl->port; + newls->server_socket = fl->server_socket; + newls->session_handler = fl->session_handler; // TODO + newls->ref = 2; // 1 reference is fl->next + + // create acceptor threads + newls->acceptors = calloc(newls->nacceptors, sizeof(void*)); + for (int i=0;inacceptors;i++) { + newls->acceptors[i] = acceptor_new(newls); + } + + // fl hold one reference of newls + fl->next = newls; + + + ucx_map_sstr_put(listener_map, newls->name, newls); + + for (int i=0;inacceptors;i++) { + acceptor_start(newls->acceptors[i]); + } + + // check if a restart is required to apply all changes + + if(newls->port != conf->port) { + // TODO: log + } + + return newls; +} HttpListener* http_listener_new(ListenerConfig *conf) { + // TODO: remove if(listener_map == NULL) { listener_map = ucx_map_new(16); } @@ -77,6 +125,7 @@ if(fl != NULL) { return fl; } + // end remove HttpListener *listener = malloc(sizeof(HttpListener)); listener->name = conf->name; @@ -84,6 +133,8 @@ listener->session_handler = create_event_session_handler(); listener->nacceptors = conf->nacceptors; listener->port = conf->port; + listener->ref = 1; + listener->next = NULL; ucx_map_sstr_put(listener_map, listener->name, listener); struct sockaddr_in servaddr; /* server address */ @@ -140,6 +191,20 @@ return 0; } +void http_listener_ref(HttpListener *listener) { + ucx_atomic_inc_32(&listener->ref); +} + +void http_listener_unref(HttpListener *listener) { + uint32_t ref = ucx_atomic_dec_32_nv(&listener->ref); + if(ref == 0) { + free(listener->acceptors); + // TODO: unref cfg + // TODO: unref session handler + free(listener); + } +} + Acceptor* acceptor_new(HttpListener *listener) { @@ -178,22 +243,33 @@ continue; } + // check listener + HttpListener *ls = listener; + int acceptor_exit = 0; + while(ls->next) { + ls = ls->next; + acceptor_exit = 1; + } + /* create Connection object */ Connection *conn = malloc(sizeof(Connection)); conn->address = ca; conn->fd = clientfd; - conn->listener = listener; + conn->listener = ls; /* enqueue the connection */ - listener->session_handler->enqueue_connection( - listener->session_handler, + ls->session_handler->enqueue_connection( + ls->session_handler, conn); /* ready for new connection */ - if(0) { + if(acceptor_exit) { break; } } + http_listener_unref(listener->next); + http_listener_unref(listener); + return NULL; }