diff --git a/ChangeLog b/ChangeLog index aa58a80..6280440 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,14 @@ +2012-02-21 13:01:38 +0100 Georg Hopp + + * now when a constructor returns -1 the new call will in turn call the destructor effectively freeing all resources. ATTENTION: now the destructor has to be aware that it might be called with a not completely initialized object. To make this more ease there is the FREE makro with the corresponding ffree that does NULL pointer checking and the destructor checks for NULL pointer too. Additionally the handle_accept now handles _SC_OPEN_MAX - 10 connections. The 10 are reserved for internal usage. (HEAD, master) + +2012-02-21 09:45:01 +0100 Georg Hopp + + * now a child is spawned and writes random values in a shared memory segment. These values will be shown in the me action (origin/master, origin/HEAD) + 2012-02-20 21:36:55 +0100 Georg Hopp - * some code cleanups...no changes in the logic (HEAD, master) + * some code cleanups...no changes in the logic 2012-02-20 18:08:23 +0100 Georg Hopp @@ -8,7 +16,7 @@ 2012-02-20 17:16:44 +0100 Georg Hopp - * changed /**/ single line comments to // (origin/master, origin/HEAD) + * changed /**/ single line comments to // 2012-02-20 14:55:46 +0100 Georg Hopp diff --git a/include/interface/class.h b/include/interface/class.h index e99e258..5202a23 100644 --- a/include/interface/class.h +++ b/include/interface/class.h @@ -31,7 +31,7 @@ #include "class.h" #include "interface.h" -typedef void (* fptr_ctor)(void *, va_list *); +typedef int (* fptr_ctor)(void *, va_list *); typedef void (* fptr_dtor)(void *); typedef void (* fptr_clone)(void *, void * const); diff --git a/include/server.h b/include/server.h index 40d8817..9f5a0ef 100644 --- a/include/server.h +++ b/include/server.h @@ -33,33 +33,21 @@ #include "socket.h" #include "logger.h" - -#define POLL_FD_NSIZE 1024 -#define POLL_FD_SIZE (sizeof(struct pollfd) * POLL_FD_NSIZE) - -#define MOVE_SIZE(size,idx) ((size) * (POLL_FD_NSIZE-((idx)+1))) -#define CLEAR_CONN(server,idx) \ - memmove(&(((server)->fds)[(idx)]), \ - &(((server)->fds)[(idx)+1]), \ - MOVE_SIZE(sizeof(((server)->fds)[0]),(idx))); \ - memmove(&(((server)->conns)[(idx)]), \ - &(((server)->conns)[(idx)+1]), \ - MOVE_SIZE(sizeof(((server)->conns)[0]),(idx))) - +struct conns { + Sock sock; + void * worker; +}; CLASS(Server) { - Logger logger; - Sock sock; - - void * worker; + Logger logger; + Sock sock; + void * worker; - nfds_t nfds; - struct pollfd fds[POLL_FD_NSIZE]; + nfds_t nfds; + struct pollfd * fds; + long max_fds; - struct { - Sock sock; - void * worker; - } conns[POLL_FD_NSIZE]; + struct conns * conns; }; void serverRun(Server this); diff --git a/include/utils/memory.h b/include/utils/memory.h index 9ea0643..708bb8b 100644 --- a/include/utils/memory.h +++ b/include/utils/memory.h @@ -23,6 +23,8 @@ #ifndef __UTILS_MEMORY_H__ #define __UTILS_MEMORY_H__ +#define FREE(val) (ffree((void**)(val))) + void ffree(void **); #endif // __UTILS_MEMORY_H__ diff --git a/src/cbuf.c b/src/cbuf.c index 44b72b0..51468a0 100644 --- a/src/cbuf.c +++ b/src/cbuf.c @@ -42,7 +42,7 @@ static void dtor(void*); static -void +int ctor(void * _this, va_list * params) { Cbuf this = _this; @@ -104,6 +104,8 @@ ctor(void * _this, va_list * params) if (1 != state) { dtor(this); } + + return 0; } static diff --git a/src/http/header.c b/src/http/header.c index f85e060..df678d0 100644 --- a/src/http/header.c +++ b/src/http/header.c @@ -31,7 +31,7 @@ #include "utils/hash.h" static -void +int ctor(void * _this, va_list * params) { HttpHeader this = _this; char * name; @@ -47,6 +47,8 @@ ctor(void * _this, va_list * params) { this->value = malloc(strlen(value) + 1); strcpy(this->value, value); + + return 0; } static diff --git a/src/http/message.c b/src/http/message.c index f767c8f..2cd099b 100644 --- a/src/http/message.c +++ b/src/http/message.c @@ -46,7 +46,7 @@ tDelete(void * node) } static -void +int ctor(void * _this, va_list * params) { HttpMessage this = _this; @@ -54,6 +54,8 @@ ctor(void * _this, va_list * params) this->version = calloc(1, strlen(version)+1); strcpy(this->version, version); + + return 0; } static diff --git a/src/http/message/queue.c b/src/http/message/queue.c index 24cde8c..162c805 100644 --- a/src/http/message/queue.c +++ b/src/http/message/queue.c @@ -28,8 +28,11 @@ #include "http/message/queue.h" static -void -ctor(void * _this, va_list * params) {} +int +ctor(void * _this, va_list * params) +{ + return 0; +} static void diff --git a/src/http/request.c b/src/http/request.c index bc7ac34..4ac58bd 100644 --- a/src/http/request.c +++ b/src/http/request.c @@ -34,8 +34,11 @@ static -void -ctor(void * _this, va_list * params) {} +int +ctor(void * _this, va_list * params) +{ + return 0; +} static void diff --git a/src/http/request/parser.c b/src/http/request/parser.c index 327b388..7fe17ee 100644 --- a/src/http/request/parser.c +++ b/src/http/request/parser.c @@ -35,13 +35,15 @@ static -void +int ctor(void * _this, va_list * params) { HttpRequestParser this = _this; this->buffer = va_arg(* params, Cbuf); this->request_queue = new(HttpMessageQueue); + + return 0; } static diff --git a/src/http/response.c b/src/http/response.c index a9bf21a..1925aa8 100644 --- a/src/http/response.c +++ b/src/http/response.c @@ -35,7 +35,7 @@ static -void +int ctor(void * _this, va_list * params) { HttpResponse this = _this; @@ -48,6 +48,8 @@ ctor(void * _this, va_list * params) this->reason = calloc(1, strlen(reason)+1); strcpy(this->reason, reason); + + return 0; } static diff --git a/src/http/response/writer.c b/src/http/response/writer.c index be7aaa6..69a6512 100644 --- a/src/http/response/writer.c +++ b/src/http/response/writer.c @@ -30,13 +30,15 @@ #include "http/response/writer.h" static -void +int ctor(void * _this, va_list * params) { HttpResponseWriter this = _this; this->buffer = va_arg(*params, Cbuf); this->response_queue = new(HttpMessageQueue); + + return 0; } static diff --git a/src/http/worker.c b/src/http/worker.c index 7e3d849..c6d0907 100644 --- a/src/http/worker.c +++ b/src/http/worker.c @@ -15,7 +15,7 @@ #define SHMN "/worker_" static -void +int ctor(void * _this, va_list * params) { HttpWorker this = _this; @@ -35,6 +35,8 @@ ctor(void * _this, va_list * params) this->parser = new(HttpRequestParser, this->pbuf); this->writer = new(HttpResponseWriter, this->wbuf); + + return 0; } static diff --git a/src/interface/class.c b/src/interface/class.c index fd7db7e..a36e936 100644 --- a/src/interface/class.c +++ b/src/interface/class.c @@ -36,8 +36,9 @@ struct interface i_Class = { void * classNew(class_ptr class, ...) { - void * object = calloc(1, class->object_size + sizeof(void*)); + void * object = calloc(1, class->object_size + sizeof(void*)); va_list params; + int ret; if (class->init) class->init(); @@ -45,19 +46,25 @@ classNew(class_ptr class, ...) object += sizeof(void*); va_start(params, class); - CALL(object, Class, ctor, ¶ms); + RETCALL(object, Class, ctor, ret, ¶ms); va_end(params); + if (-1 == ret) { + classDelete(&object); + } + return object; } void classDelete(void ** object) { - CALL(*object, Class, dtor); + if (NULL != *object) { + CALL(*object, Class, dtor); - free(*object - sizeof(void*)); - *object = NULL; + free(*object - sizeof(void*)); + *object = NULL; + } } void * diff --git a/src/logger.c b/src/logger.c index 78f821d..3222af1 100644 --- a/src/logger.c +++ b/src/logger.c @@ -40,11 +40,13 @@ logger_level_str[] = { }; static -void +int ctor(void * _this, va_list * params) { Logger this = _this; this->min_level = va_arg(*params, int); + + return 0; } static void dtor(void * _this) {} diff --git a/src/server.c b/src/server.c index a9be60d..4bce23d 100644 --- a/src/server.c +++ b/src/server.c @@ -21,6 +21,8 @@ */ #include +#include +#include #include "class.h" #include "server.h" @@ -28,8 +30,10 @@ #include "logger.h" #include "interface/class.h" +#include "utils/memory.h" + static -void +int ctor(void * _this, va_list * params) { Server this = _this; @@ -37,12 +41,23 @@ ctor(void * _this, va_list * params) unsigned int backlog; int flags; + this->max_fds = sysconf(_SC_OPEN_MAX); + if (this->max_fds <= 10) { // reserve 10 handles for internal use. + /** + * \todo some logging would be appropriate :) + */ + return -1; + } + this->max_fds -= 10; + this->logger = va_arg(* params, Logger); this->worker = va_arg(* params, void *); port = va_arg(* params, int); backlog = va_arg(* params, unsigned int); - this->sock = new(Sock, this->logger, port); + this->fds = calloc(sizeof(struct pollfd), this->max_fds); + this->conns = calloc(sizeof(struct conns), this->max_fds); + this->sock = new(Sock, this->logger, port); flags = fcntl(this->sock->handle, F_GETFL, 0); fcntl(this->sock->handle, F_SETFL, flags | O_NONBLOCK); @@ -52,6 +67,8 @@ ctor(void * _this, va_list * params) (this->fds)[0].fd = this->sock->handle; (this->fds)[0].events = POLLIN; this->nfds = 1; + + return 0; } static @@ -68,6 +85,9 @@ dtor(void * _this) } } + FREE(&(this->fds)); + FREE(&(this->conns)); + delete(&this->sock); } diff --git a/src/server/handle_accept.c b/src/server/handle_accept.c index 2cb008c..6167ef8 100644 --- a/src/server/handle_accept.c +++ b/src/server/handle_accept.c @@ -33,7 +33,11 @@ int serverHandleAccept(Server this) { char remoteAddr[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; - Sock acc; + Sock acc = NULL; + + if (this->nfds >= this->max_fds) { + return -1; + } acc = socketAccept(this->sock, &remoteAddr); diff --git a/src/socket.c b/src/socket.c index c52750a..0a1c047 100644 --- a/src/socket.c +++ b/src/socket.c @@ -30,7 +30,7 @@ #include "interface/logger.h" static -void +int ctor(void * _this, va_list * params) { Sock this = _this; @@ -49,6 +49,8 @@ ctor(void * _this, va_list * params) //! Make the socket REUSE a TIME_WAIT socket setsockopt(this->handle, SOL_SOCKET, SO_REUSEADDR, &reUse, sizeof (reUse)); + + return 0; } static diff --git a/src/testserver.c b/src/testserver.c index 5ef4355..c32a9ae 100644 --- a/src/testserver.c +++ b/src/testserver.c @@ -63,6 +63,10 @@ main() struct rlimit limit = {RLIM_INFINITY, RLIM_INFINITY}; setrlimit(RLIMIT_CPU, &limit); + getrlimit(RLIMIT_NOFILE, &limit); + limit.rlim_cur = limit.rlim_max; + setrlimit(RLIMIT_NOFILE, &limit); + init_signals(); shm = shm_open("/fooshm", O_RDWR|O_CREAT, S_IRWXU); @@ -132,7 +136,13 @@ main() server = new(Server, logger, worker, 11212, SOMAXCONN); //daemonize(); - serverRun(server); + if (NULL != server) { + serverRun(server); + } + else { + doShutdown = 1; + kill(pid, SIGINT); + } do { pid_t w; @@ -155,9 +165,9 @@ main() } } while (!WIFEXITED(status) && !WIFSIGNALED(status)); - delete(&server); - delete(&worker); - delete(&logger); + if (NULL != server) delete(&server); + if (NULL != worker) delete(&worker); + if (NULL != logger) delete(&logger); } break;