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,273 +0,0 @@
1
- /*
2
- Copyright: Boaz segev, 2016-2017
3
- License: MIT
4
-
5
- Feel free to copy, use and enjoy according to the license provided.
6
- */
7
- #include "iodine_rack_io.h"
8
-
9
- #include "iodine.h"
10
-
11
- #include <ruby/encoding.h>
12
- #include <ruby/io.h>
13
- #include <unistd.h>
14
-
15
- #ifndef _GNU_SOURCE
16
- #define _GNU_SOURCE
17
- #endif
18
-
19
- /* IodineRackIO manages a minimal interface to act as an IO wrapper according to
20
- these Rack specifications:
21
-
22
- The input stream is an IO-like object which contains the raw HTTP POST data.
23
- When applicable, its external encoding must be “ASCII-8BIT” and it must be
24
- opened in binary mode, for Ruby 1.9 compatibility. The input stream must respond
25
- to gets, each, read and rewind.
26
-
27
- gets must be called without arguments and return a string, or nil on EOF.
28
-
29
- read behaves like IO#read. Its signature is read([length, [buffer]]). If given,
30
- length must be a non-negative Integer (>= 0) or nil, and buffer must be a String
31
- and may not be nil. If length is given and not nil, then this method reads at
32
- most length bytes from the input stream. If length is not given or nil, then
33
- this method reads all data until EOF. When EOF is reached, this method returns
34
- nil if length is given and not nil, or “” if length is not given or is nil. If
35
- buffer is given, then the read data will be placed into buffer instead of a
36
- newly created String object.
37
-
38
- each must be called without arguments and only yield Strings.
39
-
40
- rewind must be called without arguments. It rewinds the input stream back to the
41
- beginning. It must not raise Errno::ESPIPE: that is, it may not be a pipe or a
42
- socket. Therefore, handler developers must buffer the input data into some
43
- rewindable object if the underlying input stream is not rewindable.
44
-
45
- close must never be called on the input stream.
46
-
47
- */
48
-
49
- /* *****************************************************************************
50
- Core data / helpers
51
- */
52
-
53
- static VALUE rRackIO;
54
-
55
- static ID env_id;
56
- static ID io_id;
57
-
58
- static VALUE R_INPUT; /* rack.input */
59
- static VALUE hijack_func_sym;
60
- static VALUE TCPSOCKET_CLASS;
61
- static ID for_fd_id;
62
- static ID iodine_fd_var_id;
63
- static ID iodine_new_func_id;
64
- #ifdef __MINGW32__
65
- static ID iodine_osffd_id;
66
- #endif
67
- static rb_encoding *IodineUTF8Encoding;
68
- static rb_encoding *IodineBinaryEncoding;
69
-
70
- #define set_handle(object, handle) \
71
- rb_ivar_set((object), iodine_fd_var_id, ULL2NUM((uintptr_t)handle))
72
-
73
- inline static http_s *get_handle(VALUE obj) {
74
- VALUE i = rb_ivar_get(obj, iodine_fd_var_id);
75
- return (http_s *)NUM2ULL(i);
76
- }
77
-
78
- /* *****************************************************************************
79
- IO API
80
- */
81
-
82
- static inline FIOBJ get_data(VALUE self) {
83
- VALUE i = rb_ivar_get(self, io_id);
84
- return (FIOBJ)NUM2ULL(i);
85
- }
86
-
87
- static VALUE rio_rewind(VALUE self) {
88
- FIOBJ io = get_data(self);
89
- if (!FIOBJ_TYPE_IS(io, FIOBJ_T_DATA))
90
- return Qnil;
91
- fiobj_data_seek(io, 0);
92
- return INT2NUM(0);
93
- }
94
- /**
95
- Gets returns a line. this is okay for small lines,
96
- but shouldn't really be used.
97
-
98
- Limited to ~ 1Mb of a line length.
99
- */
100
- static VALUE rio_gets(VALUE self) {
101
- FIOBJ io = get_data(self);
102
- if (!FIOBJ_TYPE_IS(io, FIOBJ_T_DATA))
103
- return Qnil;
104
- fio_str_info_s line = fiobj_data_gets(io);
105
- if (line.len) {
106
- VALUE buffer = rb_str_new(line.data, line.len);
107
- // make sure the buffer is binary encoded.
108
- rb_enc_associate(buffer, IodineBinaryEncoding);
109
- return buffer;
110
- }
111
- return Qnil;
112
- }
113
-
114
- // Reads data from the IO, according to the Rack specifications for `#read`.
115
- static VALUE rio_read(int argc, VALUE *argv, VALUE self) {
116
- FIOBJ io = get_data(self);
117
- VALUE buffer = Qnil;
118
- uint8_t ret_nil = 0;
119
- ssize_t len = 0;
120
- if (!FIOBJ_TYPE_IS(io, FIOBJ_T_DATA)) {
121
- return (argc > 0 && argv[0] != Qnil) ? Qnil : rb_str_buf_new(0);
122
- }
123
-
124
- // get the buffer object if given
125
- if (argc == 2) {
126
- Check_Type(argv[1], T_STRING);
127
- buffer = argv[1];
128
- }
129
- // get the length object, if given
130
- if (argc > 0 && argv[0] != Qnil) {
131
- Check_Type(argv[0], T_FIXNUM);
132
- len = FIX2LONG(argv[0]);
133
- if (len < 0)
134
- rb_raise(rb_eRangeError, "length should be bigger then 0.");
135
- if (len == 0)
136
- return rb_str_buf_new(0);
137
- ret_nil = 1;
138
- }
139
- // return if we're at the EOF.
140
- fio_str_info_s buf = fiobj_data_read(io, len);
141
- if (buf.len) {
142
- // create the buffer if we don't have one.
143
- if (buffer == Qnil) {
144
- // make sure the buffer is binary encoded.
145
- buffer = rb_enc_str_new(buf.data, buf.len, IodineBinaryEncoding);
146
- } else {
147
- // make sure the buffer is binary encoded.
148
- rb_enc_associate(buffer, IodineBinaryEncoding);
149
- if (rb_str_capacity(buffer) < (size_t)buf.len)
150
- rb_str_resize(buffer, buf.len);
151
- memcpy(RSTRING_PTR(buffer), buf.data, buf.len);
152
- rb_str_set_len(buffer, buf.len);
153
- }
154
- return buffer;
155
- }
156
- return ret_nil ? Qnil : rb_str_buf_new(0);
157
- }
158
-
159
- // Does nothing - this is controlled by the server.
160
- static VALUE rio_close(VALUE self) {
161
- // FIOBJ io = get_data(self);
162
- // fiobj_free(io); // we don't call fiobj_dup, do we?
163
- rb_ivar_set(self, io_id, INT2NUM(0));
164
- (void)self;
165
- return Qnil;
166
- }
167
-
168
- // Passes each line of the input to the block. This should be avoided.
169
- static VALUE rio_each(VALUE self) {
170
- rb_need_block();
171
- rio_rewind(self);
172
- VALUE str = Qnil;
173
- while ((str = rio_gets(self)) != Qnil) {
174
- rb_yield(str);
175
- }
176
- return self;
177
- }
178
-
179
- /* *****************************************************************************
180
- Hijacking
181
- */
182
-
183
- // defined by iodine_http
184
- extern VALUE IODINE_R_HIJACK; // for Rack: rack.hijack
185
- extern VALUE IODINE_R_HIJACK_CB; // for Rack: rack.hijack
186
- extern VALUE IODINE_R_HIJACK_IO; // for Rack: rack.hijack_io
187
-
188
- static VALUE rio_get_io(int argc, VALUE *argv, VALUE self) {
189
- if (TCPSOCKET_CLASS == Qnil)
190
- return Qfalse;
191
- VALUE env = rb_ivar_get(self, env_id);
192
- http_s *h = get_handle(self);
193
- if (h == NULL) {
194
- /* we're repeating ourselves, aren't we? */
195
- VALUE io = rb_hash_aref(env, IODINE_R_HIJACK_IO);
196
- return io;
197
- }
198
- // mark update
199
- set_handle(self, NULL);
200
- // hijack the IO object
201
- intptr_t uuid = http_hijack(h, NULL);
202
- #ifdef __MINGW32__
203
- int osffd = fio_osffd4fd(fio_uuid2fd(uuid));
204
- if (osffd == -1)
205
- return Qfalse;
206
- VALUE fd = INT2FIX(osffd);
207
- #else
208
- VALUE fd = INT2FIX(fio_uuid2fd(uuid));
209
- #endif
210
- // VALUE new_io = how the fuck do we create a new IO from the fd?
211
- VALUE new_io = IodineCaller.call2(TCPSOCKET_CLASS, for_fd_id, 1,
212
- &fd); // TCPSocket.for_fd(fd) ... cool...
213
- rb_hash_aset(env, IODINE_R_HIJACK_IO, new_io);
214
- if (argc)
215
- rb_hash_aset(env, IODINE_R_HIJACK_CB, *argv);
216
- return new_io;
217
- }
218
-
219
- /* *****************************************************************************
220
- C land API
221
- */
222
-
223
- // new object
224
- static VALUE new_rack_io(http_s *h, VALUE env) {
225
- VALUE rack_io = rb_funcall2(rRackIO, iodine_new_func_id, 0, NULL);
226
- rb_ivar_set(rack_io, io_id, ULL2NUM(h->body));
227
- set_handle(rack_io, h);
228
- rb_ivar_set(rack_io, env_id, env);
229
- rb_hash_aset(env, IODINE_R_INPUT, rack_io);
230
- rb_hash_aset(env, IODINE_R_HIJACK, rb_obj_method(rack_io, hijack_func_sym));
231
- return rack_io;
232
- }
233
-
234
- static void close_rack_io(VALUE rack_io) {
235
- // rio_close(rack_io);
236
- rb_ivar_set(rack_io, io_id, INT2NUM(0));
237
- set_handle(rack_io, NULL); /* this disables hijacking. */
238
- }
239
-
240
- // initialize library
241
- static void init_rack_io(void) {
242
- IodineUTF8Encoding = rb_enc_find("UTF-8");
243
- IodineBinaryEncoding = rb_enc_find("binary");
244
- rRackIO = rb_define_class_under(IodineBaseModule, "RackIO", rb_cObject);
245
-
246
- io_id = rb_intern("rack_io");
247
- env_id = rb_intern("env");
248
- for_fd_id = rb_intern("for_fd");
249
- iodine_fd_var_id = rb_intern("fd");
250
- iodine_new_func_id = rb_intern("new");
251
- #ifdef __MINGW32__
252
- iodine_osffd_id = rb_intern("osffd");
253
- #endif
254
- hijack_func_sym = ID2SYM(rb_intern("_hijack"));
255
-
256
- TCPSOCKET_CLASS = rb_const_get(rb_cObject, rb_intern("TCPSocket"));
257
- // IO methods
258
-
259
- rb_define_method(rRackIO, "rewind", rio_rewind, 0);
260
- rb_define_method(rRackIO, "gets", rio_gets, 0);
261
- rb_define_method(rRackIO, "read", rio_read, -1);
262
- rb_define_method(rRackIO, "close", rio_close, 0);
263
- rb_define_method(rRackIO, "each", rio_each, 0);
264
- rb_define_method(rRackIO, "_hijack", rio_get_io, -1);
265
- }
266
-
267
- ////////////////////////////////////////////////////////////////////////////
268
- // the API interface
269
- struct IodineRackIO IodineRackIO = {
270
- .create = new_rack_io,
271
- .close = close_rack_io,
272
- .init = init_rack_io,
273
- };
@@ -1,20 +0,0 @@
1
- /*
2
- Copyright: Boaz segev, 2016-2017
3
- License: MIT
4
-
5
- Feel free to copy, use and enjoy according to the license provided.
6
- */
7
- #ifndef RUBY_RACK_IO_H
8
- #define RUBY_RACK_IO_H
9
-
10
- #include <ruby.h>
11
-
12
- #include "http.h"
13
-
14
- extern struct IodineRackIO {
15
- VALUE (*create)(http_s *h, VALUE env);
16
- void (*close)(VALUE rack_io);
17
- void (*init)(void);
18
- } IodineRackIO;
19
-
20
- #endif /* RUBY_RACK_IO_H */
@@ -1,146 +0,0 @@
1
- #include "iodine_store.h"
2
-
3
- #include <inttypes.h>
4
- #include <stdint.h>
5
-
6
- #include "iodine.h"
7
-
8
- #define FIO_SET_NAME fio_store
9
- #define FIO_SET_OBJ_TYPE uintptr_t
10
- #include <fio.h>
11
-
12
- static fio_lock_i iodine_storage_lock = FIO_LOCK_INIT;
13
- static fio_store_s iodine_storage = FIO_SET_INIT;
14
- static size_t iodine_storage_count_max = 0;
15
-
16
- #ifndef IODINE_DEBUG
17
- #define IODINE_DEBUG 0
18
- #endif
19
-
20
- /* *****************************************************************************
21
- API
22
- ***************************************************************************** */
23
-
24
- /** Adds an object to the storage (or increases it's reference count). */
25
- static VALUE storage_add(VALUE obj) {
26
- if (!obj || obj == Qnil || obj == Qtrue || obj == Qfalse) return obj;
27
- uintptr_t old = 0;
28
- fio_lock(&iodine_storage_lock);
29
- fio_store_overwrite(&iodine_storage, obj, 1, &old);
30
- if (old) fio_store_overwrite(&iodine_storage, obj, old + 1, NULL);
31
- if (iodine_storage_count_max < fio_store_count(&iodine_storage))
32
- iodine_storage_count_max = fio_store_count(&iodine_storage);
33
- fio_unlock(&iodine_storage_lock);
34
- return obj;
35
- }
36
- /** Removes an object from the storage (or decreases it's reference count). */
37
- static VALUE storage_remove(VALUE obj) {
38
- if (!obj || obj == Qnil || obj == Qtrue || obj == Qfalse ||
39
- iodine_storage.count == 0)
40
- return obj;
41
- fio_lock(&iodine_storage_lock);
42
- uintptr_t old = 0;
43
- fio_store_remove(&iodine_storage, obj, 0, &old);
44
- if (old > 1) fio_store_overwrite(&iodine_storage, obj, old - 1, NULL);
45
- fio_unlock(&iodine_storage_lock);
46
- return obj;
47
- }
48
- /** Should be called after forking to reset locks */
49
- static void storage_after_fork(void) { iodine_storage_lock = FIO_LOCK_INIT; }
50
-
51
- /** Prints debugging information to the console. */
52
- static void storage_print(void) {
53
- FIO_LOG_DEBUG("Ruby <=> C Memory storage stats (pid: %d):\n", getpid());
54
- fio_lock(&iodine_storage_lock);
55
- uintptr_t index = 0;
56
- FIO_SET_FOR_LOOP(&iodine_storage, pos) {
57
- if (pos->obj) {
58
- fprintf(stderr,
59
- "[%" PRIuPTR "] => %" PRIuPTR " X obj %p type %d\n",
60
- index++,
61
- pos->obj,
62
- (void *)pos->hash,
63
- TYPE(pos->hash));
64
- }
65
- }
66
- fprintf(stderr, "Total of %" PRIuPTR " objects protected form GC\n", index);
67
- fprintf(stderr,
68
- "Storage uses %" PRIuPTR " Hash bins for %" PRIuPTR
69
- " objects\n"
70
- "The largest collection was %zu objects.\n",
71
- iodine_storage.capa,
72
- iodine_storage.count,
73
- iodine_storage_count_max);
74
- fio_unlock(&iodine_storage_lock);
75
- }
76
-
77
- /**
78
- * Used for debugging purposes (when testing iodine for Ruby object "leaks").
79
- */
80
- static VALUE storage_print_rb(VALUE self) {
81
- storage_print();
82
- return Qnil;
83
- (void)self;
84
- }
85
- /* *****************************************************************************
86
- GC protection
87
- ***************************************************************************** */
88
-
89
- /* a callback for the GC (marking active objects) */
90
- static void storage_mark(void *ignore) {
91
- (void)ignore;
92
- if (FIO_LOG_LEVEL >= FIO_LOG_LEVEL_DEBUG) storage_print();
93
- fio_lock(&iodine_storage_lock);
94
- // fio_store_compact(&iodine_storage);
95
- FIO_SET_FOR_LOOP(&iodine_storage, pos) {
96
- if (pos->obj) {
97
- rb_gc_mark((VALUE)pos->hash);
98
- }
99
- }
100
- fio_unlock(&iodine_storage_lock);
101
- }
102
-
103
- /* clear the registry (end of lifetime) */
104
- static void storage_clear(void *ignore) {
105
- (void)ignore;
106
- FIO_LOG_DEBUG("Ruby<=>C Storage cleared.\n");
107
- fio_lock(&iodine_storage_lock);
108
- fio_store_free(&iodine_storage);
109
- iodine_storage = (fio_store_s)FIO_SET_INIT;
110
- fio_unlock(&iodine_storage_lock);
111
- }
112
-
113
- /*
114
- the data-type used to identify the registry
115
- this sets the callbacks.
116
- */
117
- static const struct rb_data_type_struct storage_type_struct = {
118
- .wrap_struct_name = "RubyReferencesIn_C_Land",
119
- .function.dfree = (void (*)(void *))storage_clear,
120
- .function.dmark = (void (*)(void *))storage_mark,
121
- };
122
-
123
- /* *****************************************************************************
124
- Initialization
125
- ***************************************************************************** */
126
-
127
- struct IodineStorage_s IodineStore = {
128
- .add = storage_add,
129
- .remove = storage_remove,
130
- .after_fork = storage_after_fork,
131
- .print = storage_print,
132
- };
133
-
134
- /** Initializes the storage unit for first use. */
135
- void iodine_storage_init(void) {
136
- fio_store_capa_require(&iodine_storage, 512);
137
- VALUE tmp = rb_define_module_under(rb_cObject, "IodineObjectStorage");
138
- VALUE storage_obj =
139
- TypedData_Wrap_Struct(tmp, &storage_type_struct, &iodine_storage);
140
- // rb_global_variable(&iodine_storage_obj);
141
- rb_ivar_set(IodineModule, rb_intern2("storage", 7), storage_obj);
142
- rb_define_module_function(IodineBaseModule,
143
- "db_print_protected_objects",
144
- storage_print_rb,
145
- 0);
146
- }