iodine 0.7.59 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/.clang-format +15 -0
  3. data/.rspec +1 -0
  4. data/.yardopts +1 -3
  5. data/CHANGELOG.md +132 -12
  6. data/Gemfile +5 -7
  7. data/LICENSE.txt +1 -1
  8. data/README.md +147 -671
  9. data/Rakefile +9 -16
  10. data/examples/chatroom.nru +9 -0
  11. data/examples/client +74 -0
  12. data/examples/config-hello.nru +9 -0
  13. data/examples/config-hello.ru +11 -0
  14. data/examples/config-hijack.ru +13 -0
  15. data/examples/config-shootout.ru +43 -0
  16. data/examples/config.nru +120 -0
  17. data/examples/config.rb +37 -0
  18. data/examples/config.ru +42 -53
  19. data/examples/fake +24 -0
  20. data/examples/hello_neorack +137 -0
  21. data/examples/routes.nru +29 -0
  22. data/examples/routes.ru +42 -0
  23. data/exe/iodine +218 -258
  24. data/ext/iodine/extconf.rb +27 -100
  25. data/ext/iodine/fio-stl.h +128336 -0
  26. data/ext/iodine/fio-stl.md +26396 -0
  27. data/ext/iodine/iodine.c +213 -1393
  28. data/ext/iodine/iodine.h +250 -55
  29. data/ext/iodine/iodine_arg_helper.h +329 -0
  30. data/ext/iodine/iodine_caller.h +234 -25
  31. data/ext/iodine/iodine_cli.h +434 -0
  32. data/ext/iodine/iodine_compression.h +312 -0
  33. data/ext/iodine/iodine_connection.h +3484 -34
  34. data/ext/iodine/iodine_core.h +363 -0
  35. data/ext/iodine/iodine_crypto.h +1441 -0
  36. data/ext/iodine/iodine_defer.h +225 -4
  37. data/ext/iodine/iodine_json.h +738 -4
  38. data/ext/iodine/iodine_listener.h +263 -0
  39. data/ext/iodine/iodine_log.h +297 -0
  40. data/ext/iodine/iodine_minimap.h +543 -0
  41. data/ext/iodine/iodine_mustache.h +461 -4
  42. data/ext/iodine/iodine_pubsub_eng.h +729 -0
  43. data/ext/iodine/iodine_pubsub_history.h +547 -0
  44. data/ext/iodine/iodine_pubsub_msg.h +228 -0
  45. data/ext/iodine/iodine_redis.h +322 -0
  46. data/ext/iodine/iodine_store.h +418 -16
  47. data/ext/iodine/iodine_threads.h +279 -0
  48. data/ext/iodine/iodine_tls.h +515 -6
  49. data/ext/iodine/iodine_utils.h +923 -0
  50. data/iodine.gemspec +37 -42
  51. data/lib/iodine/benchmark.rb +1690 -0
  52. data/lib/iodine/documentation.rb +3085 -0
  53. data/lib/iodine/version.rb +17 -1
  54. data/lib/iodine.rb +54 -255
  55. data/logo.svg +36 -0
  56. data/mustache.md +55 -0
  57. data/sig/iodine.rbs +4 -0
  58. metadata +58 -184
  59. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -40
  60. data/.github/workflows/ruby.yml +0 -42
  61. data/.gitignore +0 -20
  62. data/LIMITS.md +0 -41
  63. data/SPEC-PubSub-Draft.md +0 -159
  64. data/SPEC-WebSocket-Draft.md +0 -239
  65. data/bin/console +0 -22
  66. data/bin/info.md +0 -353
  67. data/bin/mustache_bench.rb +0 -100
  68. data/bin/poc/Gemfile.lock +0 -23
  69. data/bin/poc/README.md +0 -37
  70. data/bin/poc/config.ru +0 -66
  71. data/bin/poc/gemfile +0 -1
  72. data/bin/poc/www/index.html +0 -57
  73. data/examples/async_task.ru +0 -92
  74. data/examples/bates/README.md +0 -3
  75. data/examples/bates/config.ru +0 -342
  76. data/examples/bates/david+bold.pdf +0 -0
  77. data/examples/bates/public/drop-pdf.png +0 -0
  78. data/examples/bates/public/index.html +0 -600
  79. data/examples/echo.ru +0 -59
  80. data/examples/etag.ru +0 -16
  81. data/examples/hello.ru +0 -29
  82. data/examples/pubsub_engine.ru +0 -81
  83. data/examples/rack3.ru +0 -12
  84. data/examples/redis.ru +0 -70
  85. data/examples/shootout.ru +0 -73
  86. data/examples/sub-protocols.ru +0 -90
  87. data/examples/tcp_client.rb +0 -66
  88. data/examples/x-sendfile.ru +0 -14
  89. data/ext/iodine/fio.c +0 -11995
  90. data/ext/iodine/fio.h +0 -6371
  91. data/ext/iodine/fio_cli.c +0 -431
  92. data/ext/iodine/fio_cli.h +0 -189
  93. data/ext/iodine/fio_json_parser.h +0 -688
  94. data/ext/iodine/fio_siphash.c +0 -157
  95. data/ext/iodine/fio_siphash.h +0 -37
  96. data/ext/iodine/fio_tls.h +0 -129
  97. data/ext/iodine/fio_tls_missing.c +0 -649
  98. data/ext/iodine/fio_tls_openssl.c +0 -1106
  99. data/ext/iodine/fio_tmpfile.h +0 -50
  100. data/ext/iodine/fiobj.h +0 -44
  101. data/ext/iodine/fiobj4fio.h +0 -21
  102. data/ext/iodine/fiobj_ary.c +0 -333
  103. data/ext/iodine/fiobj_ary.h +0 -139
  104. data/ext/iodine/fiobj_data.c +0 -1187
  105. data/ext/iodine/fiobj_data.h +0 -167
  106. data/ext/iodine/fiobj_hash.c +0 -409
  107. data/ext/iodine/fiobj_hash.h +0 -176
  108. data/ext/iodine/fiobj_json.c +0 -622
  109. data/ext/iodine/fiobj_json.h +0 -68
  110. data/ext/iodine/fiobj_mem.h +0 -71
  111. data/ext/iodine/fiobj_mustache.c +0 -317
  112. data/ext/iodine/fiobj_mustache.h +0 -62
  113. data/ext/iodine/fiobj_numbers.c +0 -344
  114. data/ext/iodine/fiobj_numbers.h +0 -127
  115. data/ext/iodine/fiobj_str.c +0 -433
  116. data/ext/iodine/fiobj_str.h +0 -172
  117. data/ext/iodine/fiobject.c +0 -620
  118. data/ext/iodine/fiobject.h +0 -655
  119. data/ext/iodine/hpack.h +0 -1923
  120. data/ext/iodine/http.c +0 -2743
  121. data/ext/iodine/http.h +0 -1002
  122. data/ext/iodine/http1.c +0 -910
  123. data/ext/iodine/http1.h +0 -29
  124. data/ext/iodine/http1_parser.h +0 -878
  125. data/ext/iodine/http_internal.c +0 -1279
  126. data/ext/iodine/http_internal.h +0 -237
  127. data/ext/iodine/http_mime_parser.h +0 -350
  128. data/ext/iodine/iodine_caller.c +0 -230
  129. data/ext/iodine/iodine_connection.c +0 -941
  130. data/ext/iodine/iodine_defer.c +0 -420
  131. data/ext/iodine/iodine_fiobj2rb.h +0 -120
  132. data/ext/iodine/iodine_helpers.c +0 -282
  133. data/ext/iodine/iodine_helpers.h +0 -12
  134. data/ext/iodine/iodine_http.c +0 -1181
  135. data/ext/iodine/iodine_http.h +0 -23
  136. data/ext/iodine/iodine_json.c +0 -302
  137. data/ext/iodine/iodine_mustache.c +0 -567
  138. data/ext/iodine/iodine_pubsub.c +0 -580
  139. data/ext/iodine/iodine_pubsub.h +0 -26
  140. data/ext/iodine/iodine_rack_io.c +0 -273
  141. data/ext/iodine/iodine_rack_io.h +0 -20
  142. data/ext/iodine/iodine_store.c +0 -146
  143. data/ext/iodine/iodine_tcp.c +0 -346
  144. data/ext/iodine/iodine_tcp.h +0 -13
  145. data/ext/iodine/iodine_tls.c +0 -261
  146. data/ext/iodine/mustache_parser.h +0 -1546
  147. data/ext/iodine/redis_engine.c +0 -957
  148. data/ext/iodine/redis_engine.h +0 -79
  149. data/ext/iodine/resp_parser.h +0 -317
  150. data/ext/iodine/websocket_parser.h +0 -506
  151. data/ext/iodine/websockets.c +0 -743
  152. data/ext/iodine/websockets.h +0 -185
  153. data/lib/iodine/connection.rb +0 -61
  154. data/lib/iodine/json.rb +0 -42
  155. data/lib/iodine/mustache.rb +0 -113
  156. data/lib/iodine/pubsub.rb +0 -55
  157. data/lib/iodine/rack_utils.rb +0 -43
  158. data/lib/iodine/tls.rb +0 -16
  159. data/lib/rack/handler/iodine.rb +0 -33
  160. data/logo.png +0 -0
@@ -1,420 +0,0 @@
1
- #include "iodine.h"
2
-
3
- #include <ruby/thread.h>
4
-
5
- #include <stdint.h>
6
- // clang-format on
7
-
8
- #define FIO_INCLUDE_LINKED_LIST
9
- #include "fio.h"
10
-
11
- #include <pthread.h>
12
-
13
- static ID STATE_PRE_START;
14
- static ID STATE_BEFORE_FORK;
15
- static ID STATE_AFTER_FORK;
16
- static ID STATE_ENTER_CHILD;
17
- static ID STATE_ENTER_MASTER;
18
- static ID STATE_ON_START;
19
- static ID STATE_ON_PARENT_CRUSH;
20
- static ID STATE_ON_CHILD_CRUSH;
21
- static ID STATE_START_SHUTDOWN;
22
- static ID STATE_ON_FINISH;
23
-
24
- /* *****************************************************************************
25
- IO flushing dedicated thread for protection against blocking code
26
- ***************************************************************************** */
27
-
28
- static fio_lock_i sock_io_thread_flag = 0;
29
- static pthread_t sock_io_pthread;
30
- typedef struct {
31
- size_t threads;
32
- size_t processes;
33
- } iodine_start_settings_s;
34
-
35
- static void *iodine_io_thread(void *arg) {
36
- (void)arg;
37
- while (sock_io_thread_flag) {
38
- if (fio_flush_all())
39
- fio_throttle_thread(500000UL);
40
- else
41
- fio_throttle_thread(150000000UL);
42
- }
43
- return NULL;
44
- }
45
- static void iodine_start_io_thread(void *a_) {
46
- if (!fio_trylock(&sock_io_thread_flag)) {
47
- if (pthread_create(&sock_io_pthread, NULL, iodine_io_thread, NULL)) {
48
- FIO_LOG_ERROR("Couldn't spawn IO thread.");
49
- };
50
- FIO_LOG_DEBUG("IO thread started.");
51
- }
52
- (void)a_;
53
- }
54
-
55
- static void iodine_join_io_thread(void) {
56
- if (fio_unlock(&sock_io_thread_flag) && sock_io_pthread) {
57
- pthread_join(sock_io_pthread, NULL);
58
- sock_io_pthread = (pthread_t)NULL;
59
- FIO_LOG_DEBUG("IO thread stopped and joined.");
60
- }
61
- }
62
-
63
- /* *****************************************************************************
64
- The Defer library overriding functions
65
- ***************************************************************************** */
66
-
67
- /* used to create Ruby threads and pass them the information they need */
68
- struct CreateThreadArgs {
69
- void *(*thread_func)(void *);
70
- void *arg;
71
- fio_lock_i lock;
72
- };
73
-
74
- /* used for GVL signalling */
75
- static void call_async_signal(void *pool) {
76
- fio_stop();
77
- (void)pool;
78
- }
79
-
80
- static void *defer_thread_start(void *args_) {
81
- struct CreateThreadArgs *args = args_;
82
- IodineCaller.set_GVL(0);
83
- args->thread_func(args->arg);
84
- return NULL;
85
- }
86
-
87
- /* the thread's GVL release */
88
- static VALUE defer_thread_inGVL(void *args_) {
89
- struct CreateThreadArgs *old_args = args_;
90
- struct CreateThreadArgs args = *old_args;
91
- IodineCaller.set_GVL(1);
92
- fio_unlock(&old_args->lock);
93
- rb_thread_call_without_gvl(defer_thread_start, &args,
94
- (void (*)(void *))call_async_signal, args.arg);
95
- return Qnil;
96
- }
97
-
98
- /* Within the GVL, creates a Ruby thread using an API call */
99
- static void *create_ruby_thread_gvl(void *args) {
100
- return (void *)IodineStore.add(rb_thread_create(defer_thread_inGVL, args));
101
- }
102
-
103
- static void *fork_using_ruby(void *ignr) {
104
- // stop IO thread, if running (shouldn't occur)
105
- if (sock_io_pthread) {
106
- iodine_join_io_thread();
107
- }
108
- // fork using Ruby
109
- const VALUE ProcessClass = rb_const_get(rb_cObject, rb_intern2("Process", 7));
110
- const VALUE rb_pid = IodineCaller.call(ProcessClass, rb_intern2("fork", 4));
111
- intptr_t pid = 0;
112
- if (rb_pid != Qnil) {
113
- pid = NUM2INT(rb_pid);
114
- } else {
115
- pid = 0;
116
- }
117
- // manage post forking state for Iodine
118
- IodineCaller.set_GVL(1); /* enforce GVL state in thread storage */
119
- if (!pid) {
120
- IodineStore.after_fork();
121
- }
122
- return (void *)pid;
123
- (void)ignr;
124
- }
125
-
126
- /**
127
- OVERRIDE THIS to replace the default pthread implementation.
128
- */
129
- void *fio_thread_new(void *(*thread_func)(void *), void *arg) {
130
- struct CreateThreadArgs data = (struct CreateThreadArgs){
131
- .thread_func = thread_func,
132
- .arg = arg,
133
- .lock = FIO_LOCK_INIT,
134
- };
135
- fio_lock(&data.lock);
136
- void *thr = IodineCaller.enterGVL(create_ruby_thread_gvl, &data);
137
- if (!thr || thr == (void *)Qnil || thr == (void *)Qfalse) {
138
- thr = NULL;
139
- } else {
140
- /* wait for thread to signal it's alive. */
141
- fio_lock(&data.lock);
142
- }
143
- return thr;
144
- }
145
-
146
- /**
147
- OVERRIDE THIS to replace the default pthread implementation.
148
- */
149
- int fio_thread_join(void *thr) {
150
- if (!thr || (VALUE)thr == Qfalse || (VALUE)thr == Qnil)
151
- return -1;
152
- IodineCaller.call((VALUE)thr, rb_intern("join"));
153
- IodineStore.remove((VALUE)thr);
154
- return 0;
155
- }
156
-
157
- // void defer_free_thread(void *thr) { (void)thr; }
158
- void fio_thread_free(void *thr) { IodineStore.remove((VALUE)thr); }
159
-
160
- /**
161
- OVERRIDE THIS to replace the default `fork` implementation or to inject hooks
162
- into the forking function.
163
-
164
- Behaves like the system's `fork`.
165
- */
166
- int fio_fork(void) {
167
- intptr_t pid = (intptr_t)IodineCaller.enterGVL(fork_using_ruby, NULL);
168
- return (int)pid;
169
- }
170
-
171
- /* *****************************************************************************
172
- Task performance
173
- ***************************************************************************** */
174
-
175
- static ID call_id;
176
-
177
- static void iodine_defer_performe_once(void *block, void *ignr) {
178
- IodineCaller.call((VALUE)block, call_id);
179
- IodineStore.remove((VALUE)block);
180
- (void)ignr;
181
- }
182
-
183
- static void iodine_defer_run_timer(void *block) {
184
- /* TODO, update return value to allow timer cancellation */
185
- IodineCaller.call((VALUE)block, call_id);
186
- }
187
-
188
- /* *****************************************************************************
189
- Defer API
190
- ***************************************************************************** */
191
-
192
- /**
193
- * Runs a block of code asyncronously (adds the code to the event queue).
194
- *
195
- * Always returns the block of code to executed (Proc object).
196
- *
197
- * Code will be executed only while Iodine is running (after {Iodine.start}).
198
- *
199
- * Code blocks that where scheduled to run before Iodine enters cluster mode
200
- * will run on all child processes.
201
- */
202
- static VALUE iodine_defer_run(VALUE self) {
203
- rb_need_block();
204
- VALUE block = IodineStore.add(rb_block_proc());
205
- fio_defer(iodine_defer_performe_once, (void *)block, NULL);
206
- return block;
207
- (void)self;
208
- }
209
-
210
- /**
211
- Runs the required block after the specified number of milliseconds have passed.
212
- Time is counted only once Iodine started running (using {Iodine.start}).
213
-
214
- Tasks scheduled before calling {Iodine.start} will run once for every process.
215
-
216
- Always returns a copy of the block object.
217
- */
218
- static VALUE iodine_defer_run_after(VALUE self, VALUE milliseconds) {
219
- (void)(self);
220
- if (milliseconds == Qnil) {
221
- return iodine_defer_run(self);
222
- }
223
- if (TYPE(milliseconds) != T_FIXNUM) {
224
- rb_raise(rb_eTypeError, "milliseconds must be a number");
225
- return Qnil;
226
- }
227
- size_t milli = FIX2UINT(milliseconds);
228
- if (milli == 0) {
229
- return iodine_defer_run(self);
230
- }
231
- // requires a block to be passed
232
- rb_need_block();
233
- VALUE block = rb_block_proc();
234
- if (block == Qnil)
235
- return Qfalse;
236
- IodineStore.add(block);
237
- if (fio_run_every(milli, 1, iodine_defer_run_timer, (void *)block,
238
- (void (*)(void *))IodineStore.remove) == -1) {
239
- perror("ERROR: Iodine couldn't initialize timer");
240
- return Qnil;
241
- }
242
- return block;
243
- }
244
-
245
- // clang-format off
246
- /**
247
- Runs the required block after the specified number of milliseconds have passed.
248
- Time is counted only once Iodine started running (using {Iodine.start}).
249
-
250
- Accepts:
251
-
252
- | | |
253
- |---|---|
254
- | `:milliseconds` | the number of milliseconds between event repetitions.|
255
- | `:repetitions` | the number of event repetitions. Defaults to 0 (never ending).|
256
- | `:block` | (required) a block is required, as otherwise there is nothing to|
257
- perform.
258
-
259
- The event will repeat itself until the number of repetitions had been delpeted.
260
-
261
- Always returns a copy of the block object.
262
- */
263
- static VALUE iodine_defer_run_every(int argc, VALUE *argv, VALUE self) {
264
- // clang-format on
265
- (void)(self);
266
- VALUE milliseconds, repetitions, block;
267
-
268
- rb_scan_args(argc, argv, "11&", &milliseconds, &repetitions, &block);
269
-
270
- if (TYPE(milliseconds) != T_FIXNUM) {
271
- rb_raise(rb_eTypeError, "milliseconds must be a number.");
272
- return Qnil;
273
- }
274
- if (repetitions != Qnil && TYPE(repetitions) != T_FIXNUM) {
275
- rb_raise(rb_eTypeError, "repetitions must be a number or `nil`.");
276
- return Qnil;
277
- }
278
-
279
- size_t milli = FIX2UINT(milliseconds);
280
- size_t repeat = (repetitions == Qnil) ? 0 : FIX2UINT(repetitions);
281
- // requires a block to be passed
282
- rb_need_block();
283
- IodineStore.add(block);
284
- if (fio_run_every(milli, repeat, iodine_defer_run_timer, (void *)block,
285
- (void (*)(void *))IodineStore.remove) == -1) {
286
- perror("ERROR: Iodine couldn't initialize timer");
287
- return Qnil;
288
- }
289
- return block;
290
- }
291
-
292
- /* *****************************************************************************
293
- Pre/Post `fork`
294
- ***************************************************************************** */
295
-
296
- /* performs a Ruby state callback without clearing the Ruby object's memory */
297
- static void iodine_perform_state_callback_persist(void *blk_) {
298
- VALUE blk = (VALUE)blk_;
299
- IodineCaller.call(blk, call_id);
300
- }
301
-
302
- // clang-format off
303
- /**
304
- Sets a block of code to run when Iodine's core state is updated.
305
-
306
- @param [Symbol] event the state event for which the block should run (see list).
307
- @since 0.7.9
308
-
309
- The state event Symbol can be any of the following:
310
-
311
- | | |
312
- |---|---|
313
- | `:pre_start` | the block will be called once before starting up the IO reactor. |
314
- | `:before_fork` | the block will be called before each time the IO reactor forks a new worker. |
315
- | `:after_fork` | the block will be called after each fork (both in parent and workers). |
316
- | `:enter_child` | the block will be called by a worker process right after forking. |
317
- | `:enter_master` | the block will be called by the master process after spawning a worker (after forking). |
318
- | `:on_start` | the block will be called every time a *worker* proceess starts. In single process mode, the master process is also a worker. |
319
- | `:on_parent_crush` | the block will be called by each worker the moment it detects the master process crashed. |
320
- | `:on_child_crush` | the block will be called by the parent (master) after a worker process crashed. |
321
- | `:start_shutdown` | the block will be called before starting the shutdown sequence. |
322
- | `:on_finish` | the block will be called just before finishing up (both on chlid and parent processes). |
323
-
324
- Code runs in both the parent and the child.
325
- */
326
- static VALUE iodine_on_state(VALUE self, VALUE event) {
327
- // clang-format on
328
- rb_need_block();
329
- Check_Type(event, T_SYMBOL);
330
- VALUE block = rb_block_proc();
331
- IodineStore.add(block);
332
- ID state = rb_sym2id(event);
333
-
334
- if (state == STATE_PRE_START) {
335
- fio_state_callback_add(FIO_CALL_PRE_START,
336
- iodine_perform_state_callback_persist,
337
- (void *)block);
338
- } else if (state == STATE_BEFORE_FORK) {
339
- fio_state_callback_add(FIO_CALL_BEFORE_FORK,
340
- iodine_perform_state_callback_persist,
341
- (void *)block);
342
- } else if (state == STATE_AFTER_FORK) {
343
- fio_state_callback_add(FIO_CALL_AFTER_FORK,
344
- iodine_perform_state_callback_persist,
345
- (void *)block);
346
- } else if (state == STATE_ENTER_CHILD) {
347
- fio_state_callback_add(FIO_CALL_IN_CHILD,
348
- iodine_perform_state_callback_persist,
349
- (void *)block);
350
- } else if (state == STATE_ENTER_MASTER) {
351
- fio_state_callback_add(FIO_CALL_IN_MASTER,
352
- iodine_perform_state_callback_persist,
353
- (void *)block);
354
- } else if (state == STATE_ON_START) {
355
- fio_state_callback_add(FIO_CALL_ON_START,
356
- iodine_perform_state_callback_persist,
357
- (void *)block);
358
- } else if (state == STATE_ON_PARENT_CRUSH) {
359
- fio_state_callback_add(FIO_CALL_ON_PARENT_CRUSH,
360
- iodine_perform_state_callback_persist,
361
- (void *)block);
362
- } else if (state == STATE_ON_CHILD_CRUSH) {
363
- fio_state_callback_add(FIO_CALL_ON_CHILD_CRUSH,
364
- iodine_perform_state_callback_persist,
365
- (void *)block);
366
- } else if (state == STATE_START_SHUTDOWN) {
367
- fio_state_callback_add(FIO_CALL_ON_SHUTDOWN,
368
- iodine_perform_state_callback_persist,
369
- (void *)block);
370
- } else if (state == STATE_ON_FINISH) {
371
- fio_state_callback_add(FIO_CALL_ON_FINISH,
372
- iodine_perform_state_callback_persist,
373
- (void *)block);
374
- } else {
375
- IodineStore.remove(block);
376
- rb_raise(rb_eTypeError, "unknown event in Iodine.on_state");
377
- }
378
- return block;
379
- (void)self;
380
- }
381
-
382
- /* Performs any cleanup before worker dies */
383
- static void iodine_defer_on_finish(void *ignr) {
384
- (void)ignr;
385
- iodine_join_io_thread();
386
- }
387
-
388
- /* *****************************************************************************
389
- Add defer API to Iodine
390
- ***************************************************************************** */
391
-
392
- void iodine_defer_initialize(void) {
393
- call_id = rb_intern2("call", 4);
394
- rb_define_module_function(IodineModule, "run", iodine_defer_run, 0);
395
- rb_define_module_function(IodineModule, "defer", iodine_defer_run, 0);
396
-
397
- rb_define_module_function(IodineModule, "run_after", iodine_defer_run_after,
398
- 1);
399
- rb_define_module_function(IodineModule, "run_every", iodine_defer_run_every,
400
- -1);
401
- rb_define_module_function(IodineModule, "on_state", iodine_on_state, 1);
402
-
403
- STATE_PRE_START = rb_intern("pre_start");
404
- STATE_BEFORE_FORK = rb_intern("before_fork");
405
- STATE_AFTER_FORK = rb_intern("after_fork");
406
- STATE_ENTER_CHILD = rb_intern("enter_child");
407
- STATE_ENTER_MASTER = rb_intern("enter_master");
408
- STATE_ON_START = rb_intern("on_start");
409
- STATE_ON_PARENT_CRUSH = rb_intern("on_parent_crush");
410
- STATE_ON_CHILD_CRUSH = rb_intern("on_child_crush");
411
- STATE_START_SHUTDOWN = rb_intern("start_shutdown");
412
- STATE_ON_FINISH = rb_intern("on_finish");
413
-
414
- /* start the IO thread is workrs (only starts in root if root is worker) */
415
- fio_state_callback_add(FIO_CALL_ON_START, iodine_start_io_thread, NULL);
416
- /* stop the IO thread before exit */
417
- fio_state_callback_add(FIO_CALL_ON_FINISH, iodine_defer_on_finish, NULL);
418
- /* kill IO thread even after a non-graceful iodine shutdown (force-quit) */
419
- fio_state_callback_add(FIO_CALL_AT_EXIT, iodine_defer_on_finish, NULL);
420
- }
@@ -1,120 +0,0 @@
1
- #ifndef H_RB_FIOBJ2RUBY_H
2
- /*
3
- Copyright: Boaz segev, 2016-2017
4
- License: MIT
5
-
6
- Feel free to copy, use and enjoy according to the license provided.
7
- */
8
- #define H_RB_FIOBJ2RUBY_H
9
- #include <fiobj.h>
10
- #include <ruby.h>
11
-
12
- #include "iodine_store.h"
13
-
14
- typedef struct {
15
- FIOBJ stack;
16
- uintptr_t count;
17
- VALUE rb;
18
- uint8_t str2sym;
19
- } fiobj2rb_s;
20
-
21
- typedef struct {
22
- uint8_t str2sym;
23
- } fiobj2rb_settings_s;
24
-
25
- static inline VALUE fiobj2rb(FIOBJ o, uint8_t str2sym) {
26
- VALUE rb;
27
- if (!o)
28
- return Qnil;
29
- switch (FIOBJ_TYPE(o)) {
30
- case FIOBJ_T_NUMBER:
31
- rb = LONG2FIX(fiobj_obj2num(o));
32
- break;
33
- case FIOBJ_T_TRUE:
34
- rb = Qtrue;
35
- break;
36
- case FIOBJ_T_FALSE:
37
- rb = Qfalse;
38
- break;
39
- case FIOBJ_T_FLOAT:
40
- rb = rb_float_new(fiobj_obj2float(o));
41
- break;
42
- case FIOBJ_T_DATA: /* fallthrough */
43
- case FIOBJ_T_UNKNOWN: /* fallthrough */
44
- case FIOBJ_T_STRING: {
45
- fio_str_info_s tmp = fiobj_obj2cstr(o);
46
- if (str2sym) {
47
- rb = rb_intern2(tmp.data, tmp.len);
48
- rb = ID2SYM(rb);
49
- } else {
50
- rb = rb_str_new(tmp.data, tmp.len);
51
- }
52
-
53
- } break;
54
- case FIOBJ_T_ARRAY:
55
- rb = rb_ary_new();
56
- break;
57
- case FIOBJ_T_HASH:
58
- rb = rb_hash_new();
59
- break;
60
- case FIOBJ_T_NULL: /* fallthrough */
61
- default:
62
- rb = Qnil;
63
- break;
64
- };
65
- return rb;
66
- }
67
-
68
- static int fiobj2rb_task(FIOBJ o, void *data_) {
69
- fiobj2rb_s *data = data_;
70
- VALUE rb_tmp;
71
- rb_tmp = fiobj2rb(o, 0);
72
- IodineStore.add(rb_tmp);
73
- if (data->rb) {
74
- if (RB_TYPE_P(data->rb, T_HASH)) {
75
- rb_hash_aset(data->rb, fiobj2rb(fiobj_hash_key_in_loop(), data->str2sym),
76
- rb_tmp);
77
- } else {
78
- rb_ary_push(data->rb, rb_tmp);
79
- }
80
- --(data->count);
81
- IodineStore.remove(rb_tmp);
82
- } else {
83
- data->rb = rb_tmp;
84
- // IodineStore.add(rb_tmp);
85
- }
86
- if (FIOBJ_TYPE_IS(o, FIOBJ_T_ARRAY)) {
87
- fiobj_ary_push(data->stack, (FIOBJ)data->count);
88
- fiobj_ary_push(data->stack, (FIOBJ)data->rb);
89
- data->count = fiobj_ary_count(o);
90
- data->rb = rb_tmp;
91
- } else if (FIOBJ_TYPE_IS(o, FIOBJ_T_HASH)) {
92
- fiobj_ary_push(data->stack, (FIOBJ)data->count);
93
- fiobj_ary_push(data->stack, (FIOBJ)data->rb);
94
- data->count = fiobj_hash_count(o);
95
- data->rb = rb_tmp;
96
- }
97
- while (data->count == 0 && fiobj_ary_count(data->stack)) {
98
- data->rb = fiobj_ary_pop(data->stack);
99
- data->count = fiobj_ary_pop(data->stack);
100
- }
101
- return 0;
102
- }
103
-
104
- static inline VALUE fiobj2rb_deep(FIOBJ obj, uint8_t str2sym) {
105
- fiobj2rb_s data = {.stack = fiobj_ary_new2(4), .str2sym = str2sym};
106
-
107
- /* deep copy */
108
- fiobj_each2(obj, fiobj2rb_task, &data);
109
- /* cleanup (shouldn't happen, but what the hell)... */
110
- while (fiobj_ary_pop(data.stack))
111
- ;
112
- fiobj_free(data.stack);
113
- // IodineStore.remove(data.rb); // don't remove data
114
- return data.rb;
115
- }
116
-
117
- // require 'iodine'
118
- // Iodine::JSON.parse "{\"1\":[1,2,3,4]}"
119
- // Iodine::JSON.parse IO.binread("")
120
- #endif /* H_RB_FIOBJ2RUBY_H */