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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -1
- data/README.md +5 -1
- data/ext/iodine/base64.c +3 -3
- data/ext/iodine/base64.h +3 -3
- data/ext/iodine/bscrypt-common.h +5 -5
- data/ext/iodine/bscrypt.h +4 -4
- data/ext/iodine/hex.c +11 -10
- data/ext/iodine/hex.h +3 -3
- data/ext/iodine/http.c +34 -27
- data/ext/iodine/http.h +15 -8
- data/ext/iodine/http1.c +63 -60
- data/ext/iodine/http1.h +10 -5
- data/ext/iodine/http1_simple_parser.c +6 -0
- data/ext/iodine/http1_simple_parser.h +10 -6
- data/ext/iodine/http_request.h +28 -22
- data/ext/iodine/http_response.c +22 -7
- data/ext/iodine/http_response.h +6 -0
- data/ext/iodine/http_response_http1.h +9 -1
- data/ext/iodine/iodine_core.c +6 -1
- data/ext/iodine/iodine_core.h +13 -6
- data/ext/iodine/iodine_http.c +6 -0
- data/ext/iodine/iodine_http.h +6 -0
- data/ext/iodine/iodine_websocket.c +23 -4
- data/ext/iodine/iodine_websocket.h +2 -2
- data/ext/iodine/libasync.c +5 -3
- data/ext/iodine/libasync.h +8 -8
- data/ext/iodine/libreact.c +8 -8
- data/ext/iodine/libreact.h +5 -5
- data/ext/iodine/libserver.c +2 -2
- data/ext/iodine/libserver.h +2 -2
- data/ext/iodine/libsock.c +2 -2
- data/ext/iodine/libsock.h +3 -3
- data/ext/iodine/mempool.h +826 -0
- data/ext/iodine/misc.c +14 -14
- data/ext/iodine/misc.h +3 -3
- data/ext/iodine/random.c +6 -6
- data/ext/iodine/random.h +3 -3
- data/ext/iodine/rb-call.c +6 -0
- data/ext/iodine/rb-call.h +2 -2
- data/ext/iodine/rb-libasync.h +5 -3
- data/ext/iodine/rb-rack-io.c +15 -3
- data/ext/iodine/rb-rack-io.h +5 -2
- data/ext/iodine/rb-registry.c +6 -0
- data/ext/iodine/rb-registry.h +2 -2
- data/ext/iodine/sha1.c +13 -11
- data/ext/iodine/sha1.h +3 -3
- data/ext/iodine/sha2.c +8 -6
- data/ext/iodine/sha2.h +3 -3
- data/ext/iodine/siphash.c +9 -2
- data/ext/iodine/siphash.h +8 -1
- data/ext/iodine/spnlock.h +9 -3
- data/ext/iodine/websockets.c +62 -38
- data/ext/iodine/websockets.h +6 -0
- data/ext/iodine/xor-crypt.c +3 -3
- data/ext/iodine/xor-crypt.h +3 -3
- data/lib/iodine/version.rb +1 -1
- metadata +3 -4
- data/ext/iodine/rb-call.c_old +0 -127
- data/ext/iodine/rb-registry_old.c_old +0 -213
data/ext/iodine/websockets.h
CHANGED
data/ext/iodine/xor-crypt.c
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
|
-
|
3
|
-
License:
|
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
|
*/
|
data/ext/iodine/xor-crypt.h
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
|
-
|
3
|
-
License:
|
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
|
*/
|
data/lib/iodine/version.rb
CHANGED
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.
|
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:
|
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
|
data/ext/iodine/rb-call.c_old
DELETED
@@ -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(®istry.lock)
|
17
|
-
#define unlock_registry() spn_unlock(®istry.lock)
|
18
|
-
#define lock_registry() spn_lock(®istry.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(®istry_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(®istry_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, ®istry);
|
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
|
-
};
|