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 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
... ...
... ... @@ -31,7 +31,7 @@
31 31 #include "class.h"
32 32 #include "interface.h"
33 33
34   -typedef void (* fptr_ctor)(void *, va_list *);
  34 +typedef int (* fptr_ctor)(void *, va_list *);
35 35 typedef void (* fptr_dtor)(void *);
36 36 typedef void (* fptr_clone)(void *, void * const);
37 37
... ...
... ... @@ -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);
... ...
... ... @@ -23,6 +23,8 @@
23 23 #ifndef __UTILS_MEMORY_H__
24 24 #define __UTILS_MEMORY_H__
25 25
  26 +#define FREE(val) (ffree((void**)(val)))
  27 +
26 28 void ffree(void **);
27 29
28 30 #endif // __UTILS_MEMORY_H__
... ...
... ... @@ -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
... ...
... ... @@ -28,8 +28,11 @@
28 28 #include "http/message/queue.h"
29 29
30 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 37 static
35 38 void
... ...
... ... @@ -34,8 +34,11 @@
34 34
35 35
36 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 43 static
41 44 void
... ...
... ... @@ -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, &params);
  49 + RETCALL(object, Class, ctor, ret, &params);
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