evio 0.0.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.
data/ext/evio/ev.c ADDED
@@ -0,0 +1,108 @@
1
+ #include <ruby.h>
2
+ #include <ev.h>
3
+
4
+ #include "evio.h"
5
+
6
+
7
+ static void
8
+ prepare_cb(struct ev_loop *loop, ev_prepare *watcher, int revents)
9
+ {
10
+ prepare_data *data = watcher->data;
11
+
12
+ rb_funcall(data->block, rb_intern("call"), 0);
13
+ ev_prepare_stop(loop, watcher);
14
+ rb_gc_unregister_address(&data->block);
15
+ free(data);
16
+ free(watcher);
17
+ }
18
+
19
+ static void
20
+ timer_cb(struct ev_loop *loop, ev_timer *watcher, int revents)
21
+ {
22
+ timer_data *data = watcher->data;
23
+ VALUE rv;
24
+
25
+ rv = rb_funcall(data->block, rb_intern("call"), 0);
26
+
27
+ if (data->repeat == 0 || rv == Qfalse) {
28
+ // remove watcher from loop
29
+ ev_timer_stop(loop, watcher);
30
+ // make the block available for gc collect
31
+ rb_gc_unregister_address(&data->block);
32
+ // free resources unmanaged by the gc
33
+ free(data);
34
+ free(watcher);
35
+ }
36
+ }
37
+
38
+ static VALUE
39
+ set_timer(VALUE self, VALUE delay, VALUE repeat_delay)
40
+ {
41
+ ev_timer *watcher;
42
+ timer_data *data;
43
+ int type;
44
+ double dl, repeat_dl;
45
+
46
+ rb_secure(2);
47
+
48
+ if ((type = TYPE(delay)) == T_FLOAT || type == T_FIXNUM)
49
+ dl = NUM2DBL(delay);
50
+ else
51
+ rb_raise(rb_eArgError, "first argument must be a number");
52
+
53
+ if ((type = TYPE(repeat_delay)) == T_FLOAT || type == T_FIXNUM)
54
+ repeat_dl = NUM2DBL(repeat_delay);
55
+ else
56
+ rb_raise(rb_eArgError, "second argument must be a number");
57
+
58
+ if (!rb_block_given_p())
59
+ rb_raise(rb_eArgError, "a block is required");
60
+
61
+ watcher = ALLOC(ev_timer);
62
+ data = ALLOC(timer_data);
63
+ // bind the block to its outer scope and store for later use
64
+ data->block = rb_block_proc();
65
+ // don't let the gc collect it
66
+ rb_gc_register_address(&data->block);
67
+ watcher->data = data;
68
+ if (repeat_dl > 0) data->repeat = 1;
69
+ else data->repeat = 0;
70
+ ev_timer_init(watcher, timer_cb, dl, repeat_dl);
71
+ ev_timer_start(loop, watcher);
72
+
73
+ return Qnil;
74
+ }
75
+
76
+ static VALUE
77
+ start_loop(VALUE self)
78
+ {
79
+ ev_prepare *watcher;
80
+ prepare_data *data;
81
+
82
+ if (rb_block_given_p()) {
83
+ watcher = ALLOC(ev_prepare);
84
+ data = ALLOC(prepare_data);
85
+ data->block = rb_block_proc();
86
+ rb_gc_register_address(&data->block);
87
+ watcher->data = data;
88
+ ev_prepare_init(watcher, prepare_cb);
89
+ ev_prepare_start(loop, watcher);
90
+ }
91
+
92
+ ev_run(loop, 0);
93
+ return Qnil;
94
+ }
95
+
96
+ static VALUE
97
+ stop_loop(VALUE self)
98
+ {
99
+ ev_break(loop, EVBREAK_ALL);
100
+ return Qnil;
101
+ }
102
+
103
+ void init_ev(VALUE module)
104
+ {
105
+ rb_define_module_function(module, "set_timer", set_timer, 2);
106
+ rb_define_module_function(module, "start_loop", start_loop, 0);
107
+ rb_define_module_function(module, "stop_loop", stop_loop, 0);
108
+ }
data/ext/evio/evio.c ADDED
@@ -0,0 +1,14 @@
1
+ #include <ruby.h>
2
+ #include <ev.h>
3
+
4
+ #include "evio.h"
5
+
6
+
7
+ void Init_evio()
8
+ {
9
+ loop = EV_DEFAULT;
10
+ VALUE module = rb_define_module("Evio");
11
+ init_ev(module);
12
+ init_signal(module);
13
+ init_io(module);
14
+ }
data/ext/evio/evio.h ADDED
@@ -0,0 +1,33 @@
1
+
2
+ typedef struct {
3
+ int fd;
4
+ int closed;
5
+ enum {
6
+ file,
7
+ socket
8
+ } stream_type;
9
+
10
+ } io_stream;
11
+
12
+ struct block_wrapper {
13
+ VALUE block;
14
+ };
15
+
16
+ typedef struct block_wrapper signal_data;
17
+ typedef struct block_wrapper prepare_data;
18
+ typedef struct {
19
+ VALUE block;
20
+ int buffer_size;
21
+ char *buffer;
22
+ } io_read_data;
23
+ typedef struct {
24
+ VALUE block;
25
+ int repeat;
26
+ } timer_data;
27
+
28
+ struct ev_loop *loop;
29
+
30
+ void Init_evio();
31
+ void init_ev(VALUE module);
32
+ void init_signal(VALUE module);
33
+ void init_io(VALUE module);
@@ -0,0 +1,29 @@
1
+ ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
2
+
3
+ require 'mkmf'
4
+
5
+ HEADER_DIRS = [
6
+ '/opt/local/include',
7
+ '/usr/local/include',
8
+ Config::CONFIG['includedir'],
9
+ '/usr/include',
10
+ ]
11
+
12
+ LIB_DIRS = [
13
+ '/opt/local/lib',
14
+ '/usr/local/lib',
15
+ Config::CONFIG['libdir'],
16
+ '/usr/lib',
17
+ ]
18
+
19
+ dir_config('ev', HEADER_DIRS, LIB_DIRS)
20
+
21
+ unless find_header('ev.h')
22
+ abort 'cannot find libev headers, install it before continuing'
23
+ end
24
+
25
+ unless find_library('ev', 'ev_run')
26
+ abort 'cannot find libev'
27
+ end
28
+
29
+ create_makefile('evio/evio')
data/ext/evio/io.c ADDED
@@ -0,0 +1,170 @@
1
+ #include <errno.h>
2
+ #include <string.h>
3
+
4
+ #include <sys/types.h>
5
+ #include <sys/stat.h>
6
+ #include <fcntl.h>
7
+ #include <unistd.h>
8
+
9
+ #include <ruby.h>
10
+ #include <ev.h>
11
+
12
+ #include "evio.h"
13
+
14
+
15
+ VALUE cIO;
16
+
17
+ static void
18
+ io_free(io_stream *stream)
19
+ {
20
+ close(stream->fd);
21
+ free(stream);
22
+ }
23
+
24
+ static VALUE
25
+ io_open(int argc, VALUE *argv)
26
+ {
27
+ io_stream *stream;
28
+ char *path, *mode;
29
+ int flags, filemode;
30
+
31
+ rb_secure(2);
32
+
33
+ if (argc < 1 || argc > 3)
34
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..3)", argc);
35
+
36
+ if (TYPE(argv[0]) != T_STRING)
37
+ rb_raise(rb_eArgError, "first argument must be a string");
38
+
39
+ path = RSTRING_PTR(rb_str_encode_ospath(argv[0]));
40
+
41
+ if (argc > 1) {
42
+ flags = -1;
43
+ if (TYPE(argv[1]) != T_STRING)
44
+ rb_raise(rb_eArgError, "second argument must be a string");
45
+ mode = RSTRING_PTR(argv[1]);
46
+ if (mode[0] == 'r') {
47
+ if (mode[1] == '\0')
48
+ flags = O_RDONLY;
49
+ else if (mode[1] == '+' && mode[2] == '\0')
50
+ flags = O_RDWR;
51
+ } else if (mode[0] == 'w') {
52
+ if (mode[1] == '\0')
53
+ flags = O_WRONLY | O_CREAT;
54
+ else if (mode[1] == '+' && mode[2] == '\0')
55
+ flags = O_RDWR | O_CREAT;
56
+ } else if (mode[0] == 'a') {
57
+ if (mode[1] == '\0')
58
+ flags = O_WRONLY | O_CREAT | O_APPEND;
59
+ else if (mode[1] == '+' && mode[2] == '\0')
60
+ flags = O_RDWR | O_CREAT | O_APPEND;
61
+ }
62
+ if (flags == -1) rb_raise(rb_eArgError, "invalid file mode string");
63
+ } else {
64
+ flags = O_RDONLY;
65
+ }
66
+
67
+ if (argc == 3) {
68
+ if (TYPE(argv[2]) != T_FIXNUM)
69
+ rb_raise(rb_eArgError, "third argument must be an integer");
70
+ filemode = FIX2INT(argv[2]);
71
+ } else {
72
+ filemode = 0644;
73
+ }
74
+
75
+ flags |= O_NONBLOCK;
76
+ stream = ALLOC(io_stream);
77
+ stream->fd = open(path, flags, filemode);
78
+
79
+ if (stream->fd == -1)
80
+ rb_raise(rb_eSystemCallError, "%s", strerror(errno));
81
+
82
+ return Data_Wrap_Struct(cIO, 0, io_free, stream);
83
+ }
84
+
85
+ static void
86
+ io_read_cb(struct ev_loop *loop, ev_io *watcher, int revents)
87
+ {
88
+ ssize_t read_count;
89
+ VALUE rv = Qnil;
90
+ VALUE ex = Qnil;
91
+ io_read_data *data = watcher->data;
92
+
93
+ read_count = read(watcher->fd, data->buffer, data->buffer_size);
94
+
95
+ if (read_count == -1) {
96
+ if (errno == EAGAIN) return;
97
+ else ex = rb_exc_new2(rb_eSystemCallError, strerror(errno));
98
+ }
99
+
100
+ if (read_count != 0) // not EOF
101
+ rv = rb_funcall(data->block, rb_intern("call"), 2, ex,
102
+ rb_str_new(data->buffer, read_count));
103
+
104
+ if (read_count == 0 || rv == Qfalse) {
105
+ ev_io_stop(loop, watcher);
106
+ rb_gc_unregister_address(&data->block);
107
+ free(data->buffer);
108
+ free(data);
109
+ free(watcher);
110
+ }
111
+ }
112
+
113
+ static VALUE
114
+ io_read(int argc, VALUE *argv, VALUE self)
115
+ {
116
+ ev_io *watcher;
117
+ io_read_data *data;
118
+ io_stream *stream;
119
+ int buffer_size;
120
+
121
+ rb_secure(2);
122
+
123
+ if (argc > 1)
124
+ rb_raise(rb_eArgError, "must provide zero or one arguments");
125
+
126
+ if (!rb_block_given_p())
127
+ rb_raise(rb_eArgError, "a block is required");
128
+
129
+ if (argc == 1) {
130
+ if (TYPE(argv[0]) != T_FIXNUM)
131
+ rb_raise(rb_eArgError, "first argument must be an integer");
132
+ buffer_size = FIX2INT(argv[0]);
133
+ } else {
134
+ buffer_size = 4096;
135
+ }
136
+
137
+ Data_Get_Struct(self, io_stream, stream);
138
+ watcher = ALLOC(ev_io);
139
+ data = ALLOC(io_read_data);
140
+ data->block = rb_block_proc();
141
+ data->buffer_size = buffer_size;
142
+ data->buffer = ALLOC_N(char, buffer_size);
143
+ rb_gc_register_address(&data->block);
144
+ watcher->data = data;
145
+ ev_io_init(watcher, io_read_cb, stream->fd, EV_READ);
146
+ ev_io_start(loop, watcher);
147
+
148
+ return Qnil;
149
+ }
150
+
151
+ static VALUE
152
+ io_close(VALUE self)
153
+ {
154
+ io_stream *stream;
155
+
156
+ Data_Get_Struct(self, io_stream, stream);
157
+ close(stream->fd);
158
+
159
+ return Qnil;
160
+ }
161
+
162
+ void init_io(VALUE module)
163
+ {
164
+ cIO = rb_define_class_under(module, "IO", rb_cObject);
165
+
166
+ rb_define_singleton_method(cIO, "open", io_open, -1);
167
+
168
+ rb_define_method(cIO, "read", io_read, -1);
169
+ rb_define_method(cIO, "close", io_close, 0);
170
+ }
data/ext/evio/signal.c ADDED
@@ -0,0 +1,308 @@
1
+ #include <ruby.h>
2
+ #include <ev.h>
3
+
4
+ #include "evio.h"
5
+
6
+ // mostly copied from signal.c(ruby source)
7
+
8
+ static const struct signals {
9
+ const char *signm;
10
+ int signo;
11
+ } siglist [] = {
12
+ {"EXIT", 0},
13
+ #ifdef SIGHUP
14
+ {"HUP", SIGHUP},
15
+ #endif
16
+ {"INT", SIGINT},
17
+ #ifdef SIGQUIT
18
+ {"QUIT", SIGQUIT},
19
+ #endif
20
+ #ifdef SIGILL
21
+ {"ILL", SIGILL},
22
+ #endif
23
+ #ifdef SIGTRAP
24
+ {"TRAP", SIGTRAP},
25
+ #endif
26
+ #ifdef SIGIOT
27
+ {"IOT", SIGIOT},
28
+ #endif
29
+ #ifdef SIGABRT
30
+ {"ABRT", SIGABRT},
31
+ #endif
32
+ #ifdef SIGEMT
33
+ {"EMT", SIGEMT},
34
+ #endif
35
+ #ifdef SIGFPE
36
+ {"FPE", SIGFPE},
37
+ #endif
38
+ #ifdef SIGKILL
39
+ {"KILL", SIGKILL},
40
+ #endif
41
+ #ifdef SIGBUS
42
+ {"BUS", SIGBUS},
43
+ #endif
44
+ #ifdef SIGSEGV
45
+ {"SEGV", SIGSEGV},
46
+ #endif
47
+ #ifdef SIGSYS
48
+ {"SYS", SIGSYS},
49
+ #endif
50
+ #ifdef SIGPIPE
51
+ {"PIPE", SIGPIPE},
52
+ #endif
53
+ #ifdef SIGALRM
54
+ {"ALRM", SIGALRM},
55
+ #endif
56
+ #ifdef SIGTERM
57
+ {"TERM", SIGTERM},
58
+ #endif
59
+ #ifdef SIGURG
60
+ {"URG", SIGURG},
61
+ #endif
62
+ #ifdef SIGSTOP
63
+ {"STOP", SIGSTOP},
64
+ #endif
65
+ #ifdef SIGTSTP
66
+ {"TSTP", SIGTSTP},
67
+ #endif
68
+ #ifdef SIGCONT
69
+ {"CONT", SIGCONT},
70
+ #endif
71
+ #ifdef SIGCHLD
72
+ {"CHLD", SIGCHLD},
73
+ #endif
74
+ #ifdef SIGCLD
75
+ {"CLD", SIGCLD},
76
+ #else
77
+ # ifdef SIGCHLD
78
+ {"CLD", SIGCHLD},
79
+ # endif
80
+ #endif
81
+ #ifdef SIGTTIN
82
+ {"TTIN", SIGTTIN},
83
+ #endif
84
+ #ifdef SIGTTOU
85
+ {"TTOU", SIGTTOU},
86
+ #endif
87
+ #ifdef SIGIO
88
+ {"IO", SIGIO},
89
+ #endif
90
+ #ifdef SIGXCPU
91
+ {"XCPU", SIGXCPU},
92
+ #endif
93
+ #ifdef SIGXFSZ
94
+ {"XFSZ", SIGXFSZ},
95
+ #endif
96
+ #ifdef SIGVTALRM
97
+ {"VTALRM", SIGVTALRM},
98
+ #endif
99
+ #ifdef SIGPROF
100
+ {"PROF", SIGPROF},
101
+ #endif
102
+ #ifdef SIGWINCH
103
+ {"WINCH", SIGWINCH},
104
+ #endif
105
+ #ifdef SIGUSR1
106
+ {"USR1", SIGUSR1},
107
+ #endif
108
+ #ifdef SIGUSR2
109
+ {"USR2", SIGUSR2},
110
+ #endif
111
+ #ifdef SIGLOST
112
+ {"LOST", SIGLOST},
113
+ #endif
114
+ #ifdef SIGMSG
115
+ {"MSG", SIGMSG},
116
+ #endif
117
+ #ifdef SIGPWR
118
+ {"PWR", SIGPWR},
119
+ #endif
120
+ #ifdef SIGPOLL
121
+ {"POLL", SIGPOLL},
122
+ #endif
123
+ #ifdef SIGDANGER
124
+ {"DANGER", SIGDANGER},
125
+ #endif
126
+ #ifdef SIGMIGRATE
127
+ {"MIGRATE", SIGMIGRATE},
128
+ #endif
129
+ #ifdef SIGPRE
130
+ {"PRE", SIGPRE},
131
+ #endif
132
+ #ifdef SIGGRANT
133
+ {"GRANT", SIGGRANT},
134
+ #endif
135
+ #ifdef SIGRETRACT
136
+ {"RETRACT", SIGRETRACT},
137
+ #endif
138
+ #ifdef SIGSOUND
139
+ {"SOUND", SIGSOUND},
140
+ #endif
141
+ #ifdef SIGINFO
142
+ {"INFO", SIGINFO},
143
+ #endif
144
+ {NULL, 0}
145
+ };
146
+
147
+ static int
148
+ signm2signo(const char *nm)
149
+ {
150
+ const struct signals *sigs;
151
+
152
+ for (sigs = siglist; sigs->signm; sigs++)
153
+ if (strcmp(sigs->signm, nm) == 0)
154
+ return sigs->signo;
155
+ return 0;
156
+ }
157
+
158
+ static const char*
159
+ signo2signm(int no)
160
+ {
161
+ const struct signals *sigs;
162
+
163
+ for (sigs = siglist; sigs->signm; sigs++)
164
+ if (sigs->signo == no)
165
+ return sigs->signm;
166
+ return 0;
167
+ }
168
+
169
+ static int
170
+ trap_signm(VALUE vsig)
171
+ {
172
+ int sig = -1;
173
+ const char *s;
174
+
175
+ switch (TYPE(vsig)) {
176
+ case T_FIXNUM:
177
+ sig = FIX2INT(vsig);
178
+ if (sig < 0 || sig >= NSIG) {
179
+ rb_raise(rb_eArgError, "invalid signal number (%d)", sig);
180
+ }
181
+ break;
182
+
183
+ case T_SYMBOL:
184
+ s = rb_id2name(SYM2ID(vsig));
185
+ if (!s) rb_raise(rb_eArgError, "bad signal");
186
+ goto str_signal;
187
+
188
+ default:
189
+ s = StringValuePtr(vsig);
190
+
191
+ str_signal:
192
+ if (strncmp("SIG", s, 3) == 0)
193
+ s += 3;
194
+ sig = signm2signo(s);
195
+ if (sig == 0 && strcmp(s, "EXIT") != 0)
196
+ rb_raise(rb_eArgError, "unsupported signal SIG%s", s);
197
+ }
198
+ return sig;
199
+ }
200
+
201
+ // TODO do something here
202
+ static void
203
+ default_cb(struct ev_loop *loop, ev_signal *watcher, int revents)
204
+ {
205
+
206
+ }
207
+
208
+ static void
209
+ ignore_cb(struct ev_loop *loop, ev_signal *watcher, int revents)
210
+ {
211
+
212
+ }
213
+
214
+ static void
215
+ exit_cb(struct ev_loop *loop, ev_signal *watcher, int revents)
216
+ {
217
+ exit(watcher->signum);
218
+ }
219
+
220
+ static void
221
+ block_cb(struct ev_loop *loop, ev_signal *watcher, int revents)
222
+ {
223
+ signal_data *data = watcher->data;
224
+ VALUE rv;
225
+
226
+ rv = rb_funcall(data->block, rb_intern("call"), 1, INT2FIX(watcher->signum));
227
+
228
+ if (rv == Qfalse) {
229
+ ev_signal_stop(loop, watcher);
230
+ rb_gc_unregister_address(&data->block);
231
+ free(data);
232
+ free(watcher);
233
+ }
234
+ }
235
+
236
+ static VALUE
237
+ sig_trap(int argc, VALUE *argv)
238
+ {
239
+ ev_signal *watcher;
240
+ VALUE cmd;
241
+ signal_data *data;
242
+ int sign;
243
+
244
+ rb_secure(2);
245
+
246
+ if (argc < 1 || argc > 2)
247
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..2)", argc);
248
+
249
+ sign = trap_signm(argv[0]);
250
+ watcher = ALLOC(ev_signal);
251
+
252
+ if (argc == 1) {
253
+ data = ALLOC(signal_data);
254
+ data->block = rb_block_proc();
255
+ watcher->data = data;
256
+ rb_gc_register_address(&data->block);
257
+ ev_signal_init(watcher, block_cb, sign);
258
+ } else {
259
+ cmd = argv[1];
260
+ if (OBJ_TAINTED(cmd))
261
+ rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
262
+ if (!NIL_P(cmd)) {
263
+ switch (RSTRING_LEN(cmd)) {
264
+ case 0:
265
+ goto sig_ign;
266
+ break;
267
+ case 14:
268
+ if (strncmp(RSTRING_PTR(cmd), "SYSTEM_DEFAULT", 14) == 0) {
269
+ sig_dfl:
270
+ ev_signal_init(watcher, default_cb, sign);
271
+ }
272
+ break;
273
+ case 7:
274
+ if (strncmp(RSTRING_PTR(cmd), "SIG_IGN", 7) == 0) {
275
+ sig_ign:
276
+ ev_signal_init(watcher, ignore_cb, sign);
277
+ }
278
+ else if (strncmp(RSTRING_PTR(cmd), "SIG_DFL", 7) == 0) {
279
+ goto sig_dfl;
280
+ }
281
+ else if (strncmp(RSTRING_PTR(cmd), "DEFAULT", 7) == 0) {
282
+ goto sig_dfl;
283
+ }
284
+ break;
285
+ case 6:
286
+ if (strncmp(RSTRING_PTR(cmd), "IGNORE", 6) == 0)
287
+ goto sig_ign;
288
+ break;
289
+ case 4:
290
+ if (strncmp(RSTRING_PTR(cmd), "EXIT", 4) == 0) {
291
+ ev_signal_init(watcher, exit_cb, sign);
292
+ }
293
+ break;
294
+ }
295
+ }
296
+ }
297
+
298
+ ev_signal_start(loop, watcher);
299
+ return Qnil;
300
+ }
301
+
302
+ void
303
+ init_signal(VALUE module)
304
+ {
305
+ VALUE signal_module = rb_define_module_under(module, "Signal");
306
+
307
+ rb_define_module_function(signal_module, "trap", sig_trap, -1);
308
+ }
data/lib/evio.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'evio/signal'
2
+ require 'evio/evio'
@@ -0,0 +1,18 @@
1
+
2
+ module Evio
3
+
4
+ module Signal
5
+
6
+ def clear_signal_traps
7
+ # Remove all default handlers since they cause segfault
8
+ # with libev handlers
9
+ Signal.list.values.each do |s|
10
+ Signal.trap s, 'IGNORE'
11
+ end
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+
18
+
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: evio
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Thiago de Arruda
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description:
31
+ email: tpadilha84@gmail.com
32
+ executables: []
33
+ extensions:
34
+ - ext/evio/extconf.rb
35
+ extra_rdoc_files: []
36
+ files:
37
+ - lib/evio/signal.rb
38
+ - lib/evio.rb
39
+ - ext/evio/ev.c
40
+ - ext/evio/evio.c
41
+ - ext/evio/io.c
42
+ - ext/evio/signal.c
43
+ - ext/evio/evio.h
44
+ - ext/evio/extconf.rb
45
+ homepage: http://rubygems.org/gems/evio
46
+ licenses: []
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 1.8.23
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: Simple non-blocking IO
69
+ test_files: []