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/http1.h
CHANGED
@@ -5,7 +5,7 @@ License: MIT
|
|
5
5
|
#ifndef H_HTTP1_H
|
6
6
|
#define H_HTTP1_H
|
7
7
|
|
8
|
-
#include
|
8
|
+
#include <http.h>
|
9
9
|
|
10
10
|
#ifndef HTTP1_READ_BUFFER
|
11
11
|
/**
|
@@ -17,13 +17,13 @@ License: MIT
|
|
17
17
|
|
18
18
|
/** Creates an HTTP1 protocol object and handles any unread data in the buffer
|
19
19
|
* (if any). */
|
20
|
-
|
21
|
-
|
20
|
+
fio_protocol_s *http1_new(uintptr_t uuid, http_settings_s *settings,
|
21
|
+
void *unread_data, size_t unread_length);
|
22
22
|
|
23
23
|
/** Manually destroys the HTTP1 protocol object. */
|
24
|
-
void http1_destroy(
|
24
|
+
void http1_destroy(fio_protocol_s *);
|
25
25
|
|
26
26
|
/** returns the HTTP/1.1 protocol's VTable. */
|
27
|
-
void *
|
27
|
+
void *http1_vtable(void);
|
28
28
|
|
29
29
|
#endif
|
data/ext/iodine/http1_parser.c
CHANGED
@@ -8,7 +8,8 @@ Feel free to copy, use and enjoy according to the license provided.
|
|
8
8
|
#define __GNU_SOURCE
|
9
9
|
#endif
|
10
10
|
|
11
|
-
#include
|
11
|
+
#include <http1_parser.h>
|
12
|
+
|
12
13
|
#include <ctype.h>
|
13
14
|
#include <stdio.h>
|
14
15
|
#include <string.h>
|
@@ -357,7 +358,7 @@ inline static int consume_body(struct http1_fio_parser_args_s *args,
|
|
357
358
|
/* *****************************************************************************
|
358
359
|
HTTP/1.1 parsre function
|
359
360
|
***************************************************************************** */
|
360
|
-
#
|
361
|
+
#if DEBUG
|
361
362
|
#include <assert.h>
|
362
363
|
#else
|
363
364
|
#define DEBUG 0
|
data/ext/iodine/http1_parser.h
CHANGED
@@ -57,7 +57,7 @@ typedef struct http1_parser_s {
|
|
57
57
|
/**
|
58
58
|
* Available options for the parsing function.
|
59
59
|
*
|
60
|
-
* Callbacks should return 0 unless an error
|
60
|
+
* Callbacks should return 0 unless an error occurred.
|
61
61
|
*/
|
62
62
|
struct http1_fio_parser_args_s {
|
63
63
|
/** REQUIRED: the parser object that manages the parser's state. */
|
@@ -90,7 +90,7 @@ struct http1_fio_parser_args_s {
|
|
90
90
|
/** called when a body chunk is parsed. */
|
91
91
|
int (*const on_body_chunk)(http1_parser_s *parser, char *data,
|
92
92
|
size_t data_len);
|
93
|
-
/** called when a protocol error
|
93
|
+
/** called when a protocol error occurred. */
|
94
94
|
int (*const on_error)(http1_parser_s *parser);
|
95
95
|
};
|
96
96
|
|
data/ext/iodine/http_internal.c
CHANGED
@@ -4,11 +4,9 @@ License: MIT
|
|
4
4
|
|
5
5
|
Feel free to copy, use and enjoy according to the license provided.
|
6
6
|
*/
|
7
|
-
#include
|
7
|
+
#include <http_internal.h>
|
8
8
|
|
9
|
-
#include
|
10
|
-
|
11
|
-
#include "http1.h"
|
9
|
+
#include <http1.h>
|
12
10
|
|
13
11
|
/* *****************************************************************************
|
14
12
|
Internal Request / Response Handlers
|
@@ -45,7 +43,7 @@ void http_on_request_handler______internal(http_s *h,
|
|
45
43
|
HTTP_HVALUE_SSE_MIME))
|
46
44
|
goto eventsource;
|
47
45
|
if (settings->public_folder) {
|
48
|
-
|
46
|
+
fio_str_info_s path_str = fiobj_obj2cstr(h->path);
|
49
47
|
if (!http_sendfile2(h, settings->public_folder,
|
50
48
|
settings->public_folder_length, path_str.data,
|
51
49
|
path_str.len)) {
|
@@ -58,7 +56,7 @@ void http_on_request_handler______internal(http_s *h,
|
|
58
56
|
upgrade:
|
59
57
|
if (1) {
|
60
58
|
fiobj_dup(t); /* allow upgrade name access after http_finish */
|
61
|
-
|
59
|
+
fio_str_info_s val = fiobj_obj2cstr(t);
|
62
60
|
if (val.data[0] == 'h' && val.data[1] == '2') {
|
63
61
|
http_send_error(h, 400);
|
64
62
|
} else {
|
@@ -82,7 +80,7 @@ void http_on_response_handler______internal(http_s *h,
|
|
82
80
|
settings->on_response(h);
|
83
81
|
return;
|
84
82
|
} else {
|
85
|
-
|
83
|
+
fio_str_info_s val = fiobj_obj2cstr(t);
|
86
84
|
settings->on_upgrade(h, val.data, val.len);
|
87
85
|
}
|
88
86
|
}
|
@@ -94,12 +92,12 @@ Internal helpers
|
|
94
92
|
int http_send_error2(size_t error, intptr_t uuid, http_settings_s *settings) {
|
95
93
|
if (!uuid || !settings || !error)
|
96
94
|
return -1;
|
97
|
-
|
95
|
+
fio_protocol_s *pr = http1_new(uuid, settings, NULL, 0);
|
98
96
|
http_s *r = fio_malloc(sizeof(*r));
|
99
97
|
HTTP_ASSERT(pr, "Couldn't allocate response object for error report.")
|
100
|
-
http_s_new(r, (
|
98
|
+
http_s_new(r, (http_fio_protocol_s *)pr, http1_vtable());
|
101
99
|
int ret = http_send_error(r, error);
|
102
|
-
|
100
|
+
fio_close(uuid);
|
103
101
|
return ret;
|
104
102
|
}
|
105
103
|
|
@@ -138,7 +136,8 @@ FIOBJ HTTP_HVALUE_WS_UPGRADE;
|
|
138
136
|
FIOBJ HTTP_HVALUE_WS_VERSION;
|
139
137
|
FIOBJ HTTP_HVALUE_SSE_MIME;
|
140
138
|
|
141
|
-
void http_lib_cleanup(void) {
|
139
|
+
static void http_lib_cleanup(void *ignr) {
|
140
|
+
(void)ignr;
|
142
141
|
http_mimetype_clear();
|
143
142
|
#define HTTPLIB_RESET(x) \
|
144
143
|
fiobj_free(x); \
|
@@ -180,6 +179,7 @@ void http_lib_cleanup(void) {
|
|
180
179
|
void http_lib_init(void) {
|
181
180
|
if (HTTP_HEADER_ACCEPT_RANGES)
|
182
181
|
return;
|
182
|
+
fio_state_callback_add(FIO_CALL_AT_EXIT, http_lib_cleanup, NULL);
|
183
183
|
HTTP_HEADER_ACCEPT = fiobj_str_new("accept", 6);
|
184
184
|
HTTP_HEADER_ACCEPT_RANGES = fiobj_str_new("accept-ranges", 13);
|
185
185
|
HTTP_HEADER_CACHE_CONTROL = fiobj_str_new("cache-control", 13);
|
@@ -244,7 +244,7 @@ void http_lib_init(void) {
|
|
244
244
|
|
245
245
|
#define REGISTER_MIME(ext, type) \
|
246
246
|
http_mimetype_register(ext, sizeof(ext) - 1, \
|
247
|
-
|
247
|
+
fiobj_str_new(type, sizeof(type) - 1))
|
248
248
|
|
249
249
|
REGISTER_MIME("123", "application/vnd.lotus-1-2-3");
|
250
250
|
REGISTER_MIME("3dml", "text/vnd.in3d.3dml");
|
@@ -671,6 +671,7 @@ void http_lib_init(void) {
|
|
671
671
|
REGISTER_MIME("maker", "application/vnd.framemaker");
|
672
672
|
REGISTER_MIME("man", "text/troff");
|
673
673
|
REGISTER_MIME("mar", "application/octet-stream");
|
674
|
+
REGISTER_MIME("markdown", "text/markdown");
|
674
675
|
REGISTER_MIME("mathml", "application/mathml+xml");
|
675
676
|
REGISTER_MIME("mb", "application/mathematica");
|
676
677
|
REGISTER_MIME("mbk", "application/vnd.mobius.mbk");
|
@@ -678,6 +679,7 @@ void http_lib_init(void) {
|
|
678
679
|
REGISTER_MIME("mc1", "application/vnd.medcalcdata");
|
679
680
|
REGISTER_MIME("mcd", "application/vnd.mcd");
|
680
681
|
REGISTER_MIME("mcurl", "text/vnd.curl.mcurl");
|
682
|
+
REGISTER_MIME("md", "text/markdown");
|
681
683
|
REGISTER_MIME("mdb", "application/x-msaccess");
|
682
684
|
REGISTER_MIME("mdi", "image/vnd.ms-modi");
|
683
685
|
REGISTER_MIME("me", "text/troff");
|
data/ext/iodine/http_internal.h
CHANGED
@@ -7,22 +7,25 @@ Feel free to copy, use and enjoy according to the license provided.
|
|
7
7
|
#ifndef H_HTTP_INTERNAL_H
|
8
8
|
#define H_HTTP_INTERNAL_H
|
9
9
|
|
10
|
-
#
|
10
|
+
#define FIO_INCLUDE_LINKED_LIST
|
11
|
+
#include <fio.h>
|
11
12
|
|
12
|
-
#include
|
13
|
-
#include "http.h"
|
14
|
-
#include "pubsub.h"
|
13
|
+
#include <http.h>
|
15
14
|
|
16
|
-
#include
|
15
|
+
#include <fiobj4sock.h>
|
17
16
|
|
18
17
|
#include <arpa/inet.h>
|
19
18
|
#include <errno.h>
|
20
19
|
|
20
|
+
/* *****************************************************************************
|
21
|
+
Library initialization
|
22
|
+
***************************************************************************** */
|
23
|
+
void http_lib_init(void);
|
21
24
|
/* *****************************************************************************
|
22
25
|
Types
|
23
26
|
***************************************************************************** */
|
24
27
|
|
25
|
-
typedef struct
|
28
|
+
typedef struct http_fio_protocol_s http_fio_protocol_s;
|
26
29
|
typedef struct http_vtable_s http_vtable_s;
|
27
30
|
|
28
31
|
struct http_vtable_s {
|
@@ -39,16 +42,16 @@ struct http_vtable_s {
|
|
39
42
|
int (*const http_push_data)(http_s *h, void *data, uintptr_t length,
|
40
43
|
FIOBJ mime_type);
|
41
44
|
/** Upgrades a connection to Websockets. */
|
42
|
-
int (*const http2websocket)(websocket_settings_s *arg);
|
45
|
+
int (*const http2websocket)(http_s *h, websocket_settings_s *arg);
|
43
46
|
/** Push for files. */
|
44
47
|
int (*const http_push_file)(http_s *h, FIOBJ filename, FIOBJ mime_type);
|
45
48
|
/** Pauses the request / response handling. */
|
46
|
-
void (*http_on_pause)(http_s *,
|
49
|
+
void (*http_on_pause)(http_s *, http_fio_protocol_s *);
|
47
50
|
|
48
51
|
/** Resumes a request / response handling. */
|
49
|
-
void (*http_on_resume)(http_s *,
|
52
|
+
void (*http_on_resume)(http_s *, http_fio_protocol_s *);
|
50
53
|
/** hijacks the socket aaway from the protocol. */
|
51
|
-
intptr_t (*http_hijack)(http_s *h,
|
54
|
+
intptr_t (*http_hijack)(http_s *h, fio_str_info_s *leftover);
|
52
55
|
|
53
56
|
/** Upgrades an HTTP connection to an EventSource (SSE) connection. */
|
54
57
|
int (*http_upgrade2sse)(http_s *h, http_sse_s *sse);
|
@@ -58,13 +61,13 @@ struct http_vtable_s {
|
|
58
61
|
int (*http_sse_close)(http_sse_s *sse);
|
59
62
|
};
|
60
63
|
|
61
|
-
struct
|
62
|
-
|
64
|
+
struct http_fio_protocol_s {
|
65
|
+
fio_protocol_s protocol; /* facil.io protocol */
|
63
66
|
intptr_t uuid; /* socket uuid */
|
64
67
|
http_settings_s *settings; /* pointer to HTTP settings */
|
65
68
|
};
|
66
69
|
|
67
|
-
#define http2protocol(h) ((
|
70
|
+
#define http2protocol(h) ((http_fio_protocol_s *)h->private_data.flag)
|
68
71
|
|
69
72
|
/* *****************************************************************************
|
70
73
|
Constants that shouldn't be accessed by the users (`fiobj_dup` required).
|
@@ -90,7 +93,7 @@ extern FIOBJ HTTP_HVALUE_WS_VERSION;
|
|
90
93
|
HTTP request/response object management
|
91
94
|
***************************************************************************** */
|
92
95
|
|
93
|
-
static inline void http_s_new(http_s *h,
|
96
|
+
static inline void http_s_new(http_s *h, http_fio_protocol_s *owner,
|
94
97
|
http_vtable_s *vtbl) {
|
95
98
|
*h = (http_s){
|
96
99
|
.private_data =
|
@@ -100,7 +103,7 @@ static inline void http_s_new(http_s *h, http_protocol_s *owner,
|
|
100
103
|
.out_headers = fiobj_hash_new(),
|
101
104
|
},
|
102
105
|
.headers = fiobj_hash_new(),
|
103
|
-
.received_at =
|
106
|
+
.received_at = fio_last_tick(),
|
104
107
|
.status = 200,
|
105
108
|
};
|
106
109
|
}
|
@@ -128,7 +131,8 @@ static inline void http_s_destroy(http_s *h, uint8_t log) {
|
|
128
131
|
|
129
132
|
static inline void http_s_clear(http_s *h, uint8_t log) {
|
130
133
|
http_s_destroy(h, log);
|
131
|
-
http_s_new(h, (
|
134
|
+
http_s_new(h, (http_fio_protocol_s *)h->private_data.flag,
|
135
|
+
h->private_data.vtbl);
|
132
136
|
}
|
133
137
|
|
134
138
|
/** tests handle validity */
|
@@ -157,7 +161,7 @@ typedef struct http_sse_internal_s {
|
|
157
161
|
http_vtable_s *vtable; /* the protocol's vtable */
|
158
162
|
uintptr_t id; /* the SSE identifier */
|
159
163
|
fio_ls_s subscriptions; /* Subscription List */
|
160
|
-
|
164
|
+
fio_lock_i lock; /* Subscription List lock */
|
161
165
|
size_t ref; /* reference count */
|
162
166
|
} http_sse_internal_s;
|
163
167
|
|
@@ -173,7 +177,7 @@ static inline void http_sse_init(http_sse_internal_s *sse, intptr_t uuid,
|
|
173
177
|
}
|
174
178
|
|
175
179
|
static inline void http_sse_try_free(http_sse_internal_s *sse) {
|
176
|
-
if (
|
180
|
+
if (fio_atomic_sub(&sse->ref, 1))
|
177
181
|
return;
|
178
182
|
free(sse);
|
179
183
|
}
|
@@ -181,8 +185,10 @@ static inline void http_sse_try_free(http_sse_internal_s *sse) {
|
|
181
185
|
static inline void http_sse_destroy(http_sse_internal_s *sse) {
|
182
186
|
while (fio_ls_any(&sse->subscriptions)) {
|
183
187
|
void *sub = fio_ls_pop(&sse->subscriptions);
|
184
|
-
|
188
|
+
fio_unsubscribe(sub);
|
185
189
|
}
|
190
|
+
if (sse->sse.on_close)
|
191
|
+
sse->sse.on_close(&sse->sse);
|
186
192
|
sse->uuid = -1;
|
187
193
|
http_sse_try_free(sse);
|
188
194
|
}
|
data/ext/iodine/iodine.c
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
#include <ruby/version.h>
|
4
4
|
|
5
|
-
#
|
5
|
+
#define FIO_INCLUDE_LINKED_LIST
|
6
|
+
#include "fio.h"
|
6
7
|
/* *****************************************************************************
|
7
8
|
OS specific patches
|
8
9
|
***************************************************************************** */
|
@@ -31,10 +32,8 @@ static ID call_id;
|
|
31
32
|
/* *****************************************************************************
|
32
33
|
Idling
|
33
34
|
***************************************************************************** */
|
34
|
-
#include "fio_llist.h"
|
35
|
-
#include "spnlock.inc"
|
36
35
|
|
37
|
-
static
|
36
|
+
static fio_lock_i iodine_on_idle_lock = FIO_LOCK_INIT;
|
38
37
|
static fio_ls_s iodine_on_idle_list = FIO_LS_INIT(iodine_on_idle_list);
|
39
38
|
|
40
39
|
static void iodine_perform_deferred(void *block, void *ignr) {
|
@@ -57,21 +56,22 @@ VALUE iodine_sched_on_idle(VALUE self) {
|
|
57
56
|
rb_need_block();
|
58
57
|
VALUE block = rb_block_proc();
|
59
58
|
IodineStore.add(block);
|
60
|
-
|
59
|
+
fio_lock(&iodine_on_idle_lock);
|
61
60
|
fio_ls_push(&iodine_on_idle_list, (void *)block);
|
62
|
-
|
61
|
+
fio_unlock(&iodine_on_idle_lock);
|
63
62
|
return block;
|
64
63
|
(void)self;
|
65
64
|
}
|
66
65
|
|
67
|
-
static void iodine_on_idle(void) {
|
68
|
-
|
66
|
+
static void iodine_on_idle(void *arg) {
|
67
|
+
(void)arg;
|
68
|
+
fio_lock(&iodine_on_idle_lock);
|
69
69
|
while (fio_ls_any(&iodine_on_idle_list)) {
|
70
70
|
VALUE block = (VALUE)fio_ls_shift(&iodine_on_idle_list);
|
71
|
-
|
71
|
+
fio_defer(iodine_perform_deferred, (void *)block, NULL);
|
72
72
|
IodineStore.remove(block);
|
73
73
|
}
|
74
|
-
|
74
|
+
fio_unlock(&iodine_on_idle_lock);
|
75
75
|
}
|
76
76
|
|
77
77
|
/* *****************************************************************************
|
@@ -85,8 +85,7 @@ typedef struct {
|
|
85
85
|
|
86
86
|
static void *iodine_run_outside_GVL(void *params_) {
|
87
87
|
iodine_start_params_s *params = params_;
|
88
|
-
|
89
|
-
.on_idle = iodine_on_idle, .on_finish = iodine_defer_on_finish);
|
88
|
+
fio_start(.threads = params->threads, .workers = params->workers);
|
90
89
|
return NULL;
|
91
90
|
}
|
92
91
|
|
@@ -166,14 +165,14 @@ static VALUE iodine_workers_set(VALUE self, VALUE val) {
|
|
166
165
|
static void iodine_print_startup_message(iodine_start_params_s params) {
|
167
166
|
VALUE iodine_version = rb_const_get(IodineModule, rb_intern("VERSION"));
|
168
167
|
VALUE ruby_version = rb_const_get(IodineModule, rb_intern("RUBY_VERSION"));
|
169
|
-
|
168
|
+
fio_expected_concurrency(¶ms.threads, ¶ms.workers);
|
170
169
|
fprintf(stderr,
|
171
170
|
"\nStarting up Iodine:\n"
|
172
|
-
" * Ruby
|
171
|
+
" * Iodine %s\n * Ruby %s\n * facil.io " FIO_VERSION_STRING " (%s)\n"
|
173
172
|
" * %d Workers X %d Threads per worker.\n"
|
174
173
|
"\n",
|
175
|
-
StringValueCStr(
|
176
|
-
params.workers, params.threads);
|
174
|
+
StringValueCStr(iodine_version), StringValueCStr(ruby_version),
|
175
|
+
fio_engine(), params.workers, params.threads);
|
177
176
|
(void)params;
|
178
177
|
}
|
179
178
|
|
@@ -193,19 +192,32 @@ static void iodine_print_startup_message(iodine_start_params_s params) {
|
|
193
192
|
*
|
194
193
|
*/
|
195
194
|
static VALUE iodine_start(VALUE self) {
|
196
|
-
if (
|
195
|
+
if (fio_is_running()) {
|
197
196
|
rb_raise(rb_eRuntimeError, "Iodine already running!");
|
198
197
|
}
|
198
|
+
IodineCaller.set_GVL(1);
|
199
199
|
VALUE threads_rb = iodine_threads_get(self);
|
200
200
|
VALUE workers_rb = iodine_workers_get(self);
|
201
201
|
iodine_start_params_s params = {
|
202
|
-
.threads = NUM2SHORT(threads_rb),
|
202
|
+
.threads = NUM2SHORT(threads_rb),
|
203
|
+
.workers = NUM2SHORT(workers_rb),
|
203
204
|
};
|
204
205
|
iodine_print_startup_message(params);
|
205
206
|
IodineCaller.leaveGVL(iodine_run_outside_GVL, ¶ms);
|
206
207
|
return self;
|
207
208
|
}
|
208
209
|
|
210
|
+
/**
|
211
|
+
* This will stop the iodine server, shutting it down.
|
212
|
+
*
|
213
|
+
* If called within a worker process (rather than the root/master process), this
|
214
|
+
* will cause a hot-restart for the worker.
|
215
|
+
*/
|
216
|
+
static VALUE iodine_stop(VALUE self) {
|
217
|
+
fio_stop();
|
218
|
+
return self;
|
219
|
+
}
|
220
|
+
|
209
221
|
/* *****************************************************************************
|
210
222
|
Ruby loads the library and invokes the Init_<lib_name> function...
|
211
223
|
|
@@ -230,6 +242,7 @@ void Init_iodine(void) {
|
|
230
242
|
rb_define_module_function(IodineModule, "workers", iodine_workers_get, 0);
|
231
243
|
rb_define_module_function(IodineModule, "workers=", iodine_workers_set, 1);
|
232
244
|
rb_define_module_function(IodineModule, "start", iodine_start, 0);
|
245
|
+
rb_define_module_function(IodineModule, "stop", iodine_stop, 0);
|
233
246
|
rb_define_module_function(IodineModule, "on_idle", iodine_sched_on_idle, 0);
|
234
247
|
|
235
248
|
// initialize Object storage for GC protection
|
@@ -250,10 +263,16 @@ void Init_iodine(void) {
|
|
250
263
|
// initialize JSON helpers
|
251
264
|
iodine_init_json();
|
252
265
|
|
266
|
+
// initialize Mustache engine
|
267
|
+
iodine_init_mustache();
|
268
|
+
|
253
269
|
// initialize Rack helpers and IO
|
254
270
|
iodine_init_helpers();
|
255
271
|
IodineRackIO.init();
|
256
272
|
|
257
273
|
// initialize Pub/Sub extension (for Engines)
|
258
274
|
iodine_pubsub_init();
|
275
|
+
|
276
|
+
// register idle and finish callbacks
|
277
|
+
fio_state_callback_add(FIO_CALL_ON_IDLE, iodine_on_idle, NULL);
|
259
278
|
}
|
data/ext/iodine/iodine.h
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
#include "iodine_helpers.h"
|
10
10
|
#include "iodine_http.h"
|
11
11
|
#include "iodine_json.h"
|
12
|
+
#include "iodine_mustache.h"
|
12
13
|
#include "iodine_pubsub.h"
|
13
14
|
#include "iodine_rack_io.h"
|
14
15
|
#include "iodine_store.h"
|
@@ -20,4 +21,7 @@ Constants
|
|
20
21
|
extern VALUE IodineModule;
|
21
22
|
extern VALUE IodineBaseModule;
|
22
23
|
|
24
|
+
#define IODINE_RSTRINFO(rstr) \
|
25
|
+
((fio_str_info_s){.len = RSTRING_LEN(rstr), .data = RSTRING_PTR(rstr)})
|
26
|
+
|
23
27
|
#endif
|
data/ext/iodine/iodine_caller.c
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#include "iodine_caller.h"
|
2
2
|
|
3
3
|
#include <ruby/thread.h>
|
4
|
+
#include <string.h>
|
4
5
|
|
5
6
|
static __thread volatile uint8_t iodine_GVL_state;
|
6
7
|
|
@@ -91,7 +92,10 @@ static void *iodine_leaveGVL(void *(*func)(void *), void *arg) {
|
|
91
92
|
/** Calls a Ruby method on a given object, protecting against exceptions. */
|
92
93
|
static VALUE iodine_call(VALUE obj, ID method) {
|
93
94
|
iodine_rb_task_s task = {
|
94
|
-
.obj = obj,
|
95
|
+
.obj = obj,
|
96
|
+
.argc = 0,
|
97
|
+
.argv = NULL,
|
98
|
+
.method = method,
|
95
99
|
};
|
96
100
|
void *rv = iodine_enterGVL(iodine_protect_ruby_call, &task);
|
97
101
|
return (VALUE)rv;
|
@@ -100,7 +104,10 @@ static VALUE iodine_call(VALUE obj, ID method) {
|
|
100
104
|
/** Calls a Ruby method on a given object, protecting against exceptions. */
|
101
105
|
static VALUE iodine_call2(VALUE obj, ID method, int argc, VALUE *argv) {
|
102
106
|
iodine_rb_task_s task = {
|
103
|
-
.obj = obj,
|
107
|
+
.obj = obj,
|
108
|
+
.argc = argc,
|
109
|
+
.argv = argv,
|
110
|
+
.method = method,
|
104
111
|
};
|
105
112
|
void *rv = iodine_enterGVL(iodine_protect_ruby_call, &task);
|
106
113
|
return (VALUE)rv;
|