Working on new server loop

This commit is contained in:
2014-08-07 21:36:37 +01:00
parent 40c29b190b
commit a52023a711
10 changed files with 209 additions and 13 deletions

View File

@@ -42,6 +42,7 @@ OBJECTFILES= \
${OBJECTDIR}/src/http-server.o \ ${OBJECTDIR}/src/http-server.o \
${OBJECTDIR}/src/http.o \ ${OBJECTDIR}/src/http.o \
${OBJECTDIR}/src/log.o \ ${OBJECTDIR}/src/log.o \
${OBJECTDIR}/src/main-loop.o \
${OBJECTDIR}/src/main.o \ ${OBJECTDIR}/src/main.o \
${OBJECTDIR}/src/mime.o \ ${OBJECTDIR}/src/mime.o \
${OBJECTDIR}/src/queue.o \ ${OBJECTDIR}/src/queue.o \
@@ -109,6 +110,11 @@ ${OBJECTDIR}/src/log.o: nbproject/Makefile-${CND_CONF}.mk src/log.c
${RM} "$@.d" ${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 $(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 ${OBJECTDIR}/src/main.o: nbproject/Makefile-${CND_CONF}.mk src/main.c
${MKDIR} -p ${OBJECTDIR}/src ${MKDIR} -p ${OBJECTDIR}/src
${RM} "$@.d" ${RM} "$@.d"

View File

@@ -42,6 +42,7 @@ OBJECTFILES= \
${OBJECTDIR}/src/http-server.o \ ${OBJECTDIR}/src/http-server.o \
${OBJECTDIR}/src/http.o \ ${OBJECTDIR}/src/http.o \
${OBJECTDIR}/src/log.o \ ${OBJECTDIR}/src/log.o \
${OBJECTDIR}/src/main-loop.o \
${OBJECTDIR}/src/main.o \ ${OBJECTDIR}/src/main.o \
${OBJECTDIR}/src/mime.o \ ${OBJECTDIR}/src/mime.o \
${OBJECTDIR}/src/queue.o \ ${OBJECTDIR}/src/queue.o \
@@ -109,6 +110,11 @@ ${OBJECTDIR}/src/log.o: nbproject/Makefile-${CND_CONF}.mk src/log.c
${RM} "$@.d" ${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 $(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 ${OBJECTDIR}/src/main.o: nbproject/Makefile-${CND_CONF}.mk src/main.c
${MKDIR} -p ${OBJECTDIR}/src ${MKDIR} -p ${OBJECTDIR}/src
${RM} "$@.d" ${RM} "$@.d"

View File

@@ -11,6 +11,7 @@
<itemPath>lib/http_parser.h</itemPath> <itemPath>lib/http_parser.h</itemPath>
<itemPath>lib/ini.h</itemPath> <itemPath>lib/ini.h</itemPath>
<itemPath>src/log.h</itemPath> <itemPath>src/log.h</itemPath>
<itemPath>src/main-loop.h</itemPath>
<itemPath>src/main.h</itemPath> <itemPath>src/main.h</itemPath>
<itemPath>src/mime.h</itemPath> <itemPath>src/mime.h</itemPath>
<itemPath>src/queue.h</itemPath> <itemPath>src/queue.h</itemPath>
@@ -32,6 +33,7 @@
<itemPath>lib/http_parser.c</itemPath> <itemPath>lib/http_parser.c</itemPath>
<itemPath>lib/ini.c</itemPath> <itemPath>lib/ini.c</itemPath>
<itemPath>src/log.c</itemPath> <itemPath>src/log.c</itemPath>
<itemPath>src/main-loop.c</itemPath>
<itemPath>src/main.c</itemPath> <itemPath>src/main.c</itemPath>
<itemPath>src/mime.c</itemPath> <itemPath>src/mime.c</itemPath>
<itemPath>src/queue.c</itemPath> <itemPath>src/queue.c</itemPath>
@@ -121,6 +123,10 @@
</item> </item>
<item path="src/log.h" ex="false" tool="3" flavor2="0"> <item path="src/log.h" ex="false" tool="3" flavor2="0">
</item> </item>
<item path="src/main-loop.c" ex="false" tool="0" flavor2="0">
</item>
<item path="src/main-loop.h" ex="false" tool="3" flavor2="0">
</item>
<item path="src/main.c" ex="false" tool="0" flavor2="0"> <item path="src/main.c" ex="false" tool="0" flavor2="0">
</item> </item>
<item path="src/main.h" ex="false" tool="3" flavor2="0"> <item path="src/main.h" ex="false" tool="3" flavor2="0">
@@ -211,6 +217,10 @@
</item> </item>
<item path="src/log.h" ex="false" tool="3" flavor2="0"> <item path="src/log.h" ex="false" tool="3" flavor2="0">
</item> </item>
<item path="src/main-loop.c" ex="false" tool="0" flavor2="0">
</item>
<item path="src/main-loop.h" ex="false" tool="3" flavor2="0">
</item>
<item path="src/main.c" ex="false" tool="0" flavor2="0"> <item path="src/main.c" ex="false" tool="0" flavor2="0">
</item> </item>
<item path="src/main.h" ex="false" tool="3" flavor2="0"> <item path="src/main.h" ex="false" tool="3" flavor2="0">

View File

@@ -265,7 +265,7 @@ FILE * server_generate_directory_index(config_host *hconfig, const char* dirpath
char* file_mod_time = calloc(32, sizeof(char)); char* file_mod_time = calloc(32, sizeof(char));
ctime_r(&file_mtime, file_mod_time); ctime_r(&file_mtime, file_mod_time);
utstring_printf(index, "<tr><td>%s</td><td>%s</td><td>%s</td></tr>\r\n", uri, utstring_printf(index, "<tr><td><a href=\"%s\">%s</a></td><td>%s</td><td>%s</td></tr>\r\n", uri, uri,
(filesize!=NULL)?filesize:"N/A", (filesize!=NULL)?filesize:"N/A",
(file_mod_time!=NULL)?file_mod_time:"N/A"); (file_mod_time!=NULL)?file_mod_time:"N/A");
free(file_mod_time); free(file_mod_time);

View File

@@ -29,7 +29,7 @@ log* log_new(const char* name, FILE *output) {
l->name = calloc(strlen(name)+1, sizeof(char)); l->name = calloc(strlen(name)+1, sizeof(char));
strcpy(l->name, name); strcpy(l->name, name);
l->running = false; l->running = false;
l->output_closeonstop = false;
return l; return l;
} }
void log_delete(log *l) { void log_delete(log *l) {
@@ -60,6 +60,21 @@ bool log_start(log *l) {
return true; 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) { void*log_loop(void* arg) {
log *l = (log*)arg; log *l = (log*)arg;
void** buf = calloc(1, sizeof(void*)); void** buf = calloc(1, sizeof(void*));
@@ -90,16 +105,6 @@ void*log_loop(void* arg) {
free(buf); free(buf);
free(timestr); 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) { void log_write(log *l, log_level level, const char* message) {
if (l == NULL) { if (l == NULL) {
fprintf(stderr, "%s\n", message); 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)); char* msgstr = calloc(strlen(message)+1, sizeof(char));
strcpy(msgstr, message);
log_msg *msg = log_msg_new(level, msgstr); log_msg *msg = log_msg_new(level, msgstr);
write(l->pWrite, &msg, sizeof(log_msg*)); write(l->pWrite, &msg, sizeof(log_msg*));
} }

View File

@@ -41,6 +41,7 @@ extern "C" {
char* name; char* name;
int pRead, pWrite; int pRead, pWrite;
FILE *output; FILE *output;
bool output_closeonstop;
pthread_t thread; pthread_t thread;
bool running; bool running;
} log; } log;

114
src/main-loop.c Normal file
View File

@@ -0,0 +1,114 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/epoll.h>
#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) {
}

41
src/main-loop.h Normal file
View File

@@ -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 */

View File

@@ -11,6 +11,7 @@
#include <errno.h> #include <errno.h>
#include <poll.h> #include <poll.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <fcntl.h>
#include "socket.h" #include "socket.h"
#include "ut/utstring.h" #include "ut/utstring.h"
#include "main.h" #include "main.h"
@@ -127,12 +128,22 @@ void svr_listen(int fd, uint16_t port) {
close(fd); close(fd);
fatal("Failed to bind to socket"); fatal("Failed to bind to socket");
} }
if (listen(fd, 16) < 0) { if (listen(fd, SOMAXCONN) < 0) {
close(fd); close(fd);
fatal("Could not set socket to listen mode"); fatal("Could not set socket to listen mode");
} }
info("Listening on port %u", port); 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) { void svr_release(int fd) {
if (close(fd) < 0) { if (close(fd) < 0) {
warning(true, "could not close socket"); warning(true, "could not close socket");

View File

@@ -47,6 +47,7 @@ extern "C" {
int svr_create(); int svr_create();
void svr_listen(int fd, uint16_t port); void svr_listen(int fd, uint16_t port);
void svr_setnonblock(int fd);
void svr_release(int fd); void svr_release(int fd);
bool svr_canaccept(int fd); bool svr_canaccept(int fd);
skt_info* svr_accept(int fd); skt_info* svr_accept(int fd);