Commit 424297cd5714c08b7916978376d211ec88a5cd24

Authored by Georg Hopp
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.
  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
@@ -34,8 +34,11 @@ @@ -34,8 +34,11 @@
34 34
35 35
36 static 36 static
37 -void  
38 -ctor(void * _this, va_list * params) {} 37 +int
  38 +ctor(void * _this, va_list * params)
  39 +{
  40 + return 0;
  41 +}
39 42
40 static 43 static
41 void 44 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, &params); 49 + RETCALL(object, Class, ctor, ret, &params);
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