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 | 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 | 13 | 2012-02-20 18:08:23 +0100 Georg Hopp |
6 | 14 | |
... | ... | @@ -8,7 +16,7 @@ |
8 | 16 | |
9 | 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 | 21 | 2012-02-20 14:55:46 +0100 Georg Hopp |
14 | 22 | ... | ... |
... | ... | @@ -33,33 +33,21 @@ |
33 | 33 | #include "socket.h" |
34 | 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 | 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 | 53 | void serverRun(Server this); | ... | ... |
... | ... | @@ -42,7 +42,7 @@ |
42 | 42 | static void dtor(void*); |
43 | 43 | |
44 | 44 | static |
45 | -void | |
45 | +int | |
46 | 46 | ctor(void * _this, va_list * params) |
47 | 47 | { |
48 | 48 | Cbuf this = _this; |
... | ... | @@ -104,6 +104,8 @@ ctor(void * _this, va_list * params) |
104 | 104 | if (1 != state) { |
105 | 105 | dtor(this); |
106 | 106 | } |
107 | + | |
108 | + return 0; | |
107 | 109 | } |
108 | 110 | |
109 | 111 | static | ... | ... |
... | ... | @@ -31,7 +31,7 @@ |
31 | 31 | #include "utils/hash.h" |
32 | 32 | |
33 | 33 | static |
34 | -void | |
34 | +int | |
35 | 35 | ctor(void * _this, va_list * params) { |
36 | 36 | HttpHeader this = _this; |
37 | 37 | char * name; |
... | ... | @@ -47,6 +47,8 @@ ctor(void * _this, va_list * params) { |
47 | 47 | |
48 | 48 | this->value = malloc(strlen(value) + 1); |
49 | 49 | strcpy(this->value, value); |
50 | + | |
51 | + return 0; | |
50 | 52 | } |
51 | 53 | |
52 | 54 | static | ... | ... |
... | ... | @@ -46,7 +46,7 @@ tDelete(void * node) |
46 | 46 | } |
47 | 47 | |
48 | 48 | static |
49 | -void | |
49 | +int | |
50 | 50 | ctor(void * _this, va_list * params) |
51 | 51 | { |
52 | 52 | HttpMessage this = _this; |
... | ... | @@ -54,6 +54,8 @@ ctor(void * _this, va_list * params) |
54 | 54 | |
55 | 55 | this->version = calloc(1, strlen(version)+1); |
56 | 56 | strcpy(this->version, version); |
57 | + | |
58 | + return 0; | |
57 | 59 | } |
58 | 60 | |
59 | 61 | static | ... | ... |
... | ... | @@ -35,13 +35,15 @@ |
35 | 35 | |
36 | 36 | |
37 | 37 | static |
38 | -void | |
38 | +int | |
39 | 39 | ctor(void * _this, va_list * params) |
40 | 40 | { |
41 | 41 | HttpRequestParser this = _this; |
42 | 42 | |
43 | 43 | this->buffer = va_arg(* params, Cbuf); |
44 | 44 | this->request_queue = new(HttpMessageQueue); |
45 | + | |
46 | + return 0; | |
45 | 47 | } |
46 | 48 | |
47 | 49 | static | ... | ... |
... | ... | @@ -35,7 +35,7 @@ |
35 | 35 | |
36 | 36 | |
37 | 37 | static |
38 | -void | |
38 | +int | |
39 | 39 | ctor(void * _this, va_list * params) |
40 | 40 | { |
41 | 41 | HttpResponse this = _this; |
... | ... | @@ -48,6 +48,8 @@ ctor(void * _this, va_list * params) |
48 | 48 | |
49 | 49 | this->reason = calloc(1, strlen(reason)+1); |
50 | 50 | strcpy(this->reason, reason); |
51 | + | |
52 | + return 0; | |
51 | 53 | } |
52 | 54 | |
53 | 55 | static | ... | ... |
... | ... | @@ -30,13 +30,15 @@ |
30 | 30 | #include "http/response/writer.h" |
31 | 31 | |
32 | 32 | static |
33 | -void | |
33 | +int | |
34 | 34 | ctor(void * _this, va_list * params) |
35 | 35 | { |
36 | 36 | HttpResponseWriter this = _this; |
37 | 37 | |
38 | 38 | this->buffer = va_arg(*params, Cbuf); |
39 | 39 | this->response_queue = new(HttpMessageQueue); |
40 | + | |
41 | + return 0; | |
40 | 42 | } |
41 | 43 | |
42 | 44 | static | ... | ... |
... | ... | @@ -15,7 +15,7 @@ |
15 | 15 | |
16 | 16 | #define SHMN "/worker_" |
17 | 17 | static |
18 | -void | |
18 | +int | |
19 | 19 | ctor(void * _this, va_list * params) |
20 | 20 | { |
21 | 21 | HttpWorker this = _this; |
... | ... | @@ -35,6 +35,8 @@ ctor(void * _this, va_list * params) |
35 | 35 | |
36 | 36 | this->parser = new(HttpRequestParser, this->pbuf); |
37 | 37 | this->writer = new(HttpResponseWriter, this->wbuf); |
38 | + | |
39 | + return 0; | |
38 | 40 | } |
39 | 41 | |
40 | 42 | static | ... | ... |
... | ... | @@ -36,8 +36,9 @@ struct interface i_Class = { |
36 | 36 | void * |
37 | 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 | 40 | va_list params; |
41 | + int ret; | |
41 | 42 | |
42 | 43 | if (class->init) class->init(); |
43 | 44 | |
... | ... | @@ -45,19 +46,25 @@ classNew(class_ptr class, ...) |
45 | 46 | object += sizeof(void*); |
46 | 47 | |
47 | 48 | va_start(params, class); |
48 | - CALL(object, Class, ctor, ¶ms); | |
49 | + RETCALL(object, Class, ctor, ret, ¶ms); | |
49 | 50 | va_end(params); |
50 | 51 | |
52 | + if (-1 == ret) { | |
53 | + classDelete(&object); | |
54 | + } | |
55 | + | |
51 | 56 | return object; |
52 | 57 | } |
53 | 58 | |
54 | 59 | void |
55 | 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 | 70 | void * | ... | ... |
... | ... | @@ -40,11 +40,13 @@ logger_level_str[] = { |
40 | 40 | }; |
41 | 41 | |
42 | 42 | static |
43 | -void | |
43 | +int | |
44 | 44 | ctor(void * _this, va_list * params) |
45 | 45 | { |
46 | 46 | Logger this = _this; |
47 | 47 | this->min_level = va_arg(*params, int); |
48 | + | |
49 | + return 0; | |
48 | 50 | } |
49 | 51 | |
50 | 52 | static void dtor(void * _this) {} | ... | ... |
... | ... | @@ -21,6 +21,8 @@ |
21 | 21 | */ |
22 | 22 | |
23 | 23 | #include <fcntl.h> |
24 | +#include <unistd.h> | |
25 | +#include <stdlib.h> | |
24 | 26 | |
25 | 27 | #include "class.h" |
26 | 28 | #include "server.h" |
... | ... | @@ -28,8 +30,10 @@ |
28 | 30 | #include "logger.h" |
29 | 31 | #include "interface/class.h" |
30 | 32 | |
33 | +#include "utils/memory.h" | |
34 | + | |
31 | 35 | static |
32 | -void | |
36 | +int | |
33 | 37 | ctor(void * _this, va_list * params) |
34 | 38 | { |
35 | 39 | Server this = _this; |
... | ... | @@ -37,12 +41,23 @@ ctor(void * _this, va_list * params) |
37 | 41 | unsigned int backlog; |
38 | 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 | 53 | this->logger = va_arg(* params, Logger); |
41 | 54 | this->worker = va_arg(* params, void *); |
42 | 55 | port = va_arg(* params, int); |
43 | 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 | 62 | flags = fcntl(this->sock->handle, F_GETFL, 0); |
48 | 63 | fcntl(this->sock->handle, F_SETFL, flags | O_NONBLOCK); |
... | ... | @@ -52,6 +67,8 @@ ctor(void * _this, va_list * params) |
52 | 67 | (this->fds)[0].fd = this->sock->handle; |
53 | 68 | (this->fds)[0].events = POLLIN; |
54 | 69 | this->nfds = 1; |
70 | + | |
71 | + return 0; | |
55 | 72 | } |
56 | 73 | |
57 | 74 | static |
... | ... | @@ -68,6 +85,9 @@ dtor(void * _this) |
68 | 85 | } |
69 | 86 | } |
70 | 87 | |
88 | + FREE(&(this->fds)); | |
89 | + FREE(&(this->conns)); | |
90 | + | |
71 | 91 | delete(&this->sock); |
72 | 92 | } |
73 | 93 | ... | ... |
... | ... | @@ -33,7 +33,11 @@ int |
33 | 33 | serverHandleAccept(Server this) |
34 | 34 | { |
35 | 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 | 42 | acc = socketAccept(this->sock, &remoteAddr); |
39 | 43 | ... | ... |
... | ... | @@ -30,7 +30,7 @@ |
30 | 30 | #include "interface/logger.h" |
31 | 31 | |
32 | 32 | static |
33 | -void | |
33 | +int | |
34 | 34 | ctor(void * _this, va_list * params) |
35 | 35 | { |
36 | 36 | Sock this = _this; |
... | ... | @@ -49,6 +49,8 @@ ctor(void * _this, va_list * params) |
49 | 49 | |
50 | 50 | //! Make the socket REUSE a TIME_WAIT socket |
51 | 51 | setsockopt(this->handle, SOL_SOCKET, SO_REUSEADDR, &reUse, sizeof (reUse)); |
52 | + | |
53 | + return 0; | |
52 | 54 | } |
53 | 55 | |
54 | 56 | static | ... | ... |
... | ... | @@ -63,6 +63,10 @@ main() |
63 | 63 | struct rlimit limit = {RLIM_INFINITY, RLIM_INFINITY}; |
64 | 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 | 70 | init_signals(); |
67 | 71 | |
68 | 72 | shm = shm_open("/fooshm", O_RDWR|O_CREAT, S_IRWXU); |
... | ... | @@ -132,7 +136,13 @@ main() |
132 | 136 | server = new(Server, logger, worker, 11212, SOMAXCONN); |
133 | 137 | |
134 | 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 | 147 | do { |
138 | 148 | pid_t w; |
... | ... | @@ -155,9 +165,9 @@ main() |
155 | 165 | } |
156 | 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 | 173 | break; | ... | ... |
Please
register
or
login
to post a comment