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);