From a52023a7111e4ed65f7870afc56d90387f5aadc7 Mon Sep 17 00:00:00 2001 From: Sam Stevens Date: Thu, 7 Aug 2014 21:36:37 +0100 Subject: [PATCH] Working on new server loop --- nbproject/Makefile-Debug.mk | 6 ++ nbproject/Makefile-Release.mk | 6 ++ nbproject/configurations.xml | 10 +++ src/http-server.c | 2 +- src/log.c | 28 +++++---- src/log.h | 1 + src/main-loop.c | 114 ++++++++++++++++++++++++++++++++++ src/main-loop.h | 41 ++++++++++++ src/socket.c | 13 +++- src/socket.h | 1 + 10 files changed, 209 insertions(+), 13 deletions(-) create mode 100644 src/main-loop.c create mode 100644 src/main-loop.h diff --git a/nbproject/Makefile-Debug.mk b/nbproject/Makefile-Debug.mk index 66d3082..b93a934 100644 --- a/nbproject/Makefile-Debug.mk +++ b/nbproject/Makefile-Debug.mk @@ -42,6 +42,7 @@ OBJECTFILES= \ ${OBJECTDIR}/src/http-server.o \ ${OBJECTDIR}/src/http.o \ ${OBJECTDIR}/src/log.o \ + ${OBJECTDIR}/src/main-loop.o \ ${OBJECTDIR}/src/main.o \ ${OBJECTDIR}/src/mime.o \ ${OBJECTDIR}/src/queue.o \ @@ -109,6 +110,11 @@ ${OBJECTDIR}/src/log.o: nbproject/Makefile-${CND_CONF}.mk src/log.c ${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/log.o src/log.c +${OBJECTDIR}/src/main-loop.o: nbproject/Makefile-${CND_CONF}.mk src/main-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/main-loop.o src/main-loop.c + ${OBJECTDIR}/src/main.o: nbproject/Makefile-${CND_CONF}.mk src/main.c ${MKDIR} -p ${OBJECTDIR}/src ${RM} "$@.d" diff --git a/nbproject/Makefile-Release.mk b/nbproject/Makefile-Release.mk index cf1bb2b..f01dbb9 100644 --- a/nbproject/Makefile-Release.mk +++ b/nbproject/Makefile-Release.mk @@ -42,6 +42,7 @@ OBJECTFILES= \ ${OBJECTDIR}/src/http-server.o \ ${OBJECTDIR}/src/http.o \ ${OBJECTDIR}/src/log.o \ + ${OBJECTDIR}/src/main-loop.o \ ${OBJECTDIR}/src/main.o \ ${OBJECTDIR}/src/mime.o \ ${OBJECTDIR}/src/queue.o \ @@ -109,6 +110,11 @@ ${OBJECTDIR}/src/log.o: nbproject/Makefile-${CND_CONF}.mk src/log.c ${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/log.o src/log.c +${OBJECTDIR}/src/main-loop.o: nbproject/Makefile-${CND_CONF}.mk src/main-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/main-loop.o src/main-loop.c + ${OBJECTDIR}/src/main.o: nbproject/Makefile-${CND_CONF}.mk src/main.c ${MKDIR} -p ${OBJECTDIR}/src ${RM} "$@.d" diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index d6f3804..97442ba 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -11,6 +11,7 @@ lib/http_parser.h lib/ini.h src/log.h + src/main-loop.h src/main.h src/mime.h src/queue.h @@ -32,6 +33,7 @@ lib/http_parser.c lib/ini.c src/log.c + src/main-loop.c src/main.c src/mime.c src/queue.c @@ -121,6 +123,10 @@ + + + + @@ -211,6 +217,10 @@ + + + + diff --git a/src/http-server.c b/src/http-server.c index ba37385..f03d6b3 100644 --- a/src/http-server.c +++ b/src/http-server.c @@ -265,7 +265,7 @@ FILE * server_generate_directory_index(config_host *hconfig, const char* dirpath char* file_mod_time = calloc(32, sizeof(char)); ctime_r(&file_mtime, file_mod_time); - utstring_printf(index, "%s%s%s\r\n", uri, + utstring_printf(index, "%s%s%s\r\n", uri, uri, (filesize!=NULL)?filesize:"N/A", (file_mod_time!=NULL)?file_mod_time:"N/A"); free(file_mod_time); diff --git a/src/log.c b/src/log.c index e2cc666..a5d8e29 100644 --- a/src/log.c +++ b/src/log.c @@ -29,7 +29,7 @@ log* log_new(const char* name, FILE *output) { l->name = calloc(strlen(name)+1, sizeof(char)); strcpy(l->name, name); l->running = false; - + l->output_closeonstop = false; return l; } void log_delete(log *l) { @@ -60,6 +60,21 @@ bool log_start(log *l) { return true; } +void log_stop(log *l) { + l->running = false; + close(l->pWrite); + if (pthread_equal(l->thread, pthread_self())!=0) { + pthread_detach(l->thread); + } else { + pthread_join(l->thread, NULL); + } + close(l->pRead); + if (l->output_closeonstop == true + && l->output != stdout + && l->output != stderr) { + fclose(l->output); + } +} void*log_loop(void* arg) { log *l = (log*)arg; void** buf = calloc(1, sizeof(void*)); @@ -90,16 +105,6 @@ void*log_loop(void* arg) { free(buf); free(timestr); } -void log_stop(log *l) { - l->running = false; - close(l->pWrite); - if (pthread_equal(l->thread, pthread_self())!=0) { - pthread_detach(l->thread); - } else { - pthread_join(l->thread, NULL); - } - close(l->pRead); -} void log_write(log *l, log_level level, const char* message) { if (l == NULL) { fprintf(stderr, "%s\n", message); @@ -110,6 +115,7 @@ void log_write(log *l, log_level level, const char* message) { } char* msgstr = calloc(strlen(message)+1, sizeof(char)); + strcpy(msgstr, message); log_msg *msg = log_msg_new(level, msgstr); write(l->pWrite, &msg, sizeof(log_msg*)); } diff --git a/src/log.h b/src/log.h index 9db9008..0dabdca 100644 --- a/src/log.h +++ b/src/log.h @@ -41,6 +41,7 @@ extern "C" { char* name; int pRead, pWrite; FILE *output; + bool output_closeonstop; pthread_t thread; bool running; } log; diff --git a/src/main-loop.c b/src/main-loop.c new file mode 100644 index 0000000..9d7b87d --- /dev/null +++ b/src/main-loop.c @@ -0,0 +1,114 @@ +#include +#include +#include + +#include "main-loop.h" +#include "mime.h" +#include "log.h" +#include "socket.h" +#include "thread-pool.h" +#include "queue.h" + +void hmain_setup(hmain_status **statusptr) { + hmain_status *status = *statusptr; + + if (status != NULL) { + fatal("hmain already setup"); + } + status = calloc(1, sizeof(hmain_status)); + + //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("khttpd.ini", config) < 0) { + fatal("Could not read config"); + } + status->config = config; + + //Open our listening socket + status->sfd = svr_create(); + svr_setnonblock(status->sfd); + svr_listen(status->sfd, status->config->listen_port); + + //Open epoll for socket + status->epollfd = epoll_create1(0); + if (status->epollfd < 0) { + fatal("Failed to create epollfd"); + } + + //Register socket with epoll + struct epoll_event svr_event; + svr_event.data.fd = status->sfd; + svr_event.events = EPOLLIN | EPOLLET; + if (epoll_ctl(s->epollfd, EPOLL_CTL_ADD, status->sfd, &svr_event) < 0) { + fatal("Could not register server socket with epoll"); + } + + //Create thread pools/queues + thread_pool *pool = thread_pool_new("read", queue_new()); + pool->min_threads = 1; + pool->max_threads = 2; + pool->func = thloop_read; + status->pool.read = pool; + + pool = thread_pool_new("write", queue_new()); + pool->min_threads = 1; + pool->max_threads = 2; + pool->func = thloop_write; + status->pool.write = pool; + + pool = thread_pool_new("disk_read", queue_new()); + pool->min_threads = 1; + pool->max_threads = 2; + pool->func = thloop_disk_read; + status->pool.disk_read = pool; + + pool = thread_pool_new("worker", queue_new()); + pool->min_threads = 1; + pool->max_threads = 5; + pool->func = thloop_worker; + status->pool.workers = pool; + +} +void hmain_teardown(hmain_status *status) { + if (status == NULL) { + fatal("hmain is not setup"); + } + //Close epoll + close(status->epollfd); + + //Close the listening connection + svr_release(status->sfd); + + //Cleanup the mime detector + mime_destroy(); + + //Stop and remove all loggers + log_register_clear(); + + //Delete the config and the status + config_server_delete(status->config); + free(status); +} +void hmain_loop(hmain_status *status) { + +} + +void* thloop_read(void * arg) { + +} +void* thloop_write(void * arg) { + +} +void* thloop_disk_read(void * arg){ + +} +void* thloop_worker(void * arg) { + +} \ No newline at end of file diff --git a/src/main-loop.h b/src/main-loop.h new file mode 100644 index 0000000..710fe7c --- /dev/null +++ b/src/main-loop.h @@ -0,0 +1,41 @@ +/* + * File: main-loop.h + * Author: sam + * + * Created on 07 August 2014, 18:44 + */ + +#ifndef MAIN_LOOP_H +#define MAIN_LOOP_H + +#include "config.h" +#include "thread-pool.h" + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct hmain_status { + config_server *config; + int sfd; + int epollfd; + struct { + thread_pool *read, *write, *workers, *disk_read; + } pool; + } hmain_status; + + void hmain_setup(hmain_status **statusptr); + void hmain_teardown(hmain_status *status); + void hmain_loop(hmain_status *status); + + void* thloop_read(void * arg); + void* thloop_write(void * arg); + void* thloop_disk_read(void * arg); + void* thloop_worker(void * arg); + +#ifdef __cplusplus +} +#endif + +#endif /* MAIN_LOOP_H */ + diff --git a/src/socket.c b/src/socket.c index f167950..f1c7fab 100644 --- a/src/socket.c +++ b/src/socket.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "socket.h" #include "ut/utstring.h" #include "main.h" @@ -127,12 +128,22 @@ void svr_listen(int fd, uint16_t port) { close(fd); fatal("Failed to bind to socket"); } - if (listen(fd, 16) < 0) { + if (listen(fd, SOMAXCONN) < 0) { close(fd); fatal("Could not set socket to listen mode"); } info("Listening on port %u", port); } +void svr_setnonblock(int fd) { + int flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) { + fatal("failed to set nonblocking on server socket"); + } + flags |= O_NONBLOCK; + if (fcntl(fd, F_SETFL, flags) < 0) { + fatal("failed to set nonblocking on server socket"); + } +} void svr_release(int fd) { if (close(fd) < 0) { warning(true, "could not close socket"); diff --git a/src/socket.h b/src/socket.h index 1233f9a..22e911a 100644 --- a/src/socket.h +++ b/src/socket.h @@ -47,6 +47,7 @@ extern "C" { int svr_create(); void svr_listen(int fd, uint16_t port); + void svr_setnonblock(int fd); void svr_release(int fd); bool svr_canaccept(int fd); skt_info* svr_accept(int fd);