diff --git a/nbproject/Makefile-Debug.mk b/nbproject/Makefile-Debug.mk index ddd0ef0..ddf8bb8 100644 --- a/nbproject/Makefile-Debug.mk +++ b/nbproject/Makefile-Debug.mk @@ -48,6 +48,10 @@ OBJECTFILES= \ ${OBJECTDIR}/src/mime.o \ ${OBJECTDIR}/src/queue.o \ ${OBJECTDIR}/src/server-connection.o \ + ${OBJECTDIR}/src/server-loop-read.o \ + ${OBJECTDIR}/src/server-loop-worker.o \ + ${OBJECTDIR}/src/server-loop-write.o \ + ${OBJECTDIR}/src/server-loop.o \ ${OBJECTDIR}/src/server-socket.o \ ${OBJECTDIR}/src/server-state.o \ ${OBJECTDIR}/src/server.o \ @@ -145,6 +149,26 @@ ${OBJECTDIR}/src/server-connection.o: nbproject/Makefile-${CND_CONF}.mk src/serv ${RM} "$@.d" $(COMPILE.c) -g -Werror -DINI_ALLOW_BOM=0 -DINI_ALLOW_MULTILINE=0 -D_GNU_SOURCE -Ilib -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/src/server-connection.o src/server-connection.c +${OBJECTDIR}/src/server-loop-read.o: nbproject/Makefile-${CND_CONF}.mk src/server-loop-read.c + ${MKDIR} -p ${OBJECTDIR}/src + ${RM} "$@.d" + $(COMPILE.c) -g -Werror -DINI_ALLOW_BOM=0 -DINI_ALLOW_MULTILINE=0 -D_GNU_SOURCE -Ilib -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/src/server-loop-read.o src/server-loop-read.c + +${OBJECTDIR}/src/server-loop-worker.o: nbproject/Makefile-${CND_CONF}.mk src/server-loop-worker.c + ${MKDIR} -p ${OBJECTDIR}/src + ${RM} "$@.d" + $(COMPILE.c) -g -Werror -DINI_ALLOW_BOM=0 -DINI_ALLOW_MULTILINE=0 -D_GNU_SOURCE -Ilib -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/src/server-loop-worker.o src/server-loop-worker.c + +${OBJECTDIR}/src/server-loop-write.o: nbproject/Makefile-${CND_CONF}.mk src/server-loop-write.c + ${MKDIR} -p ${OBJECTDIR}/src + ${RM} "$@.d" + $(COMPILE.c) -g -Werror -DINI_ALLOW_BOM=0 -DINI_ALLOW_MULTILINE=0 -D_GNU_SOURCE -Ilib -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/src/server-loop-write.o src/server-loop-write.c + +${OBJECTDIR}/src/server-loop.o: nbproject/Makefile-${CND_CONF}.mk src/server-loop.c + ${MKDIR} -p ${OBJECTDIR}/src + ${RM} "$@.d" + $(COMPILE.c) -g -Werror -DINI_ALLOW_BOM=0 -DINI_ALLOW_MULTILINE=0 -D_GNU_SOURCE -Ilib -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/src/server-loop.o src/server-loop.c + ${OBJECTDIR}/src/server-socket.o: nbproject/Makefile-${CND_CONF}.mk src/server-socket.c ${MKDIR} -p ${OBJECTDIR}/src ${RM} "$@.d" diff --git a/nbproject/Makefile-Release.mk b/nbproject/Makefile-Release.mk index bbb4d3c..c8094fc 100644 --- a/nbproject/Makefile-Release.mk +++ b/nbproject/Makefile-Release.mk @@ -48,6 +48,10 @@ OBJECTFILES= \ ${OBJECTDIR}/src/mime.o \ ${OBJECTDIR}/src/queue.o \ ${OBJECTDIR}/src/server-connection.o \ + ${OBJECTDIR}/src/server-loop-read.o \ + ${OBJECTDIR}/src/server-loop-worker.o \ + ${OBJECTDIR}/src/server-loop-write.o \ + ${OBJECTDIR}/src/server-loop.o \ ${OBJECTDIR}/src/server-socket.o \ ${OBJECTDIR}/src/server-state.o \ ${OBJECTDIR}/src/server.o \ @@ -145,6 +149,26 @@ ${OBJECTDIR}/src/server-connection.o: nbproject/Makefile-${CND_CONF}.mk src/serv ${RM} "$@.d" $(COMPILE.c) -O2 -Werror -DINI_ALLOW_BOM=0 -DINI_ALLOW_MULTILINE=0 -D_GNU_SOURCE -Ilib -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/src/server-connection.o src/server-connection.c +${OBJECTDIR}/src/server-loop-read.o: nbproject/Makefile-${CND_CONF}.mk src/server-loop-read.c + ${MKDIR} -p ${OBJECTDIR}/src + ${RM} "$@.d" + $(COMPILE.c) -O2 -Werror -DINI_ALLOW_BOM=0 -DINI_ALLOW_MULTILINE=0 -D_GNU_SOURCE -Ilib -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/src/server-loop-read.o src/server-loop-read.c + +${OBJECTDIR}/src/server-loop-worker.o: nbproject/Makefile-${CND_CONF}.mk src/server-loop-worker.c + ${MKDIR} -p ${OBJECTDIR}/src + ${RM} "$@.d" + $(COMPILE.c) -O2 -Werror -DINI_ALLOW_BOM=0 -DINI_ALLOW_MULTILINE=0 -D_GNU_SOURCE -Ilib -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/src/server-loop-worker.o src/server-loop-worker.c + +${OBJECTDIR}/src/server-loop-write.o: nbproject/Makefile-${CND_CONF}.mk src/server-loop-write.c + ${MKDIR} -p ${OBJECTDIR}/src + ${RM} "$@.d" + $(COMPILE.c) -O2 -Werror -DINI_ALLOW_BOM=0 -DINI_ALLOW_MULTILINE=0 -D_GNU_SOURCE -Ilib -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/src/server-loop-write.o src/server-loop-write.c + +${OBJECTDIR}/src/server-loop.o: nbproject/Makefile-${CND_CONF}.mk src/server-loop.c + ${MKDIR} -p ${OBJECTDIR}/src + ${RM} "$@.d" + $(COMPILE.c) -O2 -Werror -DINI_ALLOW_BOM=0 -DINI_ALLOW_MULTILINE=0 -D_GNU_SOURCE -Ilib -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/src/server-loop.o src/server-loop.c + ${OBJECTDIR}/src/server-socket.o: nbproject/Makefile-${CND_CONF}.mk src/server-socket.c ${MKDIR} -p ${OBJECTDIR}/src ${RM} "$@.d" diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index 99257d9..c6fe371 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -18,6 +18,7 @@ src/mime.h src/queue.h src/server-connection.h + src/server-loop.h src/server-socket.h src/server-state.h src/server.h @@ -46,6 +47,10 @@ src/mime.c src/queue.c src/server-connection.c + src/server-loop-read.c + src/server-loop-worker.c + src/server-loop-write.c + src/server-loop.c src/server-socket.c src/server-state.c src/server.c @@ -161,6 +166,16 @@ + + + + + + + + + + @@ -279,6 +294,16 @@ + + + + + + + + + + diff --git a/src/main-loop.c b/src/main-loop.c index 148f253..e6eb0fb 100644 --- a/src/main-loop.c +++ b/src/main-loop.c @@ -98,28 +98,24 @@ void hmain_setup(hmain_status *status) { pool->min_threads = 1; pool->max_threads = 2; pool->func = thloop_read; - status->pools[POOL_READ] = pool; thread_pool_start(pool); pool = thread_pool_new("write", queue_new()); pool->min_threads = 1; pool->max_threads = 2; pool->func = thloop_write; - status->pools[POOL_WRITE] = pool; thread_pool_start(pool); pool = thread_pool_new("disk_read", queue_new()); pool->min_threads = 1; pool->max_threads = 2; pool->func = thloop_disk_read; - status->pools[POOL_DISK_READ] = pool; thread_pool_start(pool); pool = thread_pool_new("worker", queue_new()); pool->min_threads = 1; pool->max_threads = 5; pool->func = thloop_worker; - status->pools[POOL_WORKERS] = pool; thread_pool_start(pool); } @@ -211,7 +207,7 @@ void hmain_loop(hmain_status *status) { if (conn->isReading == true) { continue; } - queue_add(status->pools[POOL_READ]->queue, queue_item_new2("READ", (void*)conn)); + queue_add(status->pools[1]->queue, queue_item_new2("READ", (void*)conn)); } } else if (EVENT_IS(current_event, EPOLLOUT)) { //Data can be written to connection @@ -219,7 +215,7 @@ void hmain_loop(hmain_status *status) { if (conn->isWriting == true || (conn->pending_responses == NULL && conn->pending_write == NULL)) { continue; } - queue_add(status->pools[POOL_WRITE]->queue, queue_item_new2("WRITE", (void*)conn)); + queue_add(status->pools[2]->queue, queue_item_new2("WRITE", (void*)conn)); } }//for events }//while shutdown == false @@ -257,7 +253,7 @@ void* thloop_read(void * arg) { //conn->pending_write = data_pool_appendbuffer(conn->pending_write, conn->status->buffer_pool, buffer, count); - queue_add(conn->status->pools[POOL_WRITE]->queue, queue_item_new2("WRITE", (void*)conn)); + queue_add(conn->status->pools[2]->queue, queue_item_new2("WRITE", (void*)conn)); /*if (conn->parse_data == NULL) { conn->parse_data = calloc(1, sizeof(hmain_parse_data)); conn->parse_data->parser = calloc(1, sizeof(http_parser)); diff --git a/src/main-loop.h b/src/main-loop.h index 25530d1..e1d687e 100644 --- a/src/main-loop.h +++ b/src/main-loop.h @@ -22,7 +22,7 @@ extern "C" { #define CONN_UNLOCK(c) pthread_mutex_unlock(c->mutex) typedef enum hmain_pool { - POOL_READ, POOL_WRITE, POOL_WORKERS, POOL_DISK_READ + POOL_READA, POOL_WRITEA, POOL_WORKERSA, POOL_DISK_READA } hmain_pool; //typedef enum skt_elem_hstate {HSTATE_NONE, HSTATE_VALUE, HSTATE_FIELD} skt_elem_hstate; diff --git a/src/server-loop-read.c b/src/server-loop-read.c new file mode 100644 index 0000000..756ef8f --- /dev/null +++ b/src/server-loop-read.c @@ -0,0 +1,15 @@ +#include +#include +#include + +#include "util.h" +#include "log.h" +#include "config.h" + +#include "server-connection.h" +#include "server-state.h" +#include "server-loop.h" + +void* server_loop_read(void* arg) { + +} \ No newline at end of file diff --git a/src/server-loop-worker.c b/src/server-loop-worker.c new file mode 100644 index 0000000..8398391 --- /dev/null +++ b/src/server-loop-worker.c @@ -0,0 +1,15 @@ +#include +#include +#include + +#include "util.h" +#include "log.h" +#include "config.h" + +#include "server-connection.h" +#include "server-state.h" +#include "server-loop.h" + +void* server_loop_worker(void* arg) { + +} \ No newline at end of file diff --git a/src/server-loop-write.c b/src/server-loop-write.c new file mode 100644 index 0000000..1eb03b4 --- /dev/null +++ b/src/server-loop-write.c @@ -0,0 +1,15 @@ +#include +#include +#include + +#include "util.h" +#include "log.h" +#include "config.h" + +#include "server-connection.h" +#include "server-state.h" +#include "server-loop.h" + +void* server_loop_write(void* arg) { + +} \ No newline at end of file diff --git a/src/server-loop.c b/src/server-loop.c new file mode 100644 index 0000000..1cd4590 --- /dev/null +++ b/src/server-loop.c @@ -0,0 +1,14 @@ +#include +#include +#include + +#include "util.h" +#include "log.h" +#include "config.h" + +#include "server-connection.h" +#include "server-state.h" + +void server_loop(server_status *state) { + +} \ No newline at end of file diff --git a/src/server-loop.h b/src/server-loop.h new file mode 100644 index 0000000..33c29e2 --- /dev/null +++ b/src/server-loop.h @@ -0,0 +1,32 @@ +/* + * File: server-loop.h + * Author: sam + * + * Created on 18 August 2014, 17:16 + */ + +#ifndef SERVER_LOOP_H +#define SERVER_LOOP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "server-state.h" + +#define EP_CONN(event) (server_connection*)event->data.ptr +#define EP_EVENT_IS(event, type) ((event->events & type) == type) +#define EP_EVENT_ISNOT(event, type) (!EVENT_IS(event, type)) + + void server_loop(server_status *state); + void* server_loop_read(void* arg); + void* server_loop_write(void* arg); + void* server_loop_worker(void* arg); + + +#ifdef __cplusplus +} +#endif + +#endif /* SERVER_LOOP_H */ + diff --git a/src/server-socket.c b/src/server-socket.c index f5ba84d..fa504b4 100644 --- a/src/server-socket.c +++ b/src/server-socket.c @@ -7,13 +7,14 @@ #include #include #include -#include +#include #include #include +#include +#include "util.h" #include "socket.h" #include "server-socket.h" -#include "util.h" int server_socket_create() { int fd = 0; @@ -24,6 +25,9 @@ int server_socket_create() { return fd; } void server_socket_listen(int fd, uint16_t port) { + assert(fd>=0); + assert(port>0); + struct sockaddr_in server_address; memset(&server_address, 0, sizeof server_address); server_address.sin_family = AF_INET; @@ -40,30 +44,35 @@ void server_socket_listen(int fd, uint16_t port) { } info("Listening on port %u", port); } +void server_socket_listen_epoll(int fd, uint16_t port, int *out_epfd) { + assert(out_epfd != NULL); + server_socket_listen(fd, port); + + int epfd = 0; + + //Open epoll socket + epfd = epoll_create1(0); + if (epfd < 0) { + fatal("Failed to create epollfd"); + } + + //Register socket with epoll + struct epoll_event svr_event; + svr_event.data.fd = fd; + svr_event.events = EPOLLIN | EPOLLET; + if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &svr_event) < 0) { + fatal("Could not register server socket with epoll"); + } + *out_epfd = epfd; +} void server_socket_release(int fd) { + assert(fd>=0); if (close(fd) < 0) { warning(true, "could not close socket"); } } -bool server_socket_canaccept(int fd) { - struct pollfd* pfd = calloc(1, sizeof(struct pollfd)); - - pfd[0].fd = fd; - pfd[0].events = POLLIN; - - if (poll(pfd, 1, 50/*ms*/) < 0) { - warning(true, "poll failed"); - free(pfd); - return false; - } - if ((pfd[0].revents & POLLIN) == POLLIN) { - free(pfd); - return true; - } - free(pfd); - return false; -} socket_info* server_socket_accept(int fd, int flags) { + assert(fd>=0); struct sockaddr_in* clientaddr = calloc(1, sizeof(struct sockaddr_in)); int clientfd=0; diff --git a/src/server-socket.h b/src/server-socket.h index 13ac3fe..91dea26 100644 --- a/src/server-socket.h +++ b/src/server-socket.h @@ -18,8 +18,8 @@ extern "C" { int server_socket_create(); void server_socket_listen(int fd, uint16_t port); + void server_socket_listen_epoll(int fd, uint16_t port, int *out_epfd); void server_socket_release(int fd); - bool server_socket_canaccept(int fd); socket_info* server_socket_accept(int fd, int flags); diff --git a/src/server-state.c b/src/server-state.c index 6de4479..6ba3aa3 100644 --- a/src/server-state.c +++ b/src/server-state.c @@ -10,6 +10,7 @@ #include "server-state.h" #include "queue.h" #include "thread-pool.h" +#include "main-loop.h" server_status* server_status_new(config_server *config) { assert(config!=NULL); @@ -40,7 +41,7 @@ void server_status_delete(server_status *status) { free(status); } -void server_start_pools(server_status *status) { +void server_start_pools(server_status *status, thread_func pool_functions[]) { assert(status!=NULL); assert(status->pools[0]==NULL); @@ -48,21 +49,21 @@ void server_start_pools(server_status *status) { thread_pool *pool = thread_pool_new("read", queue_new()); pool->min_threads = 1; pool->max_threads = 2; - //pool->func = thloop_read; + pool->func = pool_functions[POOL_READ]; status->pools[POOL_READ] = pool; thread_pool_start(pool); pool = thread_pool_new("write", queue_new()); pool->min_threads = 1; pool->max_threads = 2; - //pool->func = thloop_write; + pool->func = pool_functions[POOL_WRITE]; status->pools[POOL_WRITE] = pool; thread_pool_start(pool); pool = thread_pool_new("worker", queue_new()); pool->min_threads = 1; pool->max_threads = 5; - //pool->func = thloop_worker; + pool->func = pool_functions[POOL_WORKER]; status->pools[POOL_WORKER] = pool; thread_pool_start(pool); } diff --git a/src/server-state.h b/src/server-state.h index 723cbd9..9c57397 100644 --- a/src/server-state.h +++ b/src/server-state.h @@ -34,7 +34,7 @@ extern "C" { server_status* server_status_new(config_server *config); void server_status_delete(server_status *status); - void server_start_pools(server_status *status); + void server_start_pools(server_status *status, thread_func pool_functions[]); void server_stop_pools(server_status *status); #ifdef __cplusplus diff --git a/src/server.c b/src/server.c index 64f6735..020fe53 100644 --- a/src/server.c +++ b/src/server.c @@ -1,6 +1,9 @@ #include #include #include +#include +#include +#include #include "log.h" #include "util.h" @@ -13,5 +16,79 @@ #include "config.h" #include "server-socket.h" +#include "server-state.h" #include "server-connection.h" +#include "server-loop.h" #include "server.h" + +void server_start(server_status *status, const char* config_file) { + assert(status!=NULL); + assert(status->stopped==true); + + status->shutdown_requested = false; + + //Start Logging + log_register_add(log_new("stderr", stderr), true, LALL & ~(LINFO|LDEBUG)); + log_register_add(log_new("stdout", stdout), false, LDEBUG | LINFO); + + //Load mime types + mime_init(NULL); + + //Load the config + config_server *config = config_server_new(); + if (config_read_ini(config_file, config) < 0) { + fatal("Could not read config"); + } + status->config = config; + + //Open the server socket + status->sfd = server_socket_create(); + server_socket_listen_epoll(status->sfd, config->listen_port, &status->epollfd); + + //Start thread pools + thread_func pool_functions[] = { + [POOL_READ] = server_loop_read, + [POOL_WRITE] = server_loop_write, + [POOL_WORKER] = server_loop_worker + }; + server_start_pools(status, pool_functions); + + status->started = true; + status->stopped = false; + + //Start the main loop + server_loop(status); + + //Cleanup after the loop exits + server_teardown(status); +} +void server_teardown(server_status *status) { + assert(status!=NULL); + assert(status->stopped==true); + + //Stop thread pools + server_stop_pools(status); + + //Close connections + server_connection *elem, *tmp; + LL_FOREACH_SAFE(status->clients, elem, tmp) { + skt_close(elem->skt); + LL_DELETE(status->clients, elem); + server_connection_delete(elem); + } + + //Close server socket + close(status->epollfd); + server_socket_release(status->sfd); + + //Free mime data + mime_destroy(); + + //Stop loggers + log_register_clear(); + + //Delete config + config_server_delete(status->config); + + server_status_delete(status); +} \ No newline at end of file diff --git a/src/server.h b/src/server.h index c37f2f7..d7c8e35 100644 --- a/src/server.h +++ b/src/server.h @@ -11,8 +11,13 @@ #ifdef __cplusplus extern "C" { #endif + +#define DEFAULT_CONFIG_FILE "khttpd.ini" - +#include "server-state.h" + + void server_start(server_status *status, const char* config_file); + void server_teardown(server_status *status); #ifdef __cplusplus }