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

@@ -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, "<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",
(file_mod_time!=NULL)?file_mod_time:"N/A");
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));
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*));
}

View File

@@ -41,6 +41,7 @@ extern "C" {
char* name;
int pRead, pWrite;
FILE *output;
bool output_closeonstop;
pthread_t thread;
bool running;
} 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 <poll.h>
#include <arpa/inet.h>
#include <fcntl.h>
#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");

View File

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