iodine 0.7.9 → 0.7.10
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/.travis.yml +8 -2
- data/CHANGELOG.md +14 -0
- data/README.md +85 -29
- data/{examples → bin}/info.md +0 -0
- data/bin/{mustache.rb → mustache_bench.rb} +0 -0
- data/examples/shootout.ru +4 -4
- data/ext/iodine/extconf.rb +1 -1
- data/ext/iodine/fio.c +738 -549
- data/ext/iodine/fio.h +4 -5
- data/ext/iodine/fiobj_mustache.c +1 -1
- data/ext/iodine/fiobj_numbers.c +3 -3
- data/ext/iodine/http.c +15 -14
- data/ext/iodine/http1.c +6 -6
- data/ext/iodine/http1_parser.c +3 -3
- data/ext/iodine/http_internal.c +3 -3
- data/ext/iodine/http_internal.h +1 -1
- data/ext/iodine/iodine.c +7 -8
- data/ext/iodine/iodine_connection.c +48 -8
- data/ext/iodine/iodine_defer.c +7 -7
- data/ext/iodine/iodine_mustache.c +1 -1
- data/ext/iodine/redis_engine.c +4 -4
- data/ext/iodine/websockets.c +41 -22
- data/ext/iodine/websockets.h +13 -12
- data/iodine.gemspec +0 -2
- data/lib/iodine.rb +4 -0
- data/lib/iodine/version.rb +1 -1
- data/lib/rack/handler/iodine.rb +2 -4
- metadata +5 -39
- data/bin/config.ru +0 -97
- data/bin/echo +0 -46
- data/bin/http-big +0 -63
- data/bin/http-hello +0 -62
- data/bin/http-playground +0 -124
- data/bin/playground +0 -62
- data/bin/raw-rbhttp +0 -38
- data/bin/raw-rbhttp-em +0 -63
- data/bin/raw_broadcast +0 -64
- data/bin/test_with_faye +0 -44
- data/bin/updated api +0 -113
- data/bin/ws-broadcast +0 -106
- data/bin/ws-echo +0 -117
- data/examples/test_template.mustache +0 -16
data/ext/iodine/fio.h
CHANGED
@@ -109,7 +109,7 @@ Version and helper macros
|
|
109
109
|
#define FIO_VERSION_MAJOR 0
|
110
110
|
#define FIO_VERSION_MINOR 7
|
111
111
|
#define FIO_VERSION_PATCH 0
|
112
|
-
#define FIO_VERSION_BETA
|
112
|
+
#define FIO_VERSION_BETA 3
|
113
113
|
|
114
114
|
/* Automatically convert version data to a string constant - ignore these two */
|
115
115
|
#define FIO_MACRO2STR_STEP2(macro) #macro
|
@@ -167,7 +167,8 @@ Version and helper macros
|
|
167
167
|
|
168
168
|
#ifndef FIO_PRINT_STATE
|
169
169
|
/**
|
170
|
-
*
|
170
|
+
* Enables the FIO_LOG_STATE(msg,...) macro, which prints information level
|
171
|
+
* messages to stderr.
|
171
172
|
*/
|
172
173
|
#define FIO_PRINT_STATE 1
|
173
174
|
#endif
|
@@ -328,7 +329,7 @@ void *fio_mmap(size_t size);
|
|
328
329
|
void fio_malloc_after_fork(void);
|
329
330
|
|
330
331
|
#if FIO_FORCE_MALLOC
|
331
|
-
#define FIO_MALLOC(size)
|
332
|
+
#define FIO_MALLOC(size) calloc((size), 1)
|
332
333
|
#define FIO_CALLOC(size, units) calloc((size), (units))
|
333
334
|
#define FIO_REALLOC(ptr, new_length, existing_data_length) \
|
334
335
|
realloc((ptr), (new_length))
|
@@ -1713,8 +1714,6 @@ struct fio_msg_metadata_s {
|
|
1713
1714
|
void (*on_finish)(fio_msg_s *msg, void *metadata);
|
1714
1715
|
/** The pointer to be disclosed to the `fio_message_metadata` function. */
|
1715
1716
|
void *metadata;
|
1716
|
-
/** RESERVED for internal use (Metadata linked list). */
|
1717
|
-
fio_msg_metadata_s *next;
|
1718
1717
|
};
|
1719
1718
|
|
1720
1719
|
/**
|
data/ext/iodine/fiobj_mustache.c
CHANGED
@@ -66,7 +66,7 @@ b = a.map {|s| s.length }
|
|
66
66
|
puts "static char *html_escape_strs[] = {", a.to_s.slice(1..-2) ,"};",
|
67
67
|
"static uint8_t html_escape_len[] = {", b.to_s.slice(1..-2),"};"
|
68
68
|
*/
|
69
|
-
static char *html_escape_strs[] = {
|
69
|
+
static const char *html_escape_strs[] = {
|
70
70
|
"�", "", "", "", "", "", "",
|
71
71
|
"", "", "	", "
", "", "", "
",
|
72
72
|
"", "", "", "", "", "", "",
|
data/ext/iodine/fiobj_numbers.c
CHANGED
@@ -53,12 +53,12 @@ static fio_str_info_s fio_i2str(const FIOBJ o) {
|
|
53
53
|
}
|
54
54
|
static fio_str_info_s fio_f2str(const FIOBJ o) {
|
55
55
|
if (isnan(obj2float(o)->f))
|
56
|
-
return (fio_str_info_s){.data = "NaN", .len = 3};
|
56
|
+
return (fio_str_info_s){.data = (char *)"NaN", .len = 3};
|
57
57
|
else if (isinf(obj2float(o)->f)) {
|
58
58
|
if (obj2float(o)->f > 0)
|
59
|
-
return (fio_str_info_s){.data = "Infinity", .len = 8};
|
59
|
+
return (fio_str_info_s){.data = (char *)"Infinity", .len = 8};
|
60
60
|
else
|
61
|
-
return (fio_str_info_s){.data = "-Infinity", .len = 9};
|
61
|
+
return (fio_str_info_s){.data = (char *)"-Infinity", .len = 9};
|
62
62
|
}
|
63
63
|
return (fio_str_info_s){
|
64
64
|
.data = num_buffer,
|
data/ext/iodine/http.c
CHANGED
@@ -608,8 +608,8 @@ found_file:
|
|
608
608
|
switch (s.len) {
|
609
609
|
case 7:
|
610
610
|
if (!strncasecmp("options", s.data, 7)) {
|
611
|
-
http_set_header2(h, (fio_str_info_s){.data = "allow", .len = 5},
|
612
|
-
(fio_str_info_s){.data = "GET, HEAD", .len = 9});
|
611
|
+
http_set_header2(h, (fio_str_info_s){.data = (char *)"allow", .len = 5},
|
612
|
+
(fio_str_info_s){.data = (char *)"GET, HEAD", .len = 9});
|
613
613
|
h->status = 200;
|
614
614
|
http_finish(h);
|
615
615
|
return 0;
|
@@ -694,7 +694,8 @@ int http_send_error(http_s *r, size_t error) {
|
|
694
694
|
if (http_sendfile2(r, http2protocol(r)->settings->public_folder,
|
695
695
|
http2protocol(r)->settings->public_folder_length, buffer,
|
696
696
|
pos)) {
|
697
|
-
http_set_header(r, HTTP_HEADER_CONTENT_TYPE,
|
697
|
+
http_set_header(r, HTTP_HEADER_CONTENT_TYPE,
|
698
|
+
http_mimetype_find((char *)"txt", 3));
|
698
699
|
fio_str_info_s t = http_status2str(error);
|
699
700
|
http_send_body(r, t.data, t.len);
|
700
701
|
}
|
@@ -1148,15 +1149,15 @@ intptr_t http_connect(const char *address,
|
|
1148
1149
|
} else {
|
1149
1150
|
p++;
|
1150
1151
|
if (!len) {
|
1151
|
-
a = "localhost";
|
1152
|
+
a = (char *)"localhost";
|
1152
1153
|
len = 9;
|
1153
1154
|
}
|
1154
1155
|
}
|
1155
1156
|
} else {
|
1156
1157
|
if (is_secure)
|
1157
|
-
p = "443";
|
1158
|
+
p = (char *)"443";
|
1158
1159
|
else
|
1159
|
-
p = "80";
|
1160
|
+
p = (char *)"80";
|
1160
1161
|
}
|
1161
1162
|
|
1162
1163
|
/* set settings */
|
@@ -1179,7 +1180,7 @@ intptr_t http_connect(const char *address,
|
|
1179
1180
|
h->status = 0;
|
1180
1181
|
h->path = path;
|
1181
1182
|
settings->udata = h;
|
1182
|
-
http_set_header2(h, (fio_str_info_s){.data = "host", .len = 4},
|
1183
|
+
http_set_header2(h, (fio_str_info_s){.data = (char *)"host", .len = 4},
|
1183
1184
|
(fio_str_info_s){.data = a, .len = len});
|
1184
1185
|
intptr_t ret;
|
1185
1186
|
if (is_websocket) {
|
@@ -1302,7 +1303,7 @@ static void http_sse_on_unsubscribe(void *sse_, void *args_) {
|
|
1302
1303
|
struct http_sse_subscribe_args *args = args_;
|
1303
1304
|
if (args->on_unsubscribe)
|
1304
1305
|
args->on_unsubscribe(args->udata);
|
1305
|
-
|
1306
|
+
fio_free(args);
|
1306
1307
|
http_sse_try_free(sse);
|
1307
1308
|
}
|
1308
1309
|
|
@@ -1328,7 +1329,7 @@ uintptr_t http_sse_subscribe(http_sse_s *sse_,
|
|
1328
1329
|
return 0;
|
1329
1330
|
if (!args.on_message)
|
1330
1331
|
args.on_message = http_sse_on_message__direct;
|
1331
|
-
struct http_sse_subscribe_args *udata =
|
1332
|
+
struct http_sse_subscribe_args *udata = fio_malloc(sizeof(*udata));
|
1332
1333
|
FIO_ASSERT_ALLOC(udata);
|
1333
1334
|
*udata = args;
|
1334
1335
|
|
@@ -1403,15 +1404,15 @@ int http_sse_write(http_sse_s *sse, struct http_sse_write_args args) {
|
|
1403
1404
|
args.data.len + 2 + 7 + 10 + 4;
|
1404
1405
|
buf = fiobj_str_buf(total);
|
1405
1406
|
}
|
1406
|
-
http_sse_copy2str(buf, "id: ", 4, args.id);
|
1407
|
-
http_sse_copy2str(buf, "event: ", 7, args.event);
|
1407
|
+
http_sse_copy2str(buf, (char *)"id: ", 4, args.id);
|
1408
|
+
http_sse_copy2str(buf, (char *)"event: ", 7, args.event);
|
1408
1409
|
if (args.retry) {
|
1409
1410
|
FIOBJ i = fiobj_num_new(args.retry);
|
1410
|
-
fiobj_str_write(buf, "retry: ", 7);
|
1411
|
+
fiobj_str_write(buf, (char *)"retry: ", 7);
|
1411
1412
|
fiobj_str_join(buf, i);
|
1412
1413
|
fiobj_free(i);
|
1413
1414
|
}
|
1414
|
-
http_sse_copy2str(buf, "data: ", 6, args.data);
|
1415
|
+
http_sse_copy2str(buf, (char *)"data: ", 6, args.data);
|
1415
1416
|
fiobj_str_write(buf, "\r\n", 2);
|
1416
1417
|
return FIO_LS_EMBD_OBJ(http_sse_internal_s, sse, sse)
|
1417
1418
|
->vtable->http_sse_write(sse, buf);
|
@@ -2819,7 +2820,7 @@ static char invalid_cookie_value_char[256] = {
|
|
2819
2820
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
2820
2821
|
|
2821
2822
|
// clang-format off
|
2822
|
-
#define HTTP_SET_STATUS_STR(status, str) [status-100] = { .data = (str), .len = (sizeof(str) - 1) }
|
2823
|
+
#define HTTP_SET_STATUS_STR(status, str) [status-100] = { .data = (char *)(str), .len = (sizeof(str) - 1) }
|
2823
2824
|
// clang-format on
|
2824
2825
|
|
2825
2826
|
/** Returns the status as a C string struct */
|
data/ext/iodine/http1.c
CHANGED
@@ -442,7 +442,7 @@ static uint8_t http1_sse_on_shutdown(intptr_t uuid, fio_protocol_s *p_) {
|
|
442
442
|
static void http1_sse_on_close(intptr_t uuid, fio_protocol_s *p_) {
|
443
443
|
http1_sse_fio_protocol_s *p = (http1_sse_fio_protocol_s *)p_;
|
444
444
|
http_sse_destroy(p->sse);
|
445
|
-
|
445
|
+
fio_free(p);
|
446
446
|
(void)uuid;
|
447
447
|
}
|
448
448
|
static void http1_sse_ping(intptr_t uuid, fio_protocol_s *p_) {
|
@@ -472,7 +472,7 @@ static int http1_upgrade2sse(http_s *h, http_sse_s *sse) {
|
|
472
472
|
htt1p_finish(h); /* avoid the enforced content length in http_finish */
|
473
473
|
|
474
474
|
/* switch protocol to SSE */
|
475
|
-
http1_sse_fio_protocol_s *sse_pr =
|
475
|
+
http1_sse_fio_protocol_s *sse_pr = fio_malloc(sizeof(*sse_pr));
|
476
476
|
if (!sse_pr)
|
477
477
|
goto failed;
|
478
478
|
*sse_pr = (http1_sse_fio_protocol_s){
|
@@ -483,7 +483,7 @@ static int http1_upgrade2sse(http_s *h, http_sse_s *sse) {
|
|
483
483
|
.on_close = http1_sse_on_close,
|
484
484
|
.ping = http1_sse_ping,
|
485
485
|
},
|
486
|
-
.sse =
|
486
|
+
.sse = fio_malloc(sizeof(*(sse_pr->sse))),
|
487
487
|
};
|
488
488
|
|
489
489
|
if (!sse_pr->sse)
|
@@ -763,7 +763,7 @@ fio_protocol_s *http1_new(uintptr_t uuid, http_settings_s *settings,
|
|
763
763
|
void *unread_data, size_t unread_length) {
|
764
764
|
if (unread_data && unread_length > HTTP_MAX_HEADER_LENGTH)
|
765
765
|
return NULL;
|
766
|
-
http1pr_s *p =
|
766
|
+
http1pr_s *p = fio_malloc(sizeof(*p) + HTTP_MAX_HEADER_LENGTH);
|
767
767
|
FIO_ASSERT_ALLOC(p);
|
768
768
|
*p = (http1pr_s){
|
769
769
|
.p.protocol =
|
@@ -791,7 +791,7 @@ void http1_destroy(fio_protocol_s *pr) {
|
|
791
791
|
http1pr_s *p = (http1pr_s *)pr;
|
792
792
|
http1_pr2handle(p).status = 0;
|
793
793
|
http_s_destroy(&http1_pr2handle(p), 0);
|
794
|
-
|
794
|
+
fio_free(p);
|
795
795
|
}
|
796
796
|
|
797
797
|
/* *****************************************************************************
|
@@ -799,7 +799,7 @@ Protocol Data
|
|
799
799
|
***************************************************************************** */
|
800
800
|
|
801
801
|
// clang-format off
|
802
|
-
#define HTTP_SET_STATUS_STR(status, str) [((status)-100)] = { .data = ("HTTP/1.1 " #status " " str "\r\n"), .len = (sizeof("HTTP/1.1 " #status " " str "\r\n") - 1) }
|
802
|
+
#define HTTP_SET_STATUS_STR(status, str) [((status)-100)] = { .data = (char*)("HTTP/1.1 " #status " " str "\r\n"), .len = (sizeof("HTTP/1.1 " #status " " str "\r\n") - 1) }
|
803
803
|
// #undef HTTP_SET_STATUS_STR
|
804
804
|
// clang-format on
|
805
805
|
|
data/ext/iodine/http1_parser.c
CHANGED
@@ -169,7 +169,7 @@ inline static int consume_request_line(struct http1_fio_parser_args_s *args,
|
|
169
169
|
return -1;
|
170
170
|
*tmp = ' ';
|
171
171
|
if (!seek2ch(&host_end, tmp, '/')) {
|
172
|
-
if (args->on_path(args->parser, "/", 1))
|
172
|
+
if (args->on_path(args->parser, (char *)"/", 1))
|
173
173
|
return -1;
|
174
174
|
goto start_version;
|
175
175
|
}
|
@@ -201,8 +201,8 @@ start_version:
|
|
201
201
|
if (args->on_http_version(args->parser, (char *)start, end - start))
|
202
202
|
return -1;
|
203
203
|
/* */
|
204
|
-
if (host_start && args->on_header(args->parser, "host", 4,
|
205
|
-
host_end - host_start))
|
204
|
+
if (host_start && args->on_header(args->parser, (char *)"host", 4,
|
205
|
+
(char *)host_start, host_end - host_start))
|
206
206
|
return -1;
|
207
207
|
return 0;
|
208
208
|
}
|
data/ext/iodine/http_internal.c
CHANGED
@@ -68,7 +68,7 @@ upgrade:
|
|
68
68
|
return;
|
69
69
|
}
|
70
70
|
eventsource:
|
71
|
-
settings->on_upgrade(h, "sse", 3);
|
71
|
+
settings->on_upgrade(h, (char *)"sse", 3);
|
72
72
|
return;
|
73
73
|
}
|
74
74
|
|
@@ -252,8 +252,8 @@ static void http_lib_init(void *ignr_) {
|
|
252
252
|
fiobj_obj2hash(HTTP_HVALUE_WS_VERSION);
|
253
253
|
|
254
254
|
#define REGISTER_MIME(ext, type) \
|
255
|
-
http_mimetype_register(ext, sizeof(ext) - 1,
|
256
|
-
fiobj_str_new(type, sizeof(type) - 1))
|
255
|
+
http_mimetype_register((char *)ext, sizeof(ext) - 1, \
|
256
|
+
fiobj_str_new((char *)type, sizeof(type) - 1))
|
257
257
|
|
258
258
|
REGISTER_MIME("123", "application/vnd.lotus-1-2-3");
|
259
259
|
REGISTER_MIME("3dml", "text/vnd.in3d.3dml");
|
data/ext/iodine/http_internal.h
CHANGED
@@ -175,7 +175,7 @@ static inline void http_sse_init(http_sse_internal_s *sse, intptr_t uuid,
|
|
175
175
|
static inline void http_sse_try_free(http_sse_internal_s *sse) {
|
176
176
|
if (fio_atomic_sub(&sse->ref, 1))
|
177
177
|
return;
|
178
|
-
|
178
|
+
fio_free(sse);
|
179
179
|
}
|
180
180
|
|
181
181
|
static inline void http_sse_destroy(http_sse_internal_s *sse) {
|
data/ext/iodine/iodine.c
CHANGED
@@ -309,7 +309,7 @@ static VALUE iodine_cli_parse(VALUE self, VALUE desc) {
|
|
309
309
|
}
|
310
310
|
char **argv = calloc(argc, sizeof(*argv));
|
311
311
|
FIO_ASSERT_ALLOC(argv);
|
312
|
-
argv[0] = "iodine";
|
312
|
+
argv[0] = (char *)"iodine";
|
313
313
|
for (int i = 1; i < argc; ++i) {
|
314
314
|
VALUE tmp = rb_ary_entry(ARGV, (long)(i - 1));
|
315
315
|
if (TYPE(tmp) != T_STRING) {
|
@@ -326,13 +326,13 @@ static VALUE iodine_cli_parse(VALUE self, VALUE desc) {
|
|
326
326
|
/* Levarage the facil.io CLI library */
|
327
327
|
fio_cli_start(
|
328
328
|
argc, (const char **)argv, 0, -1, StringValueCStr(desc),
|
329
|
-
"\x1B[
|
329
|
+
"\x1B[4mAddress Binding:\x1B[0m", FIO_CLI_TYPE_PRINT,
|
330
330
|
"-bind -b -address address to listen to. defaults any available.",
|
331
331
|
"-port -p port number to listen to. defaults port 3000", FIO_CLI_TYPE_INT,
|
332
|
-
"\n\x1B[
|
332
|
+
"\n\x1B[4mConcurrency:\x1B[0m", FIO_CLI_TYPE_PRINT,
|
333
333
|
"-workers -w number of processes to use.", FIO_CLI_TYPE_INT,
|
334
334
|
"-threads -t number of threads per process.", FIO_CLI_TYPE_INT,
|
335
|
-
"\n\x1B[
|
335
|
+
"\n\x1B[4mHTTP Server:\x1B[0m", FIO_CLI_TYPE_PRINT,
|
336
336
|
"-public -www public folder, for static file service.",
|
337
337
|
"-log -v HTTP request logging.", FIO_CLI_TYPE_BOOL,
|
338
338
|
"-keep-alive -k -tout HTTP keep-alive timeout (0..255). Default: 40s",
|
@@ -342,15 +342,14 @@ static VALUE iodine_cli_parse(VALUE self, VALUE desc) {
|
|
342
342
|
FIO_CLI_TYPE_INT,
|
343
343
|
"-max-header -maxhd header limit per HTTP request in Kb."
|
344
344
|
" Default: 32Kb.",
|
345
|
-
FIO_CLI_TYPE_INT, "\n\x1B[
|
346
|
-
FIO_CLI_TYPE_PRINT,
|
345
|
+
FIO_CLI_TYPE_INT, "\n\x1B[4mWebSocket Server:\x1B[0m", FIO_CLI_TYPE_PRINT,
|
347
346
|
"-max-msg -maxms incoming WebSocket message limit in Kb. "
|
348
347
|
"Default: 250Kb",
|
349
|
-
FIO_CLI_TYPE_INT, "\n\x1B[
|
348
|
+
FIO_CLI_TYPE_INT, "\n\x1B[4mConnecting Iodine to Redis:\x1B[0m",
|
350
349
|
FIO_CLI_TYPE_PRINT,
|
351
350
|
"-redis -r an optional Redis URL server address. Default: none.",
|
352
351
|
"-redis-ping -rp websocket ping interval (0..255). Default: 5 minutes",
|
353
|
-
FIO_CLI_TYPE_INT, "\n\x1B[
|
352
|
+
FIO_CLI_TYPE_INT, "\n\x1B[4mMisc:\x1B[0m", FIO_CLI_TYPE_PRINT,
|
354
353
|
"-warmup warm up the application. CAREFUL! iodine might fork.",
|
355
354
|
FIO_CLI_TYPE_BOOL,
|
356
355
|
"-verbosity -V 0..5 server verbosity level. Default: 4",
|
@@ -250,7 +250,11 @@ static VALUE iodine_connection_pending(VALUE self) {
|
|
250
250
|
}
|
251
251
|
|
252
252
|
// clang-format off
|
253
|
-
/**
|
253
|
+
/**
|
254
|
+
* Returns the connection's protocol Symbol (`:sse`, `:websocket` or `:raw`).
|
255
|
+
*
|
256
|
+
* @Note For compatibility reasons (with ther `rack.upgrade` servers), it might be more prudent to use the data in the {#env} (`env['rack.upgrade?']`). However, this method is provided both as a faster alternative and for those cases where Raw / Custom (TCP/IP) data stream is a valid option.
|
257
|
+
*/
|
254
258
|
static VALUE iodine_connection_protocol_name(VALUE self) {
|
255
259
|
// clang-format on
|
256
260
|
iodine_connection_data_s *c = iodine_connection_validate_data(self);
|
@@ -334,14 +338,23 @@ static void iodine_on_pubsub(fio_msg_s *msg) {
|
|
334
338
|
iodine_connection_data_s *data = msg->udata1;
|
335
339
|
VALUE block = (VALUE)msg->udata2;
|
336
340
|
switch (block) {
|
337
|
-
case Qnil:
|
338
|
-
case Qtrue: {
|
341
|
+
case Qnil: /* fallthrough */
|
342
|
+
case Qtrue: { /* Qtrue == binary WebSocket */
|
339
343
|
if (data->info.handler == Qnil || data->info.uuid == -1 ||
|
340
344
|
fio_is_closed(data->info.uuid))
|
341
345
|
return;
|
342
346
|
switch (data->info.type) {
|
343
347
|
case IODINE_CONNECTION_WEBSOCKET: {
|
344
|
-
|
348
|
+
FIOBJ s = (FIOBJ)fio_message_metadata(
|
349
|
+
msg, (block == Qnil ? WEBSOCKET_OPTIMIZE_PUBSUB
|
350
|
+
: WEBSOCKET_OPTIMIZE_PUBSUB_BINARY));
|
351
|
+
if (s) {
|
352
|
+
// fwrite(".", 1, 1, stderr);
|
353
|
+
fiobj_send_free(data->info.uuid, fiobj_dup(s));
|
354
|
+
} else {
|
355
|
+
fwrite("-", 1, 1, stderr);
|
356
|
+
websocket_write(data->info.arg, msg->msg, (block == Qnil));
|
357
|
+
}
|
345
358
|
return;
|
346
359
|
}
|
347
360
|
case IODINE_CONNECTION_SSE:
|
@@ -353,7 +366,20 @@ static void iodine_on_pubsub(fio_msg_s *msg) {
|
|
353
366
|
}
|
354
367
|
}
|
355
368
|
default:
|
356
|
-
|
369
|
+
if (data->info.uuid != -1) {
|
370
|
+
fio_protocol_s *pr =
|
371
|
+
fio_protocol_try_lock(data->info.uuid, FIO_PR_LOCK_TASK);
|
372
|
+
if (!pr) {
|
373
|
+
// perror("Connection lock failed");
|
374
|
+
if (errno != EBADF)
|
375
|
+
fio_message_defer(msg);
|
376
|
+
break;
|
377
|
+
}
|
378
|
+
IodineCaller.enterGVL(iodine_on_pubsub_call_block, msg);
|
379
|
+
fio_protocol_unlock(pr, FIO_PR_LOCK_TASK);
|
380
|
+
} else {
|
381
|
+
IodineCaller.enterGVL(iodine_on_pubsub_call_block, msg);
|
382
|
+
}
|
357
383
|
break;
|
358
384
|
}
|
359
385
|
}
|
@@ -364,7 +390,14 @@ static void iodine_on_unsubscribe(void *udata1, void *udata2) {
|
|
364
390
|
VALUE block = (VALUE)udata2;
|
365
391
|
switch (block) {
|
366
392
|
case Qnil:
|
393
|
+
if (data && data->info.type == IODINE_CONNECTION_WEBSOCKET) {
|
394
|
+
websocket_optimize4broadcasts(WEBSOCKET_OPTIMIZE_PUBSUB, 0);
|
395
|
+
}
|
396
|
+
break;
|
367
397
|
case Qtrue:
|
398
|
+
if (data && data->info.type == IODINE_CONNECTION_WEBSOCKET) {
|
399
|
+
websocket_optimize4broadcasts(WEBSOCKET_OPTIMIZE_PUBSUB_BINARY, 0);
|
400
|
+
}
|
368
401
|
break;
|
369
402
|
default:
|
370
403
|
IodineStore.remove(block);
|
@@ -503,8 +536,15 @@ static VALUE iodine_pubsub_subscribe(int argc, VALUE *argv, VALUE self) {
|
|
503
536
|
}
|
504
537
|
return Qnil; /* cannot subscribe a closed / invalid connection. */
|
505
538
|
}
|
506
|
-
if (args.block == Qnil
|
507
|
-
|
539
|
+
if (args.block == Qnil) {
|
540
|
+
if (c->info.type == IODINE_CONNECTION_WEBSOCKET)
|
541
|
+
websocket_optimize4broadcasts((args.binary
|
542
|
+
? WEBSOCKET_OPTIMIZE_PUBSUB_BINARY
|
543
|
+
: WEBSOCKET_OPTIMIZE_PUBSUB),
|
544
|
+
1);
|
545
|
+
if (args.binary) {
|
546
|
+
args.block = Qtrue;
|
547
|
+
}
|
508
548
|
}
|
509
549
|
fio_atomic_add(&c->ref, 1);
|
510
550
|
}
|
@@ -719,11 +759,11 @@ void iodine_connection_fire_event(VALUE connection,
|
|
719
759
|
IodineCaller.call2(data->info.handler, on_close_id, 1, args);
|
720
760
|
}
|
721
761
|
fio_lock(&data->lock);
|
762
|
+
iodine_sub_clear_all(&data->subscriptions);
|
722
763
|
data->info.handler = Qnil;
|
723
764
|
data->info.env = Qnil;
|
724
765
|
data->info.uuid = -1;
|
725
766
|
data->info.arg = NULL;
|
726
|
-
iodine_sub_clear_all(&data->subscriptions);
|
727
767
|
fio_unlock(&data->lock);
|
728
768
|
IodineStore.remove(connection);
|
729
769
|
break;
|
data/ext/iodine/iodine_defer.c
CHANGED
@@ -35,7 +35,7 @@ typedef struct {
|
|
35
35
|
static void *iodine_io_thread(void *arg) {
|
36
36
|
(void)arg;
|
37
37
|
while (sock_io_thread_flag) {
|
38
|
-
if (fio_flush_all()
|
38
|
+
if (fio_flush_all())
|
39
39
|
fio_throttle_thread(500000UL);
|
40
40
|
else
|
41
41
|
fio_throttle_thread(150000000UL);
|
@@ -101,11 +101,11 @@ static void *create_ruby_thread_gvl(void *args) {
|
|
101
101
|
}
|
102
102
|
|
103
103
|
static void *fork_using_ruby(void *ignr) {
|
104
|
-
// stop IO thread
|
104
|
+
// stop IO thread, if running (shouldn't occur)
|
105
105
|
if (sock_io_pthread) {
|
106
106
|
iodine_join_io_thread();
|
107
107
|
}
|
108
|
-
// fork
|
108
|
+
// fork using Ruby
|
109
109
|
const VALUE ProcessClass = rb_const_get(rb_cObject, rb_intern2("Process", 7));
|
110
110
|
const VALUE rb_pid = IodineCaller.call(ProcessClass, rb_intern2("fork", 4));
|
111
111
|
intptr_t pid = 0;
|
@@ -114,7 +114,7 @@ static void *fork_using_ruby(void *ignr) {
|
|
114
114
|
} else {
|
115
115
|
pid = 0;
|
116
116
|
}
|
117
|
-
// manage post forking state
|
117
|
+
// manage post forking state for Iodine
|
118
118
|
IodineCaller.set_GVL(1); /* enforce GVL state in thread storage */
|
119
119
|
if (!pid) {
|
120
120
|
IodineStore.after_fork();
|
@@ -376,7 +376,6 @@ static VALUE iodine_on_state(VALUE self, VALUE event) {
|
|
376
376
|
/* Performs any cleanup before worker dies */
|
377
377
|
static void iodine_defer_on_finish(void *ignr) {
|
378
378
|
(void)ignr;
|
379
|
-
|
380
379
|
iodine_join_io_thread();
|
381
380
|
}
|
382
381
|
|
@@ -406,7 +405,8 @@ void iodine_defer_initialize(void) {
|
|
406
405
|
STATE_START_SHUTDOWN = rb_intern("start_shutdown");
|
407
406
|
STATE_ON_FINISH = rb_intern("on_finish");
|
408
407
|
|
408
|
+
/* start the IO thread is workrs (only starts in root if root is worker) */
|
409
|
+
fio_state_callback_add(FIO_CALL_ON_START, iodine_start_io_thread, NULL);
|
410
|
+
/* stop the IO thread before exit */
|
409
411
|
fio_state_callback_add(FIO_CALL_ON_FINISH, iodine_defer_on_finish, NULL);
|
410
|
-
fio_state_callback_add(FIO_CALL_PRE_START, iodine_start_io_thread, NULL);
|
411
|
-
fio_state_callback_add(FIO_CALL_AFTER_FORK, iodine_start_io_thread, NULL);
|
412
412
|
}
|