iodine 0.6.5 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +4 -4
- data/SPEC-Websocket-Draft.md +3 -6
- data/bin/mustache.rb +128 -0
- data/examples/test_template.mustache +16 -0
- data/ext/iodine/fio.c +9397 -0
- data/ext/iodine/fio.h +4723 -0
- data/ext/iodine/fio_ary.h +353 -54
- data/ext/iodine/fio_cli.c +351 -361
- data/ext/iodine/fio_cli.h +84 -105
- data/ext/iodine/fio_hashmap.h +70 -16
- data/ext/iodine/fio_json_parser.h +35 -24
- data/ext/iodine/fio_siphash.c +104 -4
- data/ext/iodine/fio_siphash.h +18 -2
- data/ext/iodine/fio_str.h +1218 -0
- data/ext/iodine/fio_tmpfile.h +1 -1
- data/ext/iodine/fiobj.h +13 -8
- data/ext/iodine/fiobj4sock.h +6 -8
- data/ext/iodine/fiobj_ary.c +107 -17
- data/ext/iodine/fiobj_ary.h +36 -4
- data/ext/iodine/fiobj_data.c +146 -127
- data/ext/iodine/fiobj_data.h +25 -23
- data/ext/iodine/fiobj_hash.c +7 -7
- data/ext/iodine/fiobj_hash.h +6 -5
- data/ext/iodine/fiobj_json.c +20 -17
- data/ext/iodine/fiobj_json.h +5 -5
- data/ext/iodine/fiobj_mem.h +71 -0
- data/ext/iodine/fiobj_mustache.c +310 -0
- data/ext/iodine/fiobj_mustache.h +40 -0
- data/ext/iodine/fiobj_numbers.c +199 -94
- data/ext/iodine/fiobj_numbers.h +7 -7
- data/ext/iodine/fiobj_str.c +142 -333
- data/ext/iodine/fiobj_str.h +65 -55
- data/ext/iodine/fiobject.c +49 -11
- data/ext/iodine/fiobject.h +40 -39
- data/ext/iodine/http.c +382 -190
- data/ext/iodine/http.h +124 -80
- data/ext/iodine/http1.c +99 -127
- data/ext/iodine/http1.h +5 -5
- data/ext/iodine/http1_parser.c +3 -2
- data/ext/iodine/http1_parser.h +2 -2
- data/ext/iodine/http_internal.c +14 -12
- data/ext/iodine/http_internal.h +25 -19
- data/ext/iodine/iodine.c +37 -18
- data/ext/iodine/iodine.h +4 -0
- data/ext/iodine/iodine_caller.c +9 -2
- data/ext/iodine/iodine_caller.h +2 -0
- data/ext/iodine/iodine_connection.c +82 -117
- data/ext/iodine/iodine_defer.c +57 -50
- data/ext/iodine/iodine_defer.h +0 -1
- data/ext/iodine/iodine_fiobj2rb.h +4 -2
- data/ext/iodine/iodine_helpers.c +4 -4
- data/ext/iodine/iodine_http.c +25 -32
- data/ext/iodine/iodine_json.c +2 -1
- data/ext/iodine/iodine_mustache.c +423 -0
- data/ext/iodine/iodine_mustache.h +6 -0
- data/ext/iodine/iodine_pubsub.c +48 -153
- data/ext/iodine/iodine_pubsub.h +5 -4
- data/ext/iodine/iodine_rack_io.c +7 -5
- data/ext/iodine/iodine_store.c +16 -13
- data/ext/iodine/iodine_tcp.c +26 -34
- data/ext/iodine/mustache_parser.h +1085 -0
- data/ext/iodine/redis_engine.c +740 -646
- data/ext/iodine/redis_engine.h +13 -15
- data/ext/iodine/resp_parser.h +11 -5
- data/ext/iodine/websocket_parser.h +13 -13
- data/ext/iodine/websockets.c +240 -393
- data/ext/iodine/websockets.h +52 -113
- data/lib/iodine.rb +1 -1
- data/lib/iodine/mustache.rb +140 -0
- data/lib/iodine/version.rb +1 -1
- metadata +15 -28
- data/ext/iodine/defer.c +0 -566
- data/ext/iodine/defer.h +0 -148
- data/ext/iodine/evio.c +0 -26
- data/ext/iodine/evio.h +0 -161
- data/ext/iodine/evio_callbacks.c +0 -26
- data/ext/iodine/evio_epoll.c +0 -251
- data/ext/iodine/evio_kqueue.c +0 -194
- data/ext/iodine/facil.c +0 -2325
- data/ext/iodine/facil.h +0 -616
- data/ext/iodine/fio_base64.c +0 -277
- data/ext/iodine/fio_base64.h +0 -71
- data/ext/iodine/fio_llist.h +0 -257
- data/ext/iodine/fio_mem.c +0 -675
- data/ext/iodine/fio_mem.h +0 -143
- data/ext/iodine/fio_random.c +0 -248
- data/ext/iodine/fio_random.h +0 -45
- data/ext/iodine/fio_sha1.c +0 -362
- data/ext/iodine/fio_sha1.h +0 -107
- data/ext/iodine/fio_sha2.c +0 -842
- data/ext/iodine/fio_sha2.h +0 -169
- data/ext/iodine/pubsub.c +0 -867
- data/ext/iodine/pubsub.h +0 -221
- data/ext/iodine/sock.c +0 -1366
- data/ext/iodine/sock.h +0 -566
- data/ext/iodine/spnlock.inc +0 -111
data/ext/iodine/iodine_pubsub.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#include "iodine_pubsub.h"
|
2
2
|
#include "iodine_fiobj2rb.h"
|
3
|
-
|
3
|
+
|
4
4
|
#include "redis_engine.h"
|
5
5
|
|
6
6
|
/*
|
@@ -46,9 +46,9 @@ Ruby <=> C Callbacks
|
|
46
46
|
|
47
47
|
typedef struct {
|
48
48
|
iodine_pubsub_s *eng;
|
49
|
-
|
50
|
-
|
51
|
-
|
49
|
+
fio_str_info_s ch;
|
50
|
+
fio_str_info_s msg;
|
51
|
+
fio_match_fn pattern;
|
52
52
|
} iodine_pubsub_task_s;
|
53
53
|
|
54
54
|
#define iodine_engine(eng) ((iodine_pubsub_s *)(eng))
|
@@ -57,21 +57,21 @@ typedef struct {
|
|
57
57
|
static void *iodine_pubsub_GIL_subscribe(void *tsk_) {
|
58
58
|
iodine_pubsub_task_s *task = tsk_;
|
59
59
|
VALUE args[2];
|
60
|
-
|
61
|
-
args[0] = rb_str_new(tmp.data, tmp.len);
|
60
|
+
args[0] = rb_str_new(task->ch.data, task->ch.len);
|
62
61
|
args[1] = task->pattern ? Qtrue : Qnil; // TODO: Qtrue should be :redis
|
63
62
|
IodineCaller.call2(task->eng->handler, subscribe_id, 2, args);
|
64
63
|
return NULL;
|
65
64
|
}
|
66
65
|
|
67
66
|
/** Must subscribe channel. Failures are ignored. */
|
68
|
-
static void iodine_pubsub_on_subscribe(const
|
69
|
-
|
67
|
+
static void iodine_pubsub_on_subscribe(const fio_pubsub_engine_s *eng,
|
68
|
+
fio_str_info_s channel,
|
69
|
+
fio_match_fn match) {
|
70
70
|
if (iodine_engine(eng)->handler == Qnil) {
|
71
71
|
return;
|
72
72
|
}
|
73
73
|
iodine_pubsub_task_s task = {
|
74
|
-
.eng = iodine_engine(eng), .ch = channel, .pattern =
|
74
|
+
.eng = iodine_engine(eng), .ch = channel, .pattern = match};
|
75
75
|
IodineCaller.enterGVL(iodine_pubsub_GIL_subscribe, &task);
|
76
76
|
}
|
77
77
|
|
@@ -79,21 +79,21 @@ static void iodine_pubsub_on_subscribe(const pubsub_engine_s *eng,
|
|
79
79
|
static void *iodine_pubsub_GIL_unsubscribe(void *tsk_) {
|
80
80
|
iodine_pubsub_task_s *task = tsk_;
|
81
81
|
VALUE args[2];
|
82
|
-
|
83
|
-
args[0] = rb_str_new(tmp.data, tmp.len);
|
82
|
+
args[0] = rb_str_new(task->ch.data, task->ch.len);
|
84
83
|
args[1] = task->pattern ? Qtrue : Qnil; // TODO: Qtrue should be :redis
|
85
84
|
IodineCaller.call2(task->eng->handler, unsubscribe_id, 2, args);
|
86
85
|
return NULL;
|
87
86
|
}
|
88
87
|
|
89
88
|
/** Must unsubscribe channel. Failures are ignored. */
|
90
|
-
static void iodine_pubsub_on_unsubscribe(const
|
91
|
-
|
89
|
+
static void iodine_pubsub_on_unsubscribe(const fio_pubsub_engine_s *eng,
|
90
|
+
fio_str_info_s channel,
|
91
|
+
fio_match_fn match) {
|
92
92
|
if (iodine_engine(eng)->handler == Qnil) {
|
93
93
|
return;
|
94
94
|
}
|
95
95
|
iodine_pubsub_task_s task = {
|
96
|
-
.eng = iodine_engine(eng), .ch = channel, .pattern =
|
96
|
+
.eng = iodine_engine(eng), .ch = channel, .pattern = match};
|
97
97
|
IodineCaller.enterGVL(iodine_pubsub_GIL_unsubscribe, &task);
|
98
98
|
}
|
99
99
|
|
@@ -101,33 +101,24 @@ static void iodine_pubsub_on_unsubscribe(const pubsub_engine_s *eng,
|
|
101
101
|
static void *iodine_pubsub_GIL_publish(void *tsk_) {
|
102
102
|
iodine_pubsub_task_s *task = tsk_;
|
103
103
|
VALUE args[2];
|
104
|
-
|
105
|
-
args[
|
106
|
-
tmp = fiobj_obj2cstr(task->msg);
|
107
|
-
args[1] = rb_str_new(tmp.data, tmp.len);
|
104
|
+
args[0] = rb_str_new(task->ch.data, task->ch.len);
|
105
|
+
args[1] = rb_str_new(task->msg.data, task->msg.len);
|
108
106
|
IodineCaller.call2(task->eng->handler, publish_id, 2, args);
|
109
107
|
return NULL;
|
110
108
|
}
|
111
109
|
|
112
110
|
/** Should return 0 on success and -1 on failure. */
|
113
|
-
static
|
114
|
-
|
111
|
+
static void iodine_pubsub_on_publish(const fio_pubsub_engine_s *eng,
|
112
|
+
fio_str_info_s channel, fio_str_info_s msg,
|
113
|
+
uint8_t is_json) {
|
115
114
|
if (iodine_engine(eng)->handler == Qnil) {
|
116
|
-
return
|
115
|
+
return;
|
117
116
|
}
|
118
117
|
iodine_pubsub_task_s task = {
|
119
118
|
.eng = iodine_engine(eng), .ch = channel, .msg = msg};
|
120
119
|
IodineCaller.enterGVL(iodine_pubsub_GIL_publish, &task);
|
121
|
-
|
120
|
+
(void)is_json;
|
122
121
|
}
|
123
|
-
/**
|
124
|
-
* facil.io will call this callback whenever starting, or restarting, the
|
125
|
-
* reactor.
|
126
|
-
*
|
127
|
-
* but iodine engines should probably use the `before_fork` and `after_fork`
|
128
|
-
* hooks.
|
129
|
-
*/
|
130
|
-
static void iodine_pubsub_on_startup(const pubsub_engine_s *eng) { (void)eng; }
|
131
122
|
|
132
123
|
/* *****************************************************************************
|
133
124
|
Ruby methods
|
@@ -194,16 +185,9 @@ static VALUE iodine_pubsub_publish(VALUE self, VALUE to, VALUE message) {
|
|
194
185
|
/* this is a Ruby engine, nothing to do. */
|
195
186
|
return Qnil;
|
196
187
|
}
|
197
|
-
|
198
|
-
|
199
|
-
msg = fiobj_str_new(RSTRING_PTR(message), RSTRING_LEN(message));
|
200
|
-
e->engine->publish(e->engine, ch, msg);
|
201
|
-
fiobj_free(ch);
|
202
|
-
fiobj_free(msg);
|
188
|
+
e->engine->publish(e->engine, IODINE_RSTRINFO(to), IODINE_RSTRINFO(message),
|
189
|
+
0);
|
203
190
|
return self;
|
204
|
-
(void)self;
|
205
|
-
(void)to;
|
206
|
-
(void)message;
|
207
191
|
}
|
208
192
|
|
209
193
|
/* *****************************************************************************
|
@@ -220,7 +204,7 @@ static void iodine_pubsub_data_mark(void *c_) {
|
|
220
204
|
/* a callback for the GC (marking active objects) */
|
221
205
|
static void iodine_pubsub_data_free(void *c_) {
|
222
206
|
iodine_pubsub_s *data = c_;
|
223
|
-
|
207
|
+
fio_pubsub_detach(data->engine);
|
224
208
|
IodineStore.remove(data->handler); /* redundant except during exit */
|
225
209
|
if (data->dealloc) {
|
226
210
|
data->dealloc(data->engine);
|
@@ -254,7 +238,6 @@ static VALUE iodine_pubsub_data_alloc_c(VALUE self) {
|
|
254
238
|
.subscribe = iodine_pubsub_on_subscribe,
|
255
239
|
.unsubscribe = iodine_pubsub_on_unsubscribe,
|
256
240
|
.publish = iodine_pubsub_on_publish,
|
257
|
-
.on_startup = iodine_pubsub_on_startup,
|
258
241
|
},
|
259
242
|
.handler = Qnil,
|
260
243
|
.engine = &c->do_not_touch,
|
@@ -266,12 +249,12 @@ static VALUE iodine_pubsub_data_alloc_c(VALUE self) {
|
|
266
249
|
C engines
|
267
250
|
***************************************************************************** */
|
268
251
|
|
269
|
-
static VALUE iodine_pubsub_make_C_engine(const
|
252
|
+
static VALUE iodine_pubsub_make_C_engine(const fio_pubsub_engine_s *e) {
|
270
253
|
VALUE engine = IodineCaller.call(EngineClass, rb_intern2("new", 3));
|
271
254
|
if (engine == Qnil) {
|
272
255
|
return Qnil;
|
273
256
|
}
|
274
|
-
iodine_pubsub_CData(engine)->engine = (
|
257
|
+
iodine_pubsub_CData(engine)->engine = (fio_pubsub_engine_s *)e;
|
275
258
|
return engine;
|
276
259
|
}
|
277
260
|
|
@@ -292,7 +275,7 @@ static VALUE iodine_pubsub_default_set(VALUE self, VALUE engine) {
|
|
292
275
|
if (e->handler == Qnil) {
|
293
276
|
e->handler = engine;
|
294
277
|
}
|
295
|
-
|
278
|
+
FIO_PUBSUB_DEFAULT = e->engine;
|
296
279
|
rb_ivar_set(self, rb_intern2("default_engine", 14), engine);
|
297
280
|
return engine;
|
298
281
|
}
|
@@ -325,7 +308,7 @@ static VALUE iodine_pubsub_attach(VALUE self, VALUE engine) {
|
|
325
308
|
e->handler = engine;
|
326
309
|
}
|
327
310
|
IodineStore.add(engine);
|
328
|
-
|
311
|
+
fio_pubsub_attach(e->engine);
|
329
312
|
return engine;
|
330
313
|
(void)self;
|
331
314
|
}
|
@@ -347,7 +330,7 @@ static VALUE iodine_pubsub_detach(VALUE self, VALUE engine) {
|
|
347
330
|
e->handler = engine;
|
348
331
|
}
|
349
332
|
IodineStore.remove(engine);
|
350
|
-
|
333
|
+
fio_pubsub_detach(e->engine);
|
351
334
|
return engine;
|
352
335
|
(void)self;
|
353
336
|
}
|
@@ -366,7 +349,7 @@ static VALUE iodine_pubsub_reset(VALUE self, VALUE engine) {
|
|
366
349
|
if (e->handler == Qnil) {
|
367
350
|
e->handler = engine;
|
368
351
|
}
|
369
|
-
|
352
|
+
fio_pubsub_reattach(e->engine);
|
370
353
|
return engine;
|
371
354
|
(void)self;
|
372
355
|
}
|
@@ -404,9 +387,6 @@ static VALUE iodine_pubsub_redis_new(int argc, VALUE *argv, VALUE self) {
|
|
404
387
|
if (RSTRING_LEN(url) > 4096) {
|
405
388
|
rb_raise(rb_eArgError, "Redis URL too long.");
|
406
389
|
}
|
407
|
-
FIOBJ port = FIOBJ_INVALID;
|
408
|
-
FIOBJ address = FIOBJ_INVALID;
|
409
|
-
FIOBJ auth = FIOBJ_INVALID;
|
410
390
|
uint8_t ping = 0;
|
411
391
|
|
412
392
|
iodine_pubsub_s *e = iodine_pubsub_CData(self);
|
@@ -430,113 +410,23 @@ static VALUE iodine_pubsub_redis_new(int argc, VALUE *argv, VALUE self) {
|
|
430
410
|
}
|
431
411
|
|
432
412
|
/* parse URL assume redis://redis:password@localhost:6379 */
|
433
|
-
|
434
|
-
|
435
|
-
char *str = RSTRING_PTR(url);
|
436
|
-
char *pointers[5];
|
437
|
-
char *end = str + l;
|
438
|
-
uint8_t flag = 1;
|
439
|
-
uint8_t counter = 0;
|
440
|
-
for (size_t i = 0; i < l; i++) {
|
441
|
-
if (counter > 4)
|
442
|
-
goto finish;
|
443
|
-
if (str[i] == ':' && str[i + 1] == '/' && str[i + 2] == '/') {
|
444
|
-
pointers[counter++] = str + i + 3;
|
445
|
-
i = i + 2;
|
446
|
-
flag = 0;
|
447
|
-
continue;
|
448
|
-
}
|
449
|
-
if (str[i] == '@' && counter == 1 - flag) {
|
450
|
-
rb_raise(rb_eArgError, "malformed URL");
|
451
|
-
}
|
452
|
-
if (str[i] == ':' || str[i] == '@') {
|
453
|
-
pointers[counter++] = str + i + 1;
|
454
|
-
continue;
|
455
|
-
}
|
456
|
-
if (str[i] == '/') {
|
457
|
-
end = str + i;
|
458
|
-
break;
|
459
|
-
}
|
460
|
-
}
|
461
|
-
if (flag) {
|
462
|
-
if (counter > 3) {
|
463
|
-
rb_raise(rb_eArgError, "malformed URL");
|
464
|
-
}
|
465
|
-
/* move pointers one step forward and set 0 to str... */
|
466
|
-
char *pointers_2[5];
|
467
|
-
for (size_t i = 0; i < counter; ++i) {
|
468
|
-
pointers_2[i + 1] = pointers[i];
|
469
|
-
}
|
470
|
-
pointers_2[0] = str;
|
471
|
-
++counter;
|
472
|
-
for (size_t i = 0; i < counter; ++i) {
|
473
|
-
pointers[i] = pointers_2[i];
|
474
|
-
}
|
475
|
-
}
|
476
|
-
/* review results */
|
477
|
-
switch (counter) {
|
478
|
-
case 1:
|
479
|
-
/* redis://localhost */
|
480
|
-
if (pointers[0] == end) {
|
481
|
-
goto finish;
|
482
|
-
}
|
483
|
-
address = fiobj_str_new(pointers[0], end - pointers[0]);
|
484
|
-
break;
|
485
|
-
case 2:
|
486
|
-
/* redis://localhost:6379 */
|
487
|
-
if (pointers[1] - pointers[0] - 1 == 0) {
|
488
|
-
goto finish;
|
489
|
-
}
|
490
|
-
address = fiobj_str_new(pointers[0], pointers[1] - pointers[0] - 1);
|
491
|
-
if (pointers[1] != end) {
|
492
|
-
port = fiobj_str_new(pointers[1], end - pointers[1]);
|
493
|
-
}
|
494
|
-
break;
|
495
|
-
case 3:
|
496
|
-
/* redis://redis:password@localhost */
|
497
|
-
if (pointers[2] - pointers[1] - 1 == 0 || end - pointers[2] == 0) {
|
498
|
-
goto finish;
|
499
|
-
}
|
500
|
-
address = fiobj_str_new(pointers[2], end - pointers[2]);
|
501
|
-
auth = fiobj_str_new(pointers[1], pointers[2] - pointers[1] - 1);
|
502
|
-
break;
|
503
|
-
case 4:
|
504
|
-
/* redis://redis:password@localhost:6379 */
|
505
|
-
if (pointers[2] - pointers[1] - 1 == 0 ||
|
506
|
-
pointers[3] - pointers[2] - 1 == 0 || end - pointers[3] == 0) {
|
507
|
-
goto finish;
|
508
|
-
}
|
509
|
-
port = fiobj_str_new(pointers[3], end - pointers[3]);
|
510
|
-
address = fiobj_str_new(pointers[2], pointers[3] - pointers[2] - 1);
|
511
|
-
auth = fiobj_str_new(pointers[1], pointers[2] - pointers[1] - 1);
|
512
|
-
break;
|
513
|
-
default:
|
514
|
-
goto finish;
|
515
|
-
}
|
516
|
-
}
|
413
|
+
http_url_s info = http_url_parse(RSTRING_PTR(url), RSTRING_LEN(url));
|
414
|
+
|
517
415
|
fprintf(
|
518
416
|
stderr,
|
519
417
|
"INFO: Initializing Redis engine for address: %s - port: %s - auth %s\n",
|
520
|
-
|
521
|
-
|
418
|
+
info.host.data ? info.host.data : "-",
|
419
|
+
info.port.data ? info.port.data : "-",
|
420
|
+
info.password.data ? info.password.data : "-");
|
522
421
|
/* create engine */
|
523
|
-
e->engine = redis_engine_create(
|
524
|
-
|
525
|
-
.data,
|
526
|
-
.port = (port == FIOBJ_INVALID ? "6379" : fiobj_obj2cstr(port).data),
|
527
|
-
.ping_interval = ping,
|
528
|
-
.auth = (auth == FIOBJ_INVALID ? NULL : fiobj_obj2cstr(auth).data),
|
529
|
-
.auth_len = (auth == FIOBJ_INVALID ? 0 : fiobj_obj2cstr(auth).len));
|
422
|
+
e->engine = redis_engine_create(.address = info.host, .port = info.port,
|
423
|
+
.auth = info.password, .ping_interval = ping);
|
530
424
|
if (!e->engine) {
|
531
425
|
e->engine = &e->do_not_touch;
|
532
426
|
} else {
|
533
427
|
e->dealloc = redis_engine_destroy;
|
534
428
|
}
|
535
429
|
|
536
|
-
finish:
|
537
|
-
fiobj_free(port);
|
538
|
-
fiobj_free(address);
|
539
|
-
fiobj_free(auth);
|
540
430
|
if (e->engine == &e->do_not_touch) {
|
541
431
|
rb_raise(rb_eArgError,
|
542
432
|
"Error initializing the Redis engine - malformed URL?");
|
@@ -548,7 +438,7 @@ finish:
|
|
548
438
|
}
|
549
439
|
|
550
440
|
/** A callback for Redis commands. */
|
551
|
-
static void iodine_pubsub_redis_callback(
|
441
|
+
static void iodine_pubsub_redis_callback(fio_pubsub_engine_s *e, FIOBJ response,
|
552
442
|
void *udata) {
|
553
443
|
VALUE block = (VALUE)udata;
|
554
444
|
if (block == Qnil) {
|
@@ -622,12 +512,10 @@ static VALUE iodine_pubsub_redis_cmd(int argc, VALUE *argv, VALUE self) {
|
|
622
512
|
goto wrong_type;
|
623
513
|
}
|
624
514
|
}
|
625
|
-
|
626
|
-
if (redis_engine_send(e->engine, cmd, data, iodine_pubsub_redis_callback,
|
515
|
+
if (redis_engine_send(e->engine, data, iodine_pubsub_redis_callback,
|
627
516
|
(void *)block)) {
|
628
517
|
iodine_pubsub_redis_callback(e->engine, fiobj_null(), (void *)block);
|
629
518
|
}
|
630
|
-
fiobj_free(cmd);
|
631
519
|
fiobj_free(data);
|
632
520
|
return self;
|
633
521
|
|
@@ -688,10 +576,17 @@ void iodine_pubsub_init(void) {
|
|
688
576
|
|
689
577
|
/* CLUSTER publishes data to all the subscribers in the process cluster. */
|
690
578
|
rb_define_const(PubSubModule, "CLUSTER",
|
691
|
-
iodine_pubsub_make_C_engine(
|
579
|
+
iodine_pubsub_make_C_engine(FIO_PUBSUB_CLUSTER));
|
692
580
|
/* PROCESS publishes data to all the subscribers in a single process. */
|
693
581
|
rb_define_const(PubSubModule, "PROCESS",
|
694
|
-
iodine_pubsub_make_C_engine(
|
582
|
+
iodine_pubsub_make_C_engine(FIO_PUBSUB_PROCESS));
|
583
|
+
/* SIBLINGS publishes data to all the subscribers in the *other* processes
|
584
|
+
* process. */
|
585
|
+
rb_define_const(PubSubModule, "SIBLINGS",
|
586
|
+
iodine_pubsub_make_C_engine(FIO_PUBSUB_SIBLINGS));
|
587
|
+
/* PUBLISH2ROOT publishes data only to the root / master process. */
|
588
|
+
rb_define_const(PubSubModule, "PUBLISH2ROOT",
|
589
|
+
iodine_pubsub_make_C_engine(FIO_PUBSUB_ROOT));
|
695
590
|
|
696
591
|
VALUE RedisClass = rb_define_class_under(PubSubModule, "Redis", EngineClass);
|
697
592
|
rb_define_method(RedisClass, "initialize", iodine_pubsub_redis_new, -1);
|
data/ext/iodine/iodine_pubsub.h
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
#define H_IODINE_PUBSUB_H
|
3
3
|
|
4
4
|
#include "iodine.h"
|
5
|
-
|
5
|
+
|
6
|
+
#include "fio.h"
|
6
7
|
|
7
8
|
/** Initializes the PubSub::Engine Ruby class. */
|
8
9
|
void iodine_pubsub_init(void);
|
@@ -10,10 +11,10 @@ void iodine_pubsub_init(void);
|
|
10
11
|
extern const rb_data_type_t iodine_pubsub_data_type;
|
11
12
|
|
12
13
|
typedef struct {
|
13
|
-
|
14
|
+
fio_pubsub_engine_s do_not_touch;
|
14
15
|
VALUE handler;
|
15
|
-
|
16
|
-
void (*dealloc)(
|
16
|
+
fio_pubsub_engine_s *engine;
|
17
|
+
void (*dealloc)(fio_pubsub_engine_s *engine);
|
17
18
|
} iodine_pubsub_s;
|
18
19
|
|
19
20
|
static inline iodine_pubsub_s *iodine_pubsub_CData(VALUE obj) {
|
data/ext/iodine/iodine_rack_io.c
CHANGED
@@ -30,7 +30,7 @@ read behaves like IO#read. Its signature is read([length, [buffer]]). If given,
|
|
30
30
|
length must be a non-negative Integer (>= 0) or nil, and buffer must be a String
|
31
31
|
and may not be nil. If length is given and not nil, then this method reads at
|
32
32
|
most length bytes from the input stream. If length is not given or nil, then
|
33
|
-
this method reads all data until
|
33
|
+
this method reads all data until EOF. When EOF is reached, this method returns
|
34
34
|
nil if length is given and not nil, or “” if length is not given or is nil. If
|
35
35
|
buffer is given, then the read data will be placed into buffer instead of a
|
36
36
|
newly created String object.
|
@@ -98,7 +98,7 @@ static VALUE rio_gets(VALUE self) {
|
|
98
98
|
FIOBJ io = get_data(self);
|
99
99
|
if (!FIOBJ_TYPE_IS(io, FIOBJ_T_DATA))
|
100
100
|
return Qnil;
|
101
|
-
|
101
|
+
fio_str_info_s line = fiobj_data_gets(io);
|
102
102
|
if (line.len) {
|
103
103
|
VALUE buffer = rb_str_new(line.data, line.len);
|
104
104
|
// make sure the buffer is binary encoded.
|
@@ -133,7 +133,7 @@ static VALUE rio_read(int argc, VALUE *argv, VALUE self) {
|
|
133
133
|
ret_nil = 1;
|
134
134
|
}
|
135
135
|
// return if we're at the EOF.
|
136
|
-
|
136
|
+
fio_str_info_s buf = fiobj_data_read(io, len);
|
137
137
|
if (buf.len) {
|
138
138
|
// create the buffer if we don't have one.
|
139
139
|
if (buffer == Qnil) {
|
@@ -198,7 +198,7 @@ static VALUE rio_get_io(int argc, VALUE *argv, VALUE self) {
|
|
198
198
|
set_handle(self, NULL);
|
199
199
|
// hijack the IO object
|
200
200
|
intptr_t uuid = http_hijack(h, NULL);
|
201
|
-
VALUE fd = INT2FIX(
|
201
|
+
VALUE fd = INT2FIX(fio_uuid2fd(uuid));
|
202
202
|
// VALUE new_io = how the fuck do we create a new IO from the fd?
|
203
203
|
VALUE new_io = IodineCaller.call2(TCPSOCKET_CLASS, for_fd_id, 1,
|
204
204
|
&fd); // TCPSocket.for_fd(fd) ... cool...
|
@@ -260,5 +260,7 @@ static void init_rack_io(void) {
|
|
260
260
|
////////////////////////////////////////////////////////////////////////////
|
261
261
|
// the API interface
|
262
262
|
struct IodineRackIO IodineRackIO = {
|
263
|
-
.create = new_rack_io,
|
263
|
+
.create = new_rack_io,
|
264
|
+
.close = close_rack_io,
|
265
|
+
.init = init_rack_io,
|
264
266
|
};
|
data/ext/iodine/iodine_store.c
CHANGED
@@ -2,9 +2,12 @@
|
|
2
2
|
|
3
3
|
#include "fio_hashmap.h"
|
4
4
|
#include "iodine_store.h"
|
5
|
-
#include "spnlock.inc"
|
6
5
|
|
7
|
-
|
6
|
+
#include <fio.h>
|
7
|
+
#include <inttypes.h>
|
8
|
+
#include <stdint.h>
|
9
|
+
|
10
|
+
fio_lock_i lock = FIO_LOCK_INIT;
|
8
11
|
fio_hash_s storage = FIO_HASH_INIT;
|
9
12
|
|
10
13
|
#ifndef IODINE_DEBUG
|
@@ -19,12 +22,12 @@ API
|
|
19
22
|
static VALUE storage_add(VALUE obj) {
|
20
23
|
if (obj == Qnil || obj == Qtrue || obj == Qfalse)
|
21
24
|
return obj;
|
22
|
-
|
25
|
+
fio_lock(&lock);
|
23
26
|
uintptr_t val = (uintptr_t)fio_hash_insert(&storage, obj, (void *)1);
|
24
27
|
if (val) {
|
25
28
|
fio_hash_insert(&storage, obj, (void *)(val + 1));
|
26
29
|
}
|
27
|
-
|
30
|
+
fio_unlock(&lock);
|
28
31
|
return obj;
|
29
32
|
}
|
30
33
|
/** Removes an object from the storage (or decreases it's reference count). */
|
@@ -32,7 +35,7 @@ static VALUE storage_remove(VALUE obj) {
|
|
32
35
|
if (obj == Qnil || obj == Qtrue || obj == Qfalse || storage.map == NULL ||
|
33
36
|
storage.count == 0)
|
34
37
|
return obj;
|
35
|
-
|
38
|
+
fio_lock(&lock);
|
36
39
|
uintptr_t val = (uintptr_t)fio_hash_insert(&storage, obj, NULL);
|
37
40
|
if (val > 1) {
|
38
41
|
fio_hash_insert(&storage, obj, (void *)(val - 1));
|
@@ -41,16 +44,16 @@ static VALUE storage_remove(VALUE obj) {
|
|
41
44
|
(storage.pos << 1) > storage.capa) {
|
42
45
|
fio_hash_compact(&storage);
|
43
46
|
}
|
44
|
-
|
47
|
+
fio_unlock(&lock);
|
45
48
|
return obj;
|
46
49
|
}
|
47
50
|
/** Should be called after forking to reset locks */
|
48
|
-
static void storage_after_fork(void) { lock =
|
51
|
+
static void storage_after_fork(void) { lock = FIO_LOCK_INIT; }
|
49
52
|
|
50
53
|
/** Prints debugging information to the console. */
|
51
54
|
static void storage_print(void) {
|
52
55
|
fprintf(stderr, "Ruby <=> C Memory storage stats (pid: %d):\n", getpid());
|
53
|
-
|
56
|
+
fio_lock(&lock);
|
54
57
|
uintptr_t index = 0;
|
55
58
|
FIO_HASH_FOR_LOOP(&storage, pos) {
|
56
59
|
if (pos->obj) {
|
@@ -62,7 +65,7 @@ static void storage_print(void) {
|
|
62
65
|
fprintf(stderr,
|
63
66
|
"Storage uses %" PRIuPTR " Hash bins for %" PRIuPTR " objects\n",
|
64
67
|
storage.capa, storage.count);
|
65
|
-
|
68
|
+
fio_unlock(&lock);
|
66
69
|
}
|
67
70
|
|
68
71
|
/**
|
@@ -83,14 +86,14 @@ static void storage_mark(void *ignore) {
|
|
83
86
|
#if IODINE_DEBUG
|
84
87
|
storage_print();
|
85
88
|
#endif
|
86
|
-
|
89
|
+
fio_lock(&lock);
|
87
90
|
// fio_hash_compact(&storage);
|
88
91
|
FIO_HASH_FOR_LOOP(&storage, pos) {
|
89
92
|
if (pos->obj) {
|
90
93
|
rb_gc_mark((VALUE)pos->key);
|
91
94
|
}
|
92
95
|
}
|
93
|
-
|
96
|
+
fio_unlock(&lock);
|
94
97
|
}
|
95
98
|
|
96
99
|
/* clear the registry (end of lifetime) */
|
@@ -99,10 +102,10 @@ static void storage_clear(void *ignore) {
|
|
99
102
|
#if IODINE_DEBUG == 1
|
100
103
|
fprintf(stderr, "* INFO: Ruby<=>C Storage cleared.\n");
|
101
104
|
#endif
|
102
|
-
|
105
|
+
fio_lock(&lock);
|
103
106
|
fio_hash_free(&storage);
|
104
107
|
storage = (fio_hash_s)FIO_HASH_INIT;
|
105
|
-
|
108
|
+
fio_unlock(&lock);
|
106
109
|
}
|
107
110
|
|
108
111
|
/*
|