iodine 0.2.7 → 0.2.8

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.

Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -1
  3. data/README.md +5 -1
  4. data/ext/iodine/base64.c +3 -3
  5. data/ext/iodine/base64.h +3 -3
  6. data/ext/iodine/bscrypt-common.h +5 -5
  7. data/ext/iodine/bscrypt.h +4 -4
  8. data/ext/iodine/hex.c +11 -10
  9. data/ext/iodine/hex.h +3 -3
  10. data/ext/iodine/http.c +34 -27
  11. data/ext/iodine/http.h +15 -8
  12. data/ext/iodine/http1.c +63 -60
  13. data/ext/iodine/http1.h +10 -5
  14. data/ext/iodine/http1_simple_parser.c +6 -0
  15. data/ext/iodine/http1_simple_parser.h +10 -6
  16. data/ext/iodine/http_request.h +28 -22
  17. data/ext/iodine/http_response.c +22 -7
  18. data/ext/iodine/http_response.h +6 -0
  19. data/ext/iodine/http_response_http1.h +9 -1
  20. data/ext/iodine/iodine_core.c +6 -1
  21. data/ext/iodine/iodine_core.h +13 -6
  22. data/ext/iodine/iodine_http.c +6 -0
  23. data/ext/iodine/iodine_http.h +6 -0
  24. data/ext/iodine/iodine_websocket.c +23 -4
  25. data/ext/iodine/iodine_websocket.h +2 -2
  26. data/ext/iodine/libasync.c +5 -3
  27. data/ext/iodine/libasync.h +8 -8
  28. data/ext/iodine/libreact.c +8 -8
  29. data/ext/iodine/libreact.h +5 -5
  30. data/ext/iodine/libserver.c +2 -2
  31. data/ext/iodine/libserver.h +2 -2
  32. data/ext/iodine/libsock.c +2 -2
  33. data/ext/iodine/libsock.h +3 -3
  34. data/ext/iodine/mempool.h +826 -0
  35. data/ext/iodine/misc.c +14 -14
  36. data/ext/iodine/misc.h +3 -3
  37. data/ext/iodine/random.c +6 -6
  38. data/ext/iodine/random.h +3 -3
  39. data/ext/iodine/rb-call.c +6 -0
  40. data/ext/iodine/rb-call.h +2 -2
  41. data/ext/iodine/rb-libasync.h +5 -3
  42. data/ext/iodine/rb-rack-io.c +15 -3
  43. data/ext/iodine/rb-rack-io.h +5 -2
  44. data/ext/iodine/rb-registry.c +6 -0
  45. data/ext/iodine/rb-registry.h +2 -2
  46. data/ext/iodine/sha1.c +13 -11
  47. data/ext/iodine/sha1.h +3 -3
  48. data/ext/iodine/sha2.c +8 -6
  49. data/ext/iodine/sha2.h +3 -3
  50. data/ext/iodine/siphash.c +9 -2
  51. data/ext/iodine/siphash.h +8 -1
  52. data/ext/iodine/spnlock.h +9 -3
  53. data/ext/iodine/websockets.c +62 -38
  54. data/ext/iodine/websockets.h +6 -0
  55. data/ext/iodine/xor-crypt.c +3 -3
  56. data/ext/iodine/xor-crypt.h +3 -3
  57. data/lib/iodine/version.rb +1 -1
  58. metadata +3 -4
  59. data/ext/iodine/rb-call.c_old +0 -127
  60. data/ext/iodine/rb-registry_old.c_old +0 -213
@@ -1,3 +1,9 @@
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
+ */
1
7
  #ifndef WEBSOCKETS_H
2
8
  #define WEBSOCKETS_H
3
9
 
@@ -1,7 +1,7 @@
1
1
  /*
2
- (un)copyright: Boaz segev, 2016
3
- License: Public Domain except for any non-public-domain algorithms, which are
4
- subject to their own licenses.
2
+ Copyright: Boaz segev, 2016-2017
3
+ License: MIT except for any non-public-domain algorithms (none that I'm aware
4
+ of), which might be subject to their own licenses.
5
5
 
6
6
  Feel free to copy, use and enjoy in accordance with to the license(s).
7
7
  */
@@ -1,7 +1,7 @@
1
1
  /*
2
- (un)copyright: Boaz segev, 2016
3
- License: Public Domain except for any non-public-domain algorithms, which are
4
- subject to their own licenses.
2
+ Copyright: Boaz segev, 2016-2017
3
+ License: MIT except for any non-public-domain algorithms (none that I'm aware
4
+ of), which might be subject to their own licenses.
5
5
 
6
6
  Feel free to copy, use and enjoy in accordance with to the license(s).
7
7
  */
@@ -1,3 +1,3 @@
1
1
  module Iodine
2
- VERSION = '0.2.7'.freeze
2
+ VERSION = '0.2.8'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iodine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-12-31 00:00:00.000000000 Z
11
+ date: 2017-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -145,19 +145,18 @@ files:
145
145
  - ext/iodine/libserver.h
146
146
  - ext/iodine/libsock.c
147
147
  - ext/iodine/libsock.h
148
+ - ext/iodine/mempool.h
148
149
  - ext/iodine/misc.c
149
150
  - ext/iodine/misc.h
150
151
  - ext/iodine/random.c
151
152
  - ext/iodine/random.h
152
153
  - ext/iodine/rb-call.c
153
- - ext/iodine/rb-call.c_old
154
154
  - ext/iodine/rb-call.h
155
155
  - ext/iodine/rb-libasync.h
156
156
  - ext/iodine/rb-rack-io.c
157
157
  - ext/iodine/rb-rack-io.h
158
158
  - ext/iodine/rb-registry.c
159
159
  - ext/iodine/rb-registry.h
160
- - ext/iodine/rb-registry_old.c_old
161
160
  - ext/iodine/sha1.c
162
161
  - ext/iodine/sha1.h
163
162
  - ext/iodine/sha2.c
@@ -1,127 +0,0 @@
1
- #include "rb-call.h"
2
- #include <ruby.h>
3
- #include <ruby/thread.h>
4
- #include <pthread.h>
5
-
6
- ///////////////
7
- // this is a simple helper that calls Ruby methods on Ruby objects while within
8
- // a non-GVL ruby thread zone.
9
-
10
- // a structure for Ruby API calls
11
- struct RubySimpleCall {
12
- VALUE obj;
13
- VALUE returned;
14
- ID method;
15
- };
16
- struct RubyArgCall {
17
- VALUE obj;
18
- int argc;
19
- VALUE *argv;
20
- VALUE returned;
21
- ID method;
22
- };
23
-
24
- #if __STDC_VERSION__ < 201112L || __STDC_NO_THREADS__
25
- #define _Thread_local __thread
26
- #endif
27
-
28
- // a thread specific global variable that lets us know if we're in the GVL
29
- static _Thread_local char in_gvl = 0;
30
- static char check_in_gvl(void) { return in_gvl; }
31
-
32
- ////////////////////////////////////////////////////////////////////////////
33
- // Calling C functions.
34
- static void *call_c(void *(*func)(void *), void *arg) {
35
- if (in_gvl) {
36
- return func(arg);
37
- }
38
- void *ret;
39
- in_gvl = 1;
40
- ret = rb_thread_call_with_gvl(func, arg);
41
- in_gvl = 0;
42
- return ret;
43
- }
44
-
45
- ////////////////////////////////////////////////////////////////////////////
46
- // Handling exceptions (printing the backtrace doesn't really work well).
47
- static void *handle_exception(void *_) {
48
- VALUE exc = rb_errinfo();
49
- if (exc != Qnil) {
50
- VALUE msg = RubyCaller.call(exc, rb_intern("message"));
51
- VALUE exc_class = rb_class_name(CLASS_OF(exc));
52
- VALUE bt = RubyCaller.call(exc, rb_intern("backtrace"));
53
- if (TYPE(bt) == T_ARRAY) {
54
- bt = rb_ary_join(bt, rb_str_new_literal("\n"));
55
- fprintf(stderr, "Iodine caught an unprotected exception - %.*s: %.*s\n%s",
56
- (int)RSTRING_LEN(exc_class), RSTRING_PTR(exc_class),
57
- (int)RSTRING_LEN(msg), RSTRING_PTR(msg), StringValueCStr(bt));
58
- } else {
59
- fprintf(stderr, "Iodine caught an unprotected exception - %.*s: %.*s\n"
60
- "No backtrace available.\n",
61
- (int)RSTRING_LEN(exc_class), RSTRING_PTR(exc_class),
62
- (int)RSTRING_LEN(msg), RSTRING_PTR(msg));
63
- }
64
- rb_backtrace();
65
- rb_set_errinfo(Qnil);
66
- }
67
- return (void *)Qnil;
68
- }
69
-
70
- ////////////////////////////////////////////////////////////////////////////
71
- // A simple (and a bit lighter) design for when there's no need for arguments.
72
-
73
- // running the actual method call
74
- static VALUE run_ruby_method_unsafe(VALUE _tsk) {
75
- struct RubySimpleCall *task = (void *)_tsk;
76
- return rb_funcall2(task->obj, task->method, 0, NULL);
77
- }
78
-
79
- // GVL gateway
80
- static void *run_ruby_method_within_gvl(void *_tsk) {
81
- struct RubySimpleCall *task = _tsk;
82
- int state = 0;
83
- task->returned = rb_protect(run_ruby_method_unsafe, (VALUE)(task), &state);
84
- if (state)
85
- handle_exception(NULL);
86
- return task;
87
- }
88
-
89
- // wrapping any API calls for exception management AND GVL entry
90
- static VALUE call(VALUE obj, ID method) {
91
- struct RubySimpleCall task = {.obj = obj, .method = method};
92
- call_c(run_ruby_method_within_gvl, &task);
93
- return task.returned;
94
- }
95
-
96
- ////////////////////////////////////////////////////////////////////////////
97
- // A heavier (memory) design for when we're passing arguments around.
98
-
99
- // running the actual method call
100
- static VALUE run_argv_method_unsafe(VALUE _tsk) {
101
- struct RubyArgCall *task = (void *)_tsk;
102
- return rb_funcall2(task->obj, task->method, task->argc, task->argv);
103
- }
104
-
105
- // GVL gateway
106
- static void *run_argv_method_within_gvl(void *_tsk) {
107
- struct RubyArgCall *task = _tsk;
108
- int state = 0;
109
- task->returned = rb_protect(run_argv_method_unsafe, (VALUE)(task), &state);
110
- if (state)
111
- handle_exception(NULL);
112
- return task;
113
- }
114
-
115
- // wrapping any API calls for exception management AND GVL entry
116
- static VALUE call_arg(VALUE obj, ID method, int argc, VALUE *argv) {
117
- struct RubyArgCall task = {
118
- .obj = obj, .method = method, .argc = argc, .argv = argv};
119
- call_c(run_argv_method_within_gvl, &task);
120
- return task.returned;
121
- }
122
-
123
- ////////////////////////////////////////////////////////////////////////////
124
- // the API interface
125
- struct _Ruby_Method_Caller_Class_ RubyCaller = {
126
- .call = call, .call2 = call_arg, .call_c = call_c, .in_gvl = check_in_gvl,
127
- };
@@ -1,213 +0,0 @@
1
- #include "rb-registry.h"
2
- #include "spnlock.h"
3
- #include <ruby.h>
4
-
5
- // #define RUBY_REG_DBG
6
-
7
- // the registry global
8
- static struct Registry {
9
- struct Object *obj_pool;
10
- struct Object *first;
11
- VALUE owner;
12
- spn_lock_i lock;
13
- } registry = {
14
- .obj_pool = NULL, .first = NULL, .owner = 0, .lock = SPN_LOCK_INIT};
15
-
16
- #define try_lock_registry() spn_trylock(&registry.lock)
17
- #define unlock_registry() spn_unlock(&registry.lock)
18
- #define lock_registry() spn_lock(&registry.lock)
19
-
20
- // the references struct (bin-tree)
21
- struct Object {
22
- struct Object *next;
23
- VALUE obj;
24
- int count;
25
- };
26
-
27
- // manage existing objects - add a reference
28
- int add_reference(VALUE obj) {
29
- struct Object *line;
30
- lock_registry();
31
- line = registry.first;
32
- while (line) {
33
- if (line->obj == obj) {
34
- line->count++;
35
- unlock_registry();
36
- return 1;
37
- }
38
- line = line->next;
39
- }
40
- unlock_registry();
41
- return 0;
42
- }
43
-
44
- // add an object to the registry
45
- //
46
- // allow multiple registrartions (bag)
47
- static VALUE register_object(VALUE obj) {
48
- if (!obj || obj == Qnil)
49
- return 0;
50
- if (add_reference(obj))
51
- return obj;
52
- struct Object *line;
53
- lock_registry();
54
- if (registry.obj_pool) {
55
- line = registry.obj_pool;
56
- registry.obj_pool = registry.obj_pool->next;
57
- } else {
58
- line = malloc(sizeof(struct Object));
59
- }
60
- if (!line) {
61
- perror("No Memory!");
62
- unlock_registry();
63
- return 0;
64
- }
65
- line->obj = obj;
66
- line->next = registry.first;
67
- line->count = 1;
68
- registry.first = line;
69
- unlock_registry();
70
- return obj;
71
- }
72
-
73
- // free a single registry
74
- //
75
- // free only one.
76
- static void unregister_object(VALUE obj) {
77
- if (!obj || obj == Qnil)
78
- return;
79
- lock_registry();
80
- struct Object *line = registry.first;
81
- struct Object *prev = NULL;
82
- while (line) {
83
- if (line->obj == obj) {
84
- line->count--;
85
- if (!line->count) {
86
- if (line == registry.first)
87
- registry.first = line->next;
88
- else if (prev) // must be true, really
89
- prev->next = line->next;
90
- // move the object container to the discarded object pool
91
- line->next = registry.obj_pool;
92
- registry.obj_pool = line;
93
- }
94
- goto finish;
95
- }
96
- prev = line;
97
- line = line->next;
98
- }
99
- finish:
100
- unlock_registry();
101
- }
102
-
103
- // // Replaces one registry object with another,
104
- // // allowing updates to the Registry with no memory allocations.
105
- // //
106
- // // returns 0 if all OK, returns -1 if it couldn't replace the object.
107
- // static int replace_object(VALUE obj, VALUE new_obj) {
108
- // int ret = -1;
109
- // if (obj == new_obj)
110
- // return 0;
111
- // pthread_mutex_lock(&registry_lock);
112
- // struct Object* line = registry.first;
113
- // while (line) {
114
- // if (line->obj == obj) {
115
- // line->obj = new_obj;
116
- // ret = 0;
117
- // goto finish;
118
- // }
119
- // line = line->next;
120
- // }
121
- // finish:
122
- // pthread_mutex_unlock(&registry_lock);
123
- // return ret;
124
- // }
125
-
126
- // a callback for the GC (marking active objects)
127
- static void registry_mark(void *ignore) {
128
- #ifdef RUBY_REG_DBG
129
- Registry.print();
130
- #endif
131
- lock_registry();
132
- struct Object *line = registry.first;
133
- while (line) {
134
- if (line->obj)
135
- rb_gc_mark(line->obj);
136
- line = line->next;
137
- }
138
- unlock_registry();
139
- }
140
-
141
- // clear the registry (end of lifetime)
142
- static void registry_clear(void *ignore) {
143
- lock_registry();
144
- struct Object *line;
145
- struct Object *to_free;
146
- // free active object references
147
- line = registry.first;
148
- while (line) {
149
- to_free = line;
150
- line = line->next;
151
- free(to_free);
152
- }
153
- registry.first = NULL;
154
- // free container pool
155
- line = registry.obj_pool;
156
- while (line) {
157
- to_free = line;
158
- line = line->next;
159
- free(to_free);
160
- }
161
- registry.obj_pool = NULL;
162
- registry.owner = 0;
163
- unlock_registry();
164
- }
165
-
166
- // the data-type used to identify the registry
167
- // this sets the callbacks.
168
- static struct rb_data_type_struct my_registry_type_struct = {
169
- .wrap_struct_name = "RubyReferencesIn_C_Land",
170
- .function.dfree = (void (*)(void *))registry_clear,
171
- .function.dmark = (void (*)(void *))registry_mark,
172
- };
173
-
174
- // initialize the registry
175
- static void init(VALUE owner) {
176
- lock_registry();
177
- if (registry.owner)
178
- goto finish;
179
- if (!owner)
180
- owner = rb_cObject;
181
- registry.owner = owner;
182
- VALUE rReferences =
183
- rb_define_class_under(owner, "RubyObjectRegistry_for_C_land", rb_cData);
184
- VALUE r_registry =
185
- TypedData_Wrap_Struct(rReferences, &my_registry_type_struct, &registry);
186
- rb_ivar_set(owner, rb_intern("registry"), r_registry);
187
- finish:
188
- unlock_registry();
189
- }
190
-
191
- // print data, for testing
192
- static void print(void) {
193
- lock_registry();
194
- struct Object *line = registry.first;
195
- fprintf(stderr, "Registry owner is %lu\n", registry.owner);
196
- long index = 0;
197
- while (line) {
198
- fprintf(stderr, "[%lu] => %d X obj %lu type %d at %p\n", index++,
199
- line->count, line->obj, TYPE(line->obj), line);
200
- line = line->next;
201
- }
202
- fprintf(stderr, "Total of %lu registered objects being marked\n", index);
203
- unlock_registry();
204
- }
205
-
206
- ////////////////////////////////////////////
207
- // The API gateway
208
- struct ___RegistryClass___ Registry = {
209
- .init = init,
210
- .remove = unregister_object,
211
- .add = register_object,
212
- .print = print,
213
- };