agoo 1.2.1 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of agoo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/ext/agoo/con.c +8 -3
- data/ext/agoo/con.h +1 -1
- data/ext/agoo/debug.c +67 -0
- data/ext/agoo/debug.h +43 -0
- data/ext/agoo/error_stream.c +4 -0
- data/ext/agoo/hook.c +5 -0
- data/ext/agoo/http.c +3 -0
- data/ext/agoo/log.c +7 -0
- data/ext/agoo/page.c +13 -0
- data/ext/agoo/queue.c +3 -0
- data/ext/agoo/rack_logger.c +10 -1
- data/ext/agoo/request.c +8 -0
- data/ext/agoo/request.h +1 -0
- data/ext/agoo/res.c +3 -0
- data/ext/agoo/response.c +10 -0
- data/ext/agoo/server.c +15 -3
- data/ext/agoo/text.c +6 -0
- data/lib/agoo/version.rb +1 -1
- data/lib/rack/handler/agoo.rb +8 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6103f21468598e8f15a8a47bca17c2b7c1c358af72f8db93090cbf03e193677c
|
4
|
+
data.tar.gz: ee415fcfbb7a45daf9dbe52b286a03317bf900c667953b5cb632f9d1f34b19d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8874e326ca975f994409a298526d12062a788d98c428f6cd71bd3c166ca53e15add697a5aebc0321ab37816dc37598da8ab667164d77d37de5317711f84de5f3
|
7
|
+
data.tar.gz: 23c8284929d79573cf5de03cf57cab3bf308db6ab53e0edb112d1b31bcf5c7cc5895aad4d231a55bfc75a7b77ea5e111b134d4514938ed6e0a19afc43e585927
|
data/ext/agoo/con.c
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
#include <string.h>
|
5
5
|
|
6
6
|
#include "con.h"
|
7
|
+
#include "debug.h"
|
7
8
|
#include "dtime.h"
|
8
9
|
#include "hook.h"
|
9
10
|
#include "http.h"
|
@@ -24,10 +25,10 @@ con_create(Err err, Server server, int sock, uint64_t id) {
|
|
24
25
|
if (NULL == (c = (Con)malloc(sizeof(struct _Con)))) {
|
25
26
|
err_set(err, ERR_MEMORY, "Failed to allocate memory for a connection.");
|
26
27
|
} else {
|
28
|
+
DEBUG_ALLOC(mem_con)
|
27
29
|
memset(c, 0, sizeof(struct _Con));
|
28
30
|
c->sock = sock;
|
29
31
|
c->iid = id;
|
30
|
-
sprintf(c->id, "%llu", (unsigned long long)id);
|
31
32
|
c->server = server;
|
32
33
|
}
|
33
34
|
return c;
|
@@ -41,7 +42,9 @@ con_destroy(Con c) {
|
|
41
42
|
}
|
42
43
|
if (NULL != c->req) {
|
43
44
|
free(c->req);
|
45
|
+
DEBUG_FREE(mem_req)
|
44
46
|
}
|
47
|
+
DEBUG_FREE(mem_con)
|
45
48
|
free(c);
|
46
49
|
}
|
47
50
|
|
@@ -63,7 +66,7 @@ con_header_value(const char *header, int hlen, const char *key, int *vlen) {
|
|
63
66
|
for (; '\r' != *h && '\0' != *h; h++) {
|
64
67
|
}
|
65
68
|
*vlen = (int)(h - value);
|
66
|
-
|
69
|
+
|
67
70
|
return value;
|
68
71
|
}
|
69
72
|
for (; h < hend; h++) {
|
@@ -88,6 +91,7 @@ bad_request(Con c, int status, int line) {
|
|
88
91
|
int cnt = snprintf(buf, sizeof(buf), "HTTP/1.1 %d %s\r\nConnection: Close\r\nContent-Length: 0\r\n\r\n", status, msg);
|
89
92
|
Text message = text_create(buf, cnt);
|
90
93
|
|
94
|
+
DEBUG_ALLOC(mem_res)
|
91
95
|
if (NULL == c->res_tail) {
|
92
96
|
c->res_head = res;
|
93
97
|
} else {
|
@@ -266,6 +270,7 @@ HOOKED:
|
|
266
270
|
if (NULL == (c->req = (Req)malloc(mlen + sizeof(struct _Req) - 8 + 1))) {
|
267
271
|
return bad_request(c, 413, __LINE__);
|
268
272
|
}
|
273
|
+
DEBUG_ALLOC(mem_req)
|
269
274
|
if ((long)c->bcnt <= mlen) {
|
270
275
|
memcpy(c->req->msg, c->buf, c->bcnt);
|
271
276
|
if ((long)c->bcnt < mlen) {
|
@@ -313,7 +318,7 @@ con_read(Con c) {
|
|
313
318
|
// If nothing read then no need to complain. Just close.
|
314
319
|
if (0 < c->bcnt) {
|
315
320
|
if (0 == cnt) {
|
316
|
-
log_cat(&c->server->warn_cat, "Nothing to read. Client closed socket %
|
321
|
+
log_cat(&c->server->warn_cat, "Nothing to read. Client closed socket on connection %llu.", c->iid);
|
317
322
|
} else {
|
318
323
|
log_cat(&c->server->warn_cat, "Failed to read request. %s.", strerror(errno));
|
319
324
|
}
|
data/ext/agoo/con.h
CHANGED
data/ext/agoo/debug.c
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
// Copyright (c) 2018, Peter Ohler, All rights reserved.
|
2
|
+
|
3
|
+
#include <stdio.h>
|
4
|
+
|
5
|
+
#include <ruby.h>
|
6
|
+
|
7
|
+
#include "debug.h"
|
8
|
+
|
9
|
+
atomic_int mem_con = 0;
|
10
|
+
atomic_int mem_err_stream = 0;
|
11
|
+
atomic_int mem_eval_threads = 0;
|
12
|
+
atomic_int mem_header = 0;
|
13
|
+
atomic_int mem_hook = 0;
|
14
|
+
atomic_int mem_hook_pattern = 0;
|
15
|
+
atomic_int mem_http_slot = 0;
|
16
|
+
atomic_int mem_log_entry = 0;
|
17
|
+
atomic_int mem_log_what = 0;
|
18
|
+
atomic_int mem_mime_slot = 0;
|
19
|
+
atomic_int mem_page = 0;
|
20
|
+
atomic_int mem_page_msg = 0;
|
21
|
+
atomic_int mem_page_path = 0;
|
22
|
+
atomic_int mem_page_slot = 0;
|
23
|
+
atomic_int mem_qitem = 0;
|
24
|
+
atomic_int mem_queue_item = 0;
|
25
|
+
atomic_int mem_rack_logger = 0;
|
26
|
+
atomic_int mem_req = 0;
|
27
|
+
atomic_int mem_res = 0;
|
28
|
+
atomic_int mem_res_body = 0;
|
29
|
+
atomic_int mem_response = 0;
|
30
|
+
atomic_int mem_server = 0;
|
31
|
+
atomic_int mem_text = 0;
|
32
|
+
atomic_int mem_to_s = 0;
|
33
|
+
|
34
|
+
void
|
35
|
+
debug_print_stats() {
|
36
|
+
#ifdef MEM_DEBUG
|
37
|
+
rb_gc_enable();
|
38
|
+
rb_gc();
|
39
|
+
|
40
|
+
printf("********************************************************************************\n");
|
41
|
+
printf("memory statistics\n");
|
42
|
+
printf(" mem_con: %d\n", mem_con);
|
43
|
+
printf(" mem_err_stream: %d\n", mem_err_stream);
|
44
|
+
printf(" mem_eval_threads: %d\n", mem_eval_threads);
|
45
|
+
printf(" mem_header: %d\n", mem_header);
|
46
|
+
printf(" mem_hook: %d\n", mem_hook);
|
47
|
+
printf(" mem_hook_pattern: %d\n", mem_hook_pattern);
|
48
|
+
printf(" mem_http_slot: %d\n", mem_http_slot);
|
49
|
+
printf(" mem_log_entry: %d\n", mem_log_entry);
|
50
|
+
printf(" mem_log_what: %d\n", mem_log_what);
|
51
|
+
printf(" mem_mime_slot: %d\n", mem_mime_slot);
|
52
|
+
printf(" mem_page: %d\n", mem_page);
|
53
|
+
printf(" mem_page_msg: %d\n", mem_page_msg);
|
54
|
+
printf(" mem_page_path: %d\n", mem_page_path);
|
55
|
+
printf(" mem_page_slot: %d\n", mem_page_slot);
|
56
|
+
printf(" mem_qitem: %d\n", mem_qitem);
|
57
|
+
printf(" mem_queue_item: %d\n", mem_queue_item);
|
58
|
+
printf(" mem_rack_logger: %d\n", mem_rack_logger);
|
59
|
+
printf(" mem_req: %d\n", mem_req);
|
60
|
+
printf(" mem_res: %d\n", mem_res);
|
61
|
+
printf(" mem_res_body: %d\n", mem_res_body);
|
62
|
+
printf(" mem_response: %d\n", mem_response);
|
63
|
+
printf(" mem_server: %d\n", mem_server);
|
64
|
+
printf(" mem_text: %d\n", mem_text);
|
65
|
+
printf(" mem_to_s: %d\n", mem_to_s);
|
66
|
+
#endif
|
67
|
+
}
|
data/ext/agoo/debug.h
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
// Copyright (c) 2018, Peter Ohler, All rights reserved.
|
2
|
+
|
3
|
+
#ifndef __AGOO_DEBUG_H__
|
4
|
+
#define __AGOO_DEBUG_H__
|
5
|
+
|
6
|
+
#include <stdatomic.h>
|
7
|
+
|
8
|
+
#ifdef MEM_DEBUG
|
9
|
+
#define DEBUG_ALLOC(var) { atomic_fetch_add(&var, 1); }
|
10
|
+
#define DEBUG_FREE(var) { atomic_fetch_sub(&var, 1); }
|
11
|
+
#else
|
12
|
+
#define DEBUG_ALLOC(var) { }
|
13
|
+
#define DEBUG_FREE(var) { }
|
14
|
+
#endif
|
15
|
+
|
16
|
+
extern atomic_int mem_con;
|
17
|
+
extern atomic_int mem_err_stream;
|
18
|
+
extern atomic_int mem_eval_threads;
|
19
|
+
extern atomic_int mem_header;
|
20
|
+
extern atomic_int mem_hook;
|
21
|
+
extern atomic_int mem_hook_pattern;
|
22
|
+
extern atomic_int mem_http_slot;
|
23
|
+
extern atomic_int mem_log_entry;
|
24
|
+
extern atomic_int mem_log_what;
|
25
|
+
extern atomic_int mem_mime_slot;
|
26
|
+
extern atomic_int mem_page;
|
27
|
+
extern atomic_int mem_page_msg;
|
28
|
+
extern atomic_int mem_page_path;
|
29
|
+
extern atomic_int mem_page_slot;
|
30
|
+
extern atomic_int mem_qitem;
|
31
|
+
extern atomic_int mem_queue_item;
|
32
|
+
extern atomic_int mem_rack_logger;
|
33
|
+
extern atomic_int mem_req;
|
34
|
+
extern atomic_int mem_res;
|
35
|
+
extern atomic_int mem_res_body;
|
36
|
+
extern atomic_int mem_response;
|
37
|
+
extern atomic_int mem_server;
|
38
|
+
extern atomic_int mem_text;
|
39
|
+
extern atomic_int mem_to_s;
|
40
|
+
|
41
|
+
extern void debug_print_stats();
|
42
|
+
|
43
|
+
#endif /* __AGOO_DEBUG_H__ */
|
data/ext/agoo/error_stream.c
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
// Copyright (c) 2018, Peter Ohler, All rights reserved.
|
2
2
|
|
3
3
|
#include "error_stream.h"
|
4
|
+
#include "debug.h"
|
4
5
|
#include "text.h"
|
5
6
|
|
6
7
|
static VALUE es_class = Qundef;
|
@@ -14,6 +15,8 @@ static void
|
|
14
15
|
es_free(void *ptr) {
|
15
16
|
ErrorStream es = (ErrorStream)ptr;
|
16
17
|
|
18
|
+
DEBUG_FREE(mem_err_stream)
|
19
|
+
DEBUG_FREE(mem_text)
|
17
20
|
free(es->text); // allocated with malloc
|
18
21
|
xfree(ptr);
|
19
22
|
}
|
@@ -22,6 +25,7 @@ VALUE
|
|
22
25
|
error_stream_new(Server server) {
|
23
26
|
ErrorStream es = ALLOC(struct _ErrorStream);
|
24
27
|
|
28
|
+
DEBUG_ALLOC(mem_err_stream)
|
25
29
|
es->text = text_allocate(1024);
|
26
30
|
es->server = server;
|
27
31
|
|
data/ext/agoo/hook.c
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
#include <stdlib.h>
|
4
4
|
#include <string.h>
|
5
5
|
|
6
|
+
#include "debug.h"
|
6
7
|
#include "hook.h"
|
7
8
|
|
8
9
|
Hook
|
@@ -10,6 +11,7 @@ hook_create(Method method, const char *pattern, VALUE handler) {
|
|
10
11
|
Hook hook = (Hook)malloc(sizeof(struct _Hook));
|
11
12
|
|
12
13
|
if (NULL != hook) {
|
14
|
+
DEBUG_ALLOC(mem_hook)
|
13
15
|
if (NULL == pattern) {
|
14
16
|
pattern = "";
|
15
17
|
}
|
@@ -17,6 +19,7 @@ hook_create(Method method, const char *pattern, VALUE handler) {
|
|
17
19
|
hook->handler = handler;
|
18
20
|
rb_gc_register_address(&handler);
|
19
21
|
hook->pattern = strdup(pattern);
|
22
|
+
DEBUG_ALLOC(mem_hook_pattern)
|
20
23
|
hook->method = method;
|
21
24
|
if (rb_respond_to(handler, rb_intern("on_request"))) {
|
22
25
|
hook->type = BASE_HOOK;
|
@@ -36,6 +39,8 @@ hook_create(Method method, const char *pattern, VALUE handler) {
|
|
36
39
|
|
37
40
|
void
|
38
41
|
hook_destroy(Hook hook) {
|
42
|
+
DEBUG_FREE(mem_hook_pattern)
|
43
|
+
DEBUG_FREE(mem_hook)
|
39
44
|
free(hook->pattern);
|
40
45
|
free(hook);
|
41
46
|
}
|
data/ext/agoo/http.c
CHANGED
@@ -6,6 +6,7 @@
|
|
6
6
|
|
7
7
|
#include <ruby.h>
|
8
8
|
|
9
|
+
#include "debug.h"
|
9
10
|
#include "http.h"
|
10
11
|
|
11
12
|
#define BUCKET_SIZE 1024
|
@@ -470,6 +471,7 @@ key_set(const char *key) {
|
|
470
471
|
Slot s;
|
471
472
|
|
472
473
|
if (NULL != (s = (Slot)malloc(sizeof(struct _Slot)))) {
|
474
|
+
DEBUG_ALLOC(mem_http_slot)
|
473
475
|
s->hash = h;
|
474
476
|
s->klen = len;
|
475
477
|
s->key = key;
|
@@ -497,6 +499,7 @@ http_cleanup() {
|
|
497
499
|
for (int i = BUCKET_SIZE; 0 < i; i--, sp++) {
|
498
500
|
for (s = *sp; NULL != s; s = n) {
|
499
501
|
n = s->next;
|
502
|
+
DEBUG_FREE(mem_http_slot)
|
500
503
|
free(s);
|
501
504
|
}
|
502
505
|
*sp = NULL;
|
data/ext/agoo/log.c
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
#include <sys/types.h>
|
9
9
|
#include <time.h>
|
10
10
|
|
11
|
+
#include "debug.h"
|
11
12
|
#include "dtime.h"
|
12
13
|
#include "log.h"
|
13
14
|
|
@@ -231,6 +232,7 @@ loop(void *ctx) {
|
|
231
232
|
}
|
232
233
|
if (NULL != e->whatp) {
|
233
234
|
free(e->whatp);
|
235
|
+
DEBUG_FREE(mem_log_what)
|
234
236
|
}
|
235
237
|
e->ready = false;
|
236
238
|
}
|
@@ -364,6 +366,8 @@ log_init(Err err, Log log, VALUE cfg) {
|
|
364
366
|
}
|
365
367
|
}
|
366
368
|
log->q = (LogEntry)malloc(sizeof(struct _LogEntry) * qsize);
|
369
|
+
DEBUG_ALLOC(mem_log_entry)
|
370
|
+
|
367
371
|
log->end = log->q + qsize;
|
368
372
|
|
369
373
|
memset(log->q, 0, sizeof(struct _LogEntry) * qsize);
|
@@ -393,6 +397,7 @@ log_close(Log log) {
|
|
393
397
|
fclose(log->file);
|
394
398
|
log->file = NULL;
|
395
399
|
}
|
400
|
+
DEBUG_FREE(mem_log_entry)
|
396
401
|
free(log->q);
|
397
402
|
log->q = NULL;
|
398
403
|
log->end = NULL;
|
@@ -468,6 +473,8 @@ log_catv(LogCat cat, const char *fmt, va_list ap) {
|
|
468
473
|
if ((int)sizeof(e->what) <= (cnt = vsnprintf(e->what, sizeof(e->what), fmt, ap))) {
|
469
474
|
e->whatp = (char*)malloc(cnt + 1);
|
470
475
|
|
476
|
+
DEBUG_ALLOC(mem_log_what)
|
477
|
+
|
471
478
|
if (NULL != e->whatp) {
|
472
479
|
vsnprintf(e->whatp, cnt + 1, fmt, ap2);
|
473
480
|
}
|
data/ext/agoo/page.c
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
|
8
8
|
#include <ruby.h>
|
9
9
|
|
10
|
+
#include "debug.h"
|
10
11
|
#include "dtime.h"
|
11
12
|
#include "page.h"
|
12
13
|
|
@@ -158,6 +159,7 @@ mime_set(Cache cache, const char *key, const char *value) {
|
|
158
159
|
((0 <= len && len <= MAX_KEY_UNIQ) || 0 == strcmp(s->key, key))) {
|
159
160
|
if (h == (int64_t)s->hash && len == s->klen &&
|
160
161
|
((0 <= len && len <= MAX_KEY_UNIQ) || 0 == strcmp(s->key, key))) {
|
162
|
+
DEBUG_FREE(mem_mime_slot)
|
161
163
|
free(s->value);
|
162
164
|
s->value = strdup(value);
|
163
165
|
return;
|
@@ -167,6 +169,7 @@ mime_set(Cache cache, const char *key, const char *value) {
|
|
167
169
|
if (NULL == (s = (MimeSlot)malloc(sizeof(struct _MimeSlot)))) {
|
168
170
|
rb_raise(rb_eArgError, "out of memory adding %s", key);
|
169
171
|
}
|
172
|
+
DEBUG_ALLOC(mem_mime_slot)
|
170
173
|
s->hash = h;
|
171
174
|
s->klen = len;
|
172
175
|
if (NULL == key) {
|
@@ -206,6 +209,7 @@ cache_set(Cache cache, const char *key, int klen, Page value) {
|
|
206
209
|
if (NULL == (s = (Slot)malloc(sizeof(struct _Slot)))) {
|
207
210
|
return value;
|
208
211
|
}
|
212
|
+
DEBUG_ALLOC(mem_page_slot)
|
209
213
|
s->hash = h;
|
210
214
|
s->klen = len;
|
211
215
|
if (NULL == key) {
|
@@ -243,6 +247,7 @@ cache_destroy(Cache cache) {
|
|
243
247
|
for (i = PAGE_BUCKET_SIZE; 0 < i; i--, sp++) {
|
244
248
|
for (s = *sp; NULL != s; s = n) {
|
245
249
|
n = s->next;
|
250
|
+
DEBUG_FREE(mem_page_slot)
|
246
251
|
free(s);
|
247
252
|
}
|
248
253
|
*sp = NULL;
|
@@ -251,10 +256,12 @@ cache_destroy(Cache cache) {
|
|
251
256
|
for (i = MIME_BUCKET_SIZE; 0 < i; i--, mp++) {
|
252
257
|
for (sm = *mp; NULL != sm; sm = m) {
|
253
258
|
m = sm->next;
|
259
|
+
DEBUG_FREE(mem_page_slot)
|
254
260
|
free(sm);
|
255
261
|
}
|
256
262
|
*mp = NULL;
|
257
263
|
}
|
264
|
+
//DEBUG_FREE(mem_cache)
|
258
265
|
free(cache);
|
259
266
|
}
|
260
267
|
|
@@ -265,11 +272,13 @@ page_create(const char *path) {
|
|
265
272
|
Page p = (Page)malloc(sizeof(struct _Page));
|
266
273
|
|
267
274
|
if (NULL != p) {
|
275
|
+
DEBUG_ALLOC(mem_page)
|
268
276
|
p->resp = NULL;
|
269
277
|
if (NULL == path) {
|
270
278
|
p->path = NULL;
|
271
279
|
} else {
|
272
280
|
p->path = strdup(path);
|
281
|
+
DEBUG_ALLOC(mem_page_path)
|
273
282
|
}
|
274
283
|
p->mtime = 0;
|
275
284
|
p->last_check = 0.0;
|
@@ -283,6 +292,8 @@ page_destroy(Page p) {
|
|
283
292
|
text_release(p->resp);
|
284
293
|
p->resp = NULL;
|
285
294
|
}
|
295
|
+
DEBUG_FREE(mem_page_path)
|
296
|
+
DEBUG_FREE(mem_page)
|
286
297
|
free(p->path);
|
287
298
|
free(p);
|
288
299
|
}
|
@@ -362,11 +373,13 @@ update_contents(Cache cache, Page p) {
|
|
362
373
|
if (NULL == (msg = (char*)malloc(msize))) {
|
363
374
|
return false;
|
364
375
|
}
|
376
|
+
DEBUG_ALLOC(mem_page_msg)
|
365
377
|
cnt = sprintf(msg, page_fmt, mime, size);
|
366
378
|
|
367
379
|
msize = cnt + size;
|
368
380
|
if (size != (long)fread(msg + cnt, 1, size, f)) {
|
369
381
|
fclose(f);
|
382
|
+
DEBUG_FREE(mem_page_msg)
|
370
383
|
free(msg);
|
371
384
|
return false;
|
372
385
|
}
|
data/ext/agoo/queue.c
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
#include <unistd.h>
|
9
9
|
#include <pthread.h>
|
10
10
|
|
11
|
+
#include "debug.h"
|
11
12
|
#include "dtime.h"
|
12
13
|
#include "queue.h"
|
13
14
|
|
@@ -34,6 +35,7 @@ queue_multi_init(Queue q, size_t qsize, bool multi_push, bool multi_pop) {
|
|
34
35
|
qsize = 4;
|
35
36
|
}
|
36
37
|
q->q = (QItem*)malloc(sizeof(QItem) * qsize);
|
38
|
+
DEBUG_ALLOC(mem_qitem)
|
37
39
|
q->end = q->q + qsize;
|
38
40
|
|
39
41
|
memset(q->q, 0, sizeof(QItem) * qsize);
|
@@ -51,6 +53,7 @@ queue_multi_init(Queue q, size_t qsize, bool multi_push, bool multi_pop) {
|
|
51
53
|
|
52
54
|
void
|
53
55
|
queue_cleanup(Queue q) {
|
56
|
+
DEBUG_FREE(mem_qitem)
|
54
57
|
free(q->q);
|
55
58
|
q->q = NULL;
|
56
59
|
q->end = NULL;
|
data/ext/agoo/rack_logger.c
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
#include <stdlib.h>
|
4
4
|
|
5
5
|
#include "rack_logger.h"
|
6
|
+
#include "debug.h"
|
6
7
|
#include "log.h"
|
7
8
|
#include "text.h"
|
8
9
|
|
@@ -12,13 +13,21 @@ typedef struct _RackLogger {
|
|
12
13
|
Server server;
|
13
14
|
} *RackLogger;
|
14
15
|
|
16
|
+
static void
|
17
|
+
rack_logger_free(void *ptr) {
|
18
|
+
DEBUG_FREE(mem_rack_logger)
|
19
|
+
xfree(ptr);
|
20
|
+
}
|
21
|
+
|
15
22
|
VALUE
|
16
23
|
rack_logger_new(Server server) {
|
17
24
|
RackLogger rl = ALLOC(struct _RackLogger);
|
18
25
|
|
26
|
+
DEBUG_ALLOC(mem_rack_logger)
|
19
27
|
rl->server = server;
|
20
28
|
|
21
|
-
return Data_Wrap_Struct(rl_class, NULL, xfree, rl);
|
29
|
+
//return Data_Wrap_Struct(rl_class, NULL, xfree, rl);
|
30
|
+
return Data_Wrap_Struct(rl_class, NULL, rack_logger_free, rl);
|
22
31
|
}
|
23
32
|
|
24
33
|
static void
|
data/ext/agoo/request.c
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
#include <stdio.h>
|
4
4
|
|
5
|
+
#include "debug.h"
|
5
6
|
#include "con.h"
|
6
7
|
#include "error_stream.h"
|
7
8
|
#include "rack_logger.h"
|
@@ -517,8 +518,15 @@ to_s(VALUE self) {
|
|
517
518
|
return rb_funcall(h, rb_intern("to_s"), 0);
|
518
519
|
}
|
519
520
|
|
521
|
+
void
|
522
|
+
request_destroy(Req req) {
|
523
|
+
DEBUG_FREE(mem_req)
|
524
|
+
free(req);
|
525
|
+
}
|
526
|
+
|
520
527
|
VALUE
|
521
528
|
request_wrap(Req req) {
|
529
|
+
// freed from the C side of things
|
522
530
|
return Data_Wrap_Struct(req_class, NULL, NULL, req);
|
523
531
|
}
|
524
532
|
|
data/ext/agoo/request.h
CHANGED
data/ext/agoo/res.c
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
#include <stdlib.h>
|
4
4
|
|
5
|
+
#include "debug.h"
|
5
6
|
#include "res.h"
|
6
7
|
|
7
8
|
Res
|
@@ -9,6 +10,7 @@ res_create() {
|
|
9
10
|
Res res = (Res)malloc(sizeof(struct _Res));
|
10
11
|
|
11
12
|
if (NULL != res) {
|
13
|
+
DEBUG_ALLOC(mem_res)
|
12
14
|
res->next = NULL;
|
13
15
|
atomic_init(&res->message, NULL);
|
14
16
|
res->close = false;
|
@@ -24,6 +26,7 @@ res_destroy(Res res) {
|
|
24
26
|
if (NULL != message) {
|
25
27
|
text_release(message);
|
26
28
|
}
|
29
|
+
DEBUG_FREE(mem_res)
|
27
30
|
free(res);
|
28
31
|
}
|
29
32
|
}
|
data/ext/agoo/response.c
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
#include <stdlib.h>
|
4
4
|
|
5
|
+
#include "debug.h"
|
5
6
|
#include "http.h"
|
6
7
|
#include "response.h"
|
7
8
|
#include "text.h"
|
@@ -51,8 +52,11 @@ response_free(void *ptr) {
|
|
51
52
|
|
52
53
|
while (NULL != (h = res->headers)) {
|
53
54
|
res->headers = h->next;
|
55
|
+
DEBUG_FREE(mem_header)
|
54
56
|
xfree(h);
|
55
57
|
}
|
58
|
+
DEBUG_FREE(mem_res_body);
|
59
|
+
DEBUG_FREE(mem_response);
|
56
60
|
free(res->body); // allocated with strdup
|
57
61
|
xfree(ptr);
|
58
62
|
}
|
@@ -61,6 +65,7 @@ VALUE
|
|
61
65
|
response_new(Server server ) {
|
62
66
|
Response res = ALLOC(struct _Response);
|
63
67
|
|
68
|
+
DEBUG_ALLOC(mem_response)
|
64
69
|
memset(res, 0, sizeof(struct _Response));
|
65
70
|
res->code = 200;
|
66
71
|
res->server = server;
|
@@ -80,6 +85,7 @@ to_s(VALUE self) {
|
|
80
85
|
int len = response_len(res);
|
81
86
|
char *s = ALLOC_N(char, len + 1);
|
82
87
|
|
88
|
+
DEBUG_ALLOC(mem_to_s)
|
83
89
|
response_fill(res, s);
|
84
90
|
|
85
91
|
return rb_str_new(s, len);
|
@@ -127,6 +133,7 @@ body_set(VALUE self, VALUE val) {
|
|
127
133
|
|
128
134
|
if (T_STRING == rb_type(val)) {
|
129
135
|
res->body = strdup(StringValuePtr(val));
|
136
|
+
DEBUG_ALLOC(mem_res_body)
|
130
137
|
res->blen = (int)RSTRING_LEN(val);
|
131
138
|
} else {
|
132
139
|
// TBD use Oj
|
@@ -208,6 +215,7 @@ head_set(VALUE self, VALUE key, VALUE val) {
|
|
208
215
|
} else {
|
209
216
|
prev->next = h->next;
|
210
217
|
}
|
218
|
+
DEBUG_FREE(mem_header)
|
211
219
|
xfree(h);
|
212
220
|
break;
|
213
221
|
}
|
@@ -224,6 +232,8 @@ head_set(VALUE self, VALUE key, VALUE val) {
|
|
224
232
|
}
|
225
233
|
hlen = klen + vlen + 4;
|
226
234
|
h = (Header)ALLOC_N(char, sizeof(struct _Header) - 8 + hlen + 1);
|
235
|
+
DEBUG_ALLOC(mem_header)
|
236
|
+
|
227
237
|
h->next = NULL;
|
228
238
|
h->len = hlen;
|
229
239
|
strncpy(h->text, ks, klen);
|
data/ext/agoo/server.c
CHANGED
@@ -21,6 +21,7 @@
|
|
21
21
|
#include <ruby/thread.h>
|
22
22
|
|
23
23
|
#include "con.h"
|
24
|
+
#include "debug.h"
|
24
25
|
#include "dtime.h"
|
25
26
|
#include "err.h"
|
26
27
|
#include "http.h"
|
@@ -74,6 +75,7 @@ shutdown_server(Server server) {
|
|
74
75
|
}
|
75
76
|
dsleep(0.02);
|
76
77
|
}
|
78
|
+
DEBUG_FREE(mem_eval_threads)
|
77
79
|
xfree(server->eval_threads);
|
78
80
|
server->eval_threads = NULL;
|
79
81
|
}
|
@@ -85,6 +87,7 @@ shutdown_server(Server server) {
|
|
85
87
|
}
|
86
88
|
queue_cleanup(&server->eval_queue);
|
87
89
|
log_close(&server->log);
|
90
|
+
debug_print_stats();
|
88
91
|
}
|
89
92
|
}
|
90
93
|
|
@@ -105,6 +108,7 @@ server_free(void *ptr) {
|
|
105
108
|
//to be pointing at it even though they have exited so live with a memory
|
106
109
|
//leak that only shows up when the program exits.
|
107
110
|
//xfree(ptr);
|
111
|
+
DEBUG_FREE(mem_server)
|
108
112
|
the_server = NULL;
|
109
113
|
}
|
110
114
|
|
@@ -193,7 +197,6 @@ configure(Err err, Server s, int port, const char *root, VALUE options) {
|
|
193
197
|
*
|
194
198
|
* - *:pedantic* [_true_|_false_] if true response header and status codes are check and an exception raised if they violate the rack spec at https://github.com/rack/rack/blob/master/SPEC, https://tools.ietf.org/html/rfc3875#section-4.1.18, or https://tools.ietf.org/html/rfc7230.
|
195
199
|
*
|
196
|
-
*
|
197
200
|
* - *:thread_count* [_Integer_] number of ruby worker threads. Defaults to one. If zero then the _start_ function will not return but instead will proess using the thread that called _start_. Usually the default is best unless the workers are making IO calls.
|
198
201
|
*
|
199
202
|
* - *:log_dir* [_String_] directory to place log files in. If nil or empty then no log files are written.
|
@@ -232,9 +235,11 @@ server_new(int argc, VALUE *argv, VALUE self) {
|
|
232
235
|
options = argv[2];
|
233
236
|
}
|
234
237
|
s = ALLOC(struct _Server);
|
238
|
+
DEBUG_ALLOC(mem_server)
|
235
239
|
memset(s, 0, sizeof(struct _Server));
|
236
240
|
if (ERR_OK != configure(&err, s, port, root, options)) {
|
237
241
|
xfree(s);
|
242
|
+
DEBUG_FREE(mem_server)
|
238
243
|
// TBD raise Agoo specific exception
|
239
244
|
rb_raise(rb_eArgError, "%s", err.msg);
|
240
245
|
}
|
@@ -542,9 +547,10 @@ handle_rack(void *x) {
|
|
542
547
|
// Disable GC. The handle_rack function or rather the env seems to get
|
543
548
|
// collected even though it is volatile so for now turn off GC
|
544
549
|
// temporarily.
|
545
|
-
rb_gc_disable();
|
550
|
+
//rb_gc_disable();
|
546
551
|
rb_rescue2(handle_rack_inner, (VALUE)x, rescue_error, (VALUE)x, rb_eException, 0);
|
547
|
-
rb_gc_enable();
|
552
|
+
//rb_gc_enable();
|
553
|
+
//rb_gc();
|
548
554
|
|
549
555
|
return NULL;
|
550
556
|
}
|
@@ -604,6 +610,8 @@ process_loop(void *ptr) {
|
|
604
610
|
while (server->active) {
|
605
611
|
if (NULL != (req = (Req)queue_pop(&server->eval_queue, 0.1))) {
|
606
612
|
handle_protected(req);
|
613
|
+
free(req);
|
614
|
+
DEBUG_FREE(mem_req)
|
607
615
|
}
|
608
616
|
}
|
609
617
|
atomic_fetch_sub(&server->running, 1);
|
@@ -679,10 +687,14 @@ start(VALUE self) {
|
|
679
687
|
break;
|
680
688
|
}
|
681
689
|
}
|
690
|
+
free(req);
|
691
|
+
DEBUG_FREE(mem_req)
|
682
692
|
}
|
683
693
|
}
|
684
694
|
} else {
|
685
695
|
server->eval_threads = ALLOC_N(VALUE, server->thread_cnt + 1);
|
696
|
+
DEBUG_ALLOC(mem_eval_threads)
|
697
|
+
|
686
698
|
for (i = server->thread_cnt, vp = server->eval_threads; 0 < i; i--, vp++) {
|
687
699
|
*vp = rb_thread_create(wrap_process_loop, server);
|
688
700
|
}
|
data/ext/agoo/text.c
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
// Copyright 2016, 2018 by Peter Ohler, All Rights Reserved
|
2
2
|
|
3
|
+
#include <stdio.h>
|
3
4
|
#include <stdlib.h>
|
4
5
|
#include <string.h>
|
5
6
|
|
7
|
+
#include "debug.h"
|
6
8
|
#include "text.h"
|
7
9
|
|
8
10
|
Text
|
@@ -10,6 +12,7 @@ text_create(const char *str, int len) {
|
|
10
12
|
Text t = (Text)malloc(sizeof(struct _Text) - TEXT_MIN_SIZE + len + 1);
|
11
13
|
|
12
14
|
if (NULL != t) {
|
15
|
+
DEBUG_ALLOC(mem_text)
|
13
16
|
t->len = len;
|
14
17
|
t->alen = len;
|
15
18
|
atomic_init(&t->ref_cnt, 0);
|
@@ -24,6 +27,7 @@ text_allocate(int len) {
|
|
24
27
|
Text t = (Text)malloc(sizeof(struct _Text) - TEXT_MIN_SIZE + len + 1);
|
25
28
|
|
26
29
|
if (NULL != t) {
|
30
|
+
DEBUG_ALLOC(mem_text)
|
27
31
|
t->len = 0;
|
28
32
|
t->alen = len;
|
29
33
|
atomic_init(&t->ref_cnt, 0);
|
@@ -40,6 +44,7 @@ text_ref(Text t) {
|
|
40
44
|
void
|
41
45
|
text_release(Text t) {
|
42
46
|
if (1 >= atomic_fetch_sub(&t->ref_cnt, 1)) {
|
47
|
+
DEBUG_FREE(mem_text)
|
43
48
|
free(t);
|
44
49
|
}
|
45
50
|
}
|
@@ -56,6 +61,7 @@ text_append(Text t, const char *s, int len) {
|
|
56
61
|
if (NULL == (t = (Text)realloc(t, size))) {
|
57
62
|
return NULL;
|
58
63
|
}
|
64
|
+
DEBUG_ALLOC(mem_text)
|
59
65
|
t->alen = new_len;
|
60
66
|
}
|
61
67
|
memcpy(t->text + t->len, s, len);
|
data/lib/agoo/version.rb
CHANGED
data/lib/rack/handler/agoo.rb
CHANGED
@@ -18,7 +18,7 @@ module Rack
|
|
18
18
|
|
19
19
|
default_handler = handler unless handler.nil?
|
20
20
|
options.each { |k,v|
|
21
|
-
if :port == k
|
21
|
+
if :port == k || :p == k
|
22
22
|
port = v.to_i
|
23
23
|
options.delete(k)
|
24
24
|
elsif :root == k
|
@@ -47,3 +47,10 @@ module Rack
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
50
|
+
|
51
|
+
begin
|
52
|
+
::Rack::Handler.register('agoo', 'Rack::Handler::Agoo')
|
53
|
+
::Rack::Handler.register('Agoo', 'Rack::Handler::Agoo')
|
54
|
+
rescue Exception
|
55
|
+
# Rack or Rack::Handler.register has not been required.
|
56
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: agoo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03-
|
11
|
+
date: 2018-03-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oj
|
@@ -45,6 +45,8 @@ files:
|
|
45
45
|
- ext/agoo/agoo.c
|
46
46
|
- ext/agoo/con.c
|
47
47
|
- ext/agoo/con.h
|
48
|
+
- ext/agoo/debug.c
|
49
|
+
- ext/agoo/debug.h
|
48
50
|
- ext/agoo/dtime.c
|
49
51
|
- ext/agoo/dtime.h
|
50
52
|
- ext/agoo/err.c
|