Working on new server loop
This commit is contained in:
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
28
src/log.c
28
src/log.c
@@ -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*));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
114
src/main-loop.c
Normal 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
41
src/main-loop.h
Normal 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 */
|
||||||
|
|
||||||
13
src/socket.c
13
src/socket.c
@@ -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");
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user