Commit 424297cd5714c08b7916978376d211ec88a5cd24
1 parent
01ae8736
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.
Showing
19 changed files
with
114 additions
and
51 deletions
1 | +2012-02-21 13:01:38 +0100 Georg Hopp | ||
2 | + | ||
3 | + * 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) | ||
4 | + | ||
5 | +2012-02-21 09:45:01 +0100 Georg Hopp | ||
6 | + | ||
7 | + * 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) | ||
8 | + | ||
1 | 2012-02-20 21:36:55 +0100 Georg Hopp | 9 | 2012-02-20 21:36:55 +0100 Georg Hopp |
2 | 10 | ||
3 | - * some code cleanups...no changes in the logic (HEAD, master) | 11 | + * some code cleanups...no changes in the logic |
4 | 12 | ||
5 | 2012-02-20 18:08:23 +0100 Georg Hopp | 13 | 2012-02-20 18:08:23 +0100 Georg Hopp |
6 | 14 | ||
@@ -8,7 +16,7 @@ | @@ -8,7 +16,7 @@ | ||
8 | 16 | ||
9 | 2012-02-20 17:16:44 +0100 Georg Hopp | 17 | 2012-02-20 17:16:44 +0100 Georg Hopp |
10 | 18 | ||
11 | - * changed /**/ single line comments to // (origin/master, origin/HEAD) | 19 | + * changed /**/ single line comments to // |
12 | 20 | ||
13 | 2012-02-20 14:55:46 +0100 Georg Hopp | 21 | 2012-02-20 14:55:46 +0100 Georg Hopp |
14 | 22 |
@@ -31,7 +31,7 @@ | @@ -31,7 +31,7 @@ | ||
31 | #include "class.h" | 31 | #include "class.h" |
32 | #include "interface.h" | 32 | #include "interface.h" |
33 | 33 | ||
34 | -typedef void (* fptr_ctor)(void *, va_list *); | 34 | +typedef int (* fptr_ctor)(void *, va_list *); |
35 | typedef void (* fptr_dtor)(void *); | 35 | typedef void (* fptr_dtor)(void *); |
36 | typedef void (* fptr_clone)(void *, void * const); | 36 | typedef void (* fptr_clone)(void *, void * const); |
37 | 37 |
@@ -33,33 +33,21 @@ | @@ -33,33 +33,21 @@ | ||
33 | #include "socket.h" | 33 | #include "socket.h" |
34 | #include "logger.h" | 34 | #include "logger.h" |
35 | 35 | ||
36 | - | ||
37 | -#define POLL_FD_NSIZE 1024 | ||
38 | -#define POLL_FD_SIZE (sizeof(struct pollfd) * POLL_FD_NSIZE) | ||
39 | - | ||
40 | -#define MOVE_SIZE(size,idx) ((size) * (POLL_FD_NSIZE-((idx)+1))) | ||
41 | -#define CLEAR_CONN(server,idx) \ | ||
42 | - memmove(&(((server)->fds)[(idx)]), \ | ||
43 | - &(((server)->fds)[(idx)+1]), \ | ||
44 | - MOVE_SIZE(sizeof(((server)->fds)[0]),(idx))); \ | ||
45 | - memmove(&(((server)->conns)[(idx)]), \ | ||
46 | - &(((server)->conns)[(idx)+1]), \ | ||
47 | - MOVE_SIZE(sizeof(((server)->conns)[0]),(idx))) | ||
48 | - | 36 | +struct conns { |
37 | + Sock sock; | ||
38 | + void * worker; | ||
39 | +}; | ||
49 | 40 | ||
50 | CLASS(Server) { | 41 | CLASS(Server) { |
51 | - Logger logger; | ||
52 | - Sock sock; | ||
53 | - | ||
54 | - void * worker; | 42 | + Logger logger; |
43 | + Sock sock; | ||
44 | + void * worker; | ||
55 | 45 | ||
56 | - nfds_t nfds; | ||
57 | - struct pollfd fds[POLL_FD_NSIZE]; | 46 | + nfds_t nfds; |
47 | + struct pollfd * fds; | ||
48 | + long max_fds; | ||
58 | 49 | ||
59 | - struct { | ||
60 | - Sock sock; | ||
61 | - void * worker; | ||
62 | - } conns[POLL_FD_NSIZE]; | 50 | + struct conns * conns; |
63 | }; | 51 | }; |
64 | 52 | ||
65 | void serverRun(Server this); | 53 | void serverRun(Server this); |
@@ -23,6 +23,8 @@ | @@ -23,6 +23,8 @@ | ||
23 | #ifndef __UTILS_MEMORY_H__ | 23 | #ifndef __UTILS_MEMORY_H__ |
24 | #define __UTILS_MEMORY_H__ | 24 | #define __UTILS_MEMORY_H__ |
25 | 25 | ||
26 | +#define FREE(val) (ffree((void**)(val))) | ||
27 | + | ||
26 | void ffree(void **); | 28 | void ffree(void **); |
27 | 29 | ||
28 | #endif // __UTILS_MEMORY_H__ | 30 | #endif // __UTILS_MEMORY_H__ |
@@ -42,7 +42,7 @@ | @@ -42,7 +42,7 @@ | ||
42 | static void dtor(void*); | 42 | static void dtor(void*); |
43 | 43 | ||
44 | static | 44 | static |
45 | -void | 45 | +int |
46 | ctor(void * _this, va_list * params) | 46 | ctor(void * _this, va_list * params) |
47 | { | 47 | { |
48 | Cbuf this = _this; | 48 | Cbuf this = _this; |
@@ -104,6 +104,8 @@ ctor(void * _this, va_list * params) | @@ -104,6 +104,8 @@ ctor(void * _this, va_list * params) | ||
104 | if (1 != state) { | 104 | if (1 != state) { |
105 | dtor(this); | 105 | dtor(this); |
106 | } | 106 | } |
107 | + | ||
108 | + return 0; | ||
107 | } | 109 | } |
108 | 110 | ||
109 | static | 111 | static |
@@ -31,7 +31,7 @@ | @@ -31,7 +31,7 @@ | ||
31 | #include "utils/hash.h" | 31 | #include "utils/hash.h" |
32 | 32 | ||
33 | static | 33 | static |
34 | -void | 34 | +int |
35 | ctor(void * _this, va_list * params) { | 35 | ctor(void * _this, va_list * params) { |
36 | HttpHeader this = _this; | 36 | HttpHeader this = _this; |
37 | char * name; | 37 | char * name; |
@@ -47,6 +47,8 @@ ctor(void * _this, va_list * params) { | @@ -47,6 +47,8 @@ ctor(void * _this, va_list * params) { | ||
47 | 47 | ||
48 | this->value = malloc(strlen(value) + 1); | 48 | this->value = malloc(strlen(value) + 1); |
49 | strcpy(this->value, value); | 49 | strcpy(this->value, value); |
50 | + | ||
51 | + return 0; | ||
50 | } | 52 | } |
51 | 53 | ||
52 | static | 54 | static |
@@ -46,7 +46,7 @@ tDelete(void * node) | @@ -46,7 +46,7 @@ tDelete(void * node) | ||
46 | } | 46 | } |
47 | 47 | ||
48 | static | 48 | static |
49 | -void | 49 | +int |
50 | ctor(void * _this, va_list * params) | 50 | ctor(void * _this, va_list * params) |
51 | { | 51 | { |
52 | HttpMessage this = _this; | 52 | HttpMessage this = _this; |
@@ -54,6 +54,8 @@ ctor(void * _this, va_list * params) | @@ -54,6 +54,8 @@ ctor(void * _this, va_list * params) | ||
54 | 54 | ||
55 | this->version = calloc(1, strlen(version)+1); | 55 | this->version = calloc(1, strlen(version)+1); |
56 | strcpy(this->version, version); | 56 | strcpy(this->version, version); |
57 | + | ||
58 | + return 0; | ||
57 | } | 59 | } |
58 | 60 | ||
59 | static | 61 | static |
@@ -28,8 +28,11 @@ | @@ -28,8 +28,11 @@ | ||
28 | #include "http/message/queue.h" | 28 | #include "http/message/queue.h" |
29 | 29 | ||
30 | static | 30 | static |
31 | -void | ||
32 | -ctor(void * _this, va_list * params) {} | 31 | +int |
32 | +ctor(void * _this, va_list * params) | ||
33 | +{ | ||
34 | + return 0; | ||
35 | +} | ||
33 | 36 | ||
34 | static | 37 | static |
35 | void | 38 | void |
@@ -35,13 +35,15 @@ | @@ -35,13 +35,15 @@ | ||
35 | 35 | ||
36 | 36 | ||
37 | static | 37 | static |
38 | -void | 38 | +int |
39 | ctor(void * _this, va_list * params) | 39 | ctor(void * _this, va_list * params) |
40 | { | 40 | { |
41 | HttpRequestParser this = _this; | 41 | HttpRequestParser this = _this; |
42 | 42 | ||
43 | this->buffer = va_arg(* params, Cbuf); | 43 | this->buffer = va_arg(* params, Cbuf); |
44 | this->request_queue = new(HttpMessageQueue); | 44 | this->request_queue = new(HttpMessageQueue); |
45 | + | ||
46 | + return 0; | ||
45 | } | 47 | } |
46 | 48 | ||
47 | static | 49 | static |
@@ -35,7 +35,7 @@ | @@ -35,7 +35,7 @@ | ||
35 | 35 | ||
36 | 36 | ||
37 | static | 37 | static |
38 | -void | 38 | +int |
39 | ctor(void * _this, va_list * params) | 39 | ctor(void * _this, va_list * params) |
40 | { | 40 | { |
41 | HttpResponse this = _this; | 41 | HttpResponse this = _this; |
@@ -48,6 +48,8 @@ ctor(void * _this, va_list * params) | @@ -48,6 +48,8 @@ ctor(void * _this, va_list * params) | ||
48 | 48 | ||
49 | this->reason = calloc(1, strlen(reason)+1); | 49 | this->reason = calloc(1, strlen(reason)+1); |
50 | strcpy(this->reason, reason); | 50 | strcpy(this->reason, reason); |
51 | + | ||
52 | + return 0; | ||
51 | } | 53 | } |
52 | 54 | ||
53 | static | 55 | static |
@@ -30,13 +30,15 @@ | @@ -30,13 +30,15 @@ | ||
30 | #include "http/response/writer.h" | 30 | #include "http/response/writer.h" |
31 | 31 | ||
32 | static | 32 | static |
33 | -void | 33 | +int |
34 | ctor(void * _this, va_list * params) | 34 | ctor(void * _this, va_list * params) |
35 | { | 35 | { |
36 | HttpResponseWriter this = _this; | 36 | HttpResponseWriter this = _this; |
37 | 37 | ||
38 | this->buffer = va_arg(*params, Cbuf); | 38 | this->buffer = va_arg(*params, Cbuf); |
39 | this->response_queue = new(HttpMessageQueue); | 39 | this->response_queue = new(HttpMessageQueue); |
40 | + | ||
41 | + return 0; | ||
40 | } | 42 | } |
41 | 43 | ||
42 | static | 44 | static |
@@ -15,7 +15,7 @@ | @@ -15,7 +15,7 @@ | ||
15 | 15 | ||
16 | #define SHMN "/worker_" | 16 | #define SHMN "/worker_" |
17 | static | 17 | static |
18 | -void | 18 | +int |
19 | ctor(void * _this, va_list * params) | 19 | ctor(void * _this, va_list * params) |
20 | { | 20 | { |
21 | HttpWorker this = _this; | 21 | HttpWorker this = _this; |
@@ -35,6 +35,8 @@ ctor(void * _this, va_list * params) | @@ -35,6 +35,8 @@ ctor(void * _this, va_list * params) | ||
35 | 35 | ||
36 | this->parser = new(HttpRequestParser, this->pbuf); | 36 | this->parser = new(HttpRequestParser, this->pbuf); |
37 | this->writer = new(HttpResponseWriter, this->wbuf); | 37 | this->writer = new(HttpResponseWriter, this->wbuf); |
38 | + | ||
39 | + return 0; | ||
38 | } | 40 | } |
39 | 41 | ||
40 | static | 42 | static |
@@ -36,8 +36,9 @@ struct interface i_Class = { | @@ -36,8 +36,9 @@ struct interface i_Class = { | ||
36 | void * | 36 | void * |
37 | classNew(class_ptr class, ...) | 37 | classNew(class_ptr class, ...) |
38 | { | 38 | { |
39 | - void * object = calloc(1, class->object_size + sizeof(void*)); | 39 | + void * object = calloc(1, class->object_size + sizeof(void*)); |
40 | va_list params; | 40 | va_list params; |
41 | + int ret; | ||
41 | 42 | ||
42 | if (class->init) class->init(); | 43 | if (class->init) class->init(); |
43 | 44 | ||
@@ -45,19 +46,25 @@ classNew(class_ptr class, ...) | @@ -45,19 +46,25 @@ classNew(class_ptr class, ...) | ||
45 | object += sizeof(void*); | 46 | object += sizeof(void*); |
46 | 47 | ||
47 | va_start(params, class); | 48 | va_start(params, class); |
48 | - CALL(object, Class, ctor, ¶ms); | 49 | + RETCALL(object, Class, ctor, ret, ¶ms); |
49 | va_end(params); | 50 | va_end(params); |
50 | 51 | ||
52 | + if (-1 == ret) { | ||
53 | + classDelete(&object); | ||
54 | + } | ||
55 | + | ||
51 | return object; | 56 | return object; |
52 | } | 57 | } |
53 | 58 | ||
54 | void | 59 | void |
55 | classDelete(void ** object) | 60 | classDelete(void ** object) |
56 | { | 61 | { |
57 | - CALL(*object, Class, dtor); | 62 | + if (NULL != *object) { |
63 | + CALL(*object, Class, dtor); | ||
58 | 64 | ||
59 | - free(*object - sizeof(void*)); | ||
60 | - *object = NULL; | 65 | + free(*object - sizeof(void*)); |
66 | + *object = NULL; | ||
67 | + } | ||
61 | } | 68 | } |
62 | 69 | ||
63 | void * | 70 | void * |
@@ -40,11 +40,13 @@ logger_level_str[] = { | @@ -40,11 +40,13 @@ logger_level_str[] = { | ||
40 | }; | 40 | }; |
41 | 41 | ||
42 | static | 42 | static |
43 | -void | 43 | +int |
44 | ctor(void * _this, va_list * params) | 44 | ctor(void * _this, va_list * params) |
45 | { | 45 | { |
46 | Logger this = _this; | 46 | Logger this = _this; |
47 | this->min_level = va_arg(*params, int); | 47 | this->min_level = va_arg(*params, int); |
48 | + | ||
49 | + return 0; | ||
48 | } | 50 | } |
49 | 51 | ||
50 | static void dtor(void * _this) {} | 52 | static void dtor(void * _this) {} |
@@ -21,6 +21,8 @@ | @@ -21,6 +21,8 @@ | ||
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <fcntl.h> | 23 | #include <fcntl.h> |
24 | +#include <unistd.h> | ||
25 | +#include <stdlib.h> | ||
24 | 26 | ||
25 | #include "class.h" | 27 | #include "class.h" |
26 | #include "server.h" | 28 | #include "server.h" |
@@ -28,8 +30,10 @@ | @@ -28,8 +30,10 @@ | ||
28 | #include "logger.h" | 30 | #include "logger.h" |
29 | #include "interface/class.h" | 31 | #include "interface/class.h" |
30 | 32 | ||
33 | +#include "utils/memory.h" | ||
34 | + | ||
31 | static | 35 | static |
32 | -void | 36 | +int |
33 | ctor(void * _this, va_list * params) | 37 | ctor(void * _this, va_list * params) |
34 | { | 38 | { |
35 | Server this = _this; | 39 | Server this = _this; |
@@ -37,12 +41,23 @@ ctor(void * _this, va_list * params) | @@ -37,12 +41,23 @@ ctor(void * _this, va_list * params) | ||
37 | unsigned int backlog; | 41 | unsigned int backlog; |
38 | int flags; | 42 | int flags; |
39 | 43 | ||
44 | + this->max_fds = sysconf(_SC_OPEN_MAX); | ||
45 | + if (this->max_fds <= 10) { // reserve 10 handles for internal use. | ||
46 | + /** | ||
47 | + * \todo some logging would be appropriate :) | ||
48 | + */ | ||
49 | + return -1; | ||
50 | + } | ||
51 | + this->max_fds -= 10; | ||
52 | + | ||
40 | this->logger = va_arg(* params, Logger); | 53 | this->logger = va_arg(* params, Logger); |
41 | this->worker = va_arg(* params, void *); | 54 | this->worker = va_arg(* params, void *); |
42 | port = va_arg(* params, int); | 55 | port = va_arg(* params, int); |
43 | backlog = va_arg(* params, unsigned int); | 56 | backlog = va_arg(* params, unsigned int); |
44 | 57 | ||
45 | - this->sock = new(Sock, this->logger, port); | 58 | + this->fds = calloc(sizeof(struct pollfd), this->max_fds); |
59 | + this->conns = calloc(sizeof(struct conns), this->max_fds); | ||
60 | + this->sock = new(Sock, this->logger, port); | ||
46 | 61 | ||
47 | flags = fcntl(this->sock->handle, F_GETFL, 0); | 62 | flags = fcntl(this->sock->handle, F_GETFL, 0); |
48 | fcntl(this->sock->handle, F_SETFL, flags | O_NONBLOCK); | 63 | fcntl(this->sock->handle, F_SETFL, flags | O_NONBLOCK); |
@@ -52,6 +67,8 @@ ctor(void * _this, va_list * params) | @@ -52,6 +67,8 @@ ctor(void * _this, va_list * params) | ||
52 | (this->fds)[0].fd = this->sock->handle; | 67 | (this->fds)[0].fd = this->sock->handle; |
53 | (this->fds)[0].events = POLLIN; | 68 | (this->fds)[0].events = POLLIN; |
54 | this->nfds = 1; | 69 | this->nfds = 1; |
70 | + | ||
71 | + return 0; | ||
55 | } | 72 | } |
56 | 73 | ||
57 | static | 74 | static |
@@ -68,6 +85,9 @@ dtor(void * _this) | @@ -68,6 +85,9 @@ dtor(void * _this) | ||
68 | } | 85 | } |
69 | } | 86 | } |
70 | 87 | ||
88 | + FREE(&(this->fds)); | ||
89 | + FREE(&(this->conns)); | ||
90 | + | ||
71 | delete(&this->sock); | 91 | delete(&this->sock); |
72 | } | 92 | } |
73 | 93 |
@@ -33,7 +33,11 @@ int | @@ -33,7 +33,11 @@ int | ||
33 | serverHandleAccept(Server this) | 33 | serverHandleAccept(Server this) |
34 | { | 34 | { |
35 | char remoteAddr[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; | 35 | char remoteAddr[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; |
36 | - Sock acc; | 36 | + Sock acc = NULL; |
37 | + | ||
38 | + if (this->nfds >= this->max_fds) { | ||
39 | + return -1; | ||
40 | + } | ||
37 | 41 | ||
38 | acc = socketAccept(this->sock, &remoteAddr); | 42 | acc = socketAccept(this->sock, &remoteAddr); |
39 | 43 |
@@ -30,7 +30,7 @@ | @@ -30,7 +30,7 @@ | ||
30 | #include "interface/logger.h" | 30 | #include "interface/logger.h" |
31 | 31 | ||
32 | static | 32 | static |
33 | -void | 33 | +int |
34 | ctor(void * _this, va_list * params) | 34 | ctor(void * _this, va_list * params) |
35 | { | 35 | { |
36 | Sock this = _this; | 36 | Sock this = _this; |
@@ -49,6 +49,8 @@ ctor(void * _this, va_list * params) | @@ -49,6 +49,8 @@ ctor(void * _this, va_list * params) | ||
49 | 49 | ||
50 | //! Make the socket REUSE a TIME_WAIT socket | 50 | //! Make the socket REUSE a TIME_WAIT socket |
51 | setsockopt(this->handle, SOL_SOCKET, SO_REUSEADDR, &reUse, sizeof (reUse)); | 51 | setsockopt(this->handle, SOL_SOCKET, SO_REUSEADDR, &reUse, sizeof (reUse)); |
52 | + | ||
53 | + return 0; | ||
52 | } | 54 | } |
53 | 55 | ||
54 | static | 56 | static |
@@ -63,6 +63,10 @@ main() | @@ -63,6 +63,10 @@ main() | ||
63 | struct rlimit limit = {RLIM_INFINITY, RLIM_INFINITY}; | 63 | struct rlimit limit = {RLIM_INFINITY, RLIM_INFINITY}; |
64 | setrlimit(RLIMIT_CPU, &limit); | 64 | setrlimit(RLIMIT_CPU, &limit); |
65 | 65 | ||
66 | + getrlimit(RLIMIT_NOFILE, &limit); | ||
67 | + limit.rlim_cur = limit.rlim_max; | ||
68 | + setrlimit(RLIMIT_NOFILE, &limit); | ||
69 | + | ||
66 | init_signals(); | 70 | init_signals(); |
67 | 71 | ||
68 | shm = shm_open("/fooshm", O_RDWR|O_CREAT, S_IRWXU); | 72 | shm = shm_open("/fooshm", O_RDWR|O_CREAT, S_IRWXU); |
@@ -132,7 +136,13 @@ main() | @@ -132,7 +136,13 @@ main() | ||
132 | server = new(Server, logger, worker, 11212, SOMAXCONN); | 136 | server = new(Server, logger, worker, 11212, SOMAXCONN); |
133 | 137 | ||
134 | //daemonize(); | 138 | //daemonize(); |
135 | - serverRun(server); | 139 | + if (NULL != server) { |
140 | + serverRun(server); | ||
141 | + } | ||
142 | + else { | ||
143 | + doShutdown = 1; | ||
144 | + kill(pid, SIGINT); | ||
145 | + } | ||
136 | 146 | ||
137 | do { | 147 | do { |
138 | pid_t w; | 148 | pid_t w; |
@@ -155,9 +165,9 @@ main() | @@ -155,9 +165,9 @@ main() | ||
155 | } | 165 | } |
156 | } while (!WIFEXITED(status) && !WIFSIGNALED(status)); | 166 | } while (!WIFEXITED(status) && !WIFSIGNALED(status)); |
157 | 167 | ||
158 | - delete(&server); | ||
159 | - delete(&worker); | ||
160 | - delete(&logger); | 168 | + if (NULL != server) delete(&server); |
169 | + if (NULL != worker) delete(&worker); | ||
170 | + if (NULL != logger) delete(&logger); | ||
161 | } | 171 | } |
162 | 172 | ||
163 | break; | 173 | break; |
Please
register
or
login
to post a comment