rev 0.1.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/LICENSE +58 -0
- data/README +107 -0
- data/ext/libev/ev.c +2440 -0
- data/ext/libev/ev.h +551 -0
- data/ext/libev/ev_epoll.c +174 -0
- data/ext/libev/ev_kqueue.c +186 -0
- data/ext/libev/ev_poll.c +127 -0
- data/ext/libev/ev_port.c +155 -0
- data/ext/libev/ev_select.c +236 -0
- data/ext/libev/ev_vars.h +108 -0
- data/ext/libev/ev_win32.c +117 -0
- data/ext/libev/ev_wrap.h +132 -0
- data/ext/rev/extconf.rb +36 -0
- data/ext/rev/rev.h +44 -0
- data/ext/rev/rev_ext.c +29 -0
- data/ext/rev/rev_io_watcher.c +157 -0
- data/ext/rev/rev_loop.c +254 -0
- data/ext/rev/rev_timer_watcher.c +153 -0
- data/ext/rev/rev_watcher.c +222 -0
- data/ext/rev/rev_watcher.h +79 -0
- data/lib/rev.rb +21 -0
- data/lib/rev/buffered_io.rb +123 -0
- data/lib/rev/dns_resolver.rb +178 -0
- data/lib/rev/io_watcher.rb +18 -0
- data/lib/rev/listener.rb +50 -0
- data/lib/rev/loop.rb +101 -0
- data/lib/rev/server.rb +53 -0
- data/lib/rev/socket.rb +186 -0
- data/lib/rev/timer_watcher.rb +18 -0
- data/lib/rev/watcher.rb +49 -0
- data/spec/rev_spec.rb +26 -0
- metadata +93 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
/*
|
2
|
+
* libev win32 compatibility cruft
|
3
|
+
*
|
4
|
+
* Copyright (c) 2007 Marc Alexander Lehmann <libev@schmorp.de>
|
5
|
+
* All rights reserved.
|
6
|
+
*
|
7
|
+
* Redistribution and use in source and binary forms, with or without
|
8
|
+
* modification, are permitted provided that the following conditions are
|
9
|
+
* met:
|
10
|
+
*
|
11
|
+
* * Redistributions of source code must retain the above copyright
|
12
|
+
* notice, this list of conditions and the following disclaimer.
|
13
|
+
*
|
14
|
+
* * Redistributions in binary form must reproduce the above
|
15
|
+
* copyright notice, this list of conditions and the following
|
16
|
+
* disclaimer in the documentation and/or other materials provided
|
17
|
+
* with the distribution.
|
18
|
+
*
|
19
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
20
|
+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
21
|
+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
22
|
+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
23
|
+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
24
|
+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
25
|
+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
26
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
27
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
28
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
*/
|
31
|
+
|
32
|
+
#ifdef _WIN32
|
33
|
+
|
34
|
+
#include <sys/timeb.h>
|
35
|
+
|
36
|
+
/* note: the comment below could not be substantiated, but what would I care */
|
37
|
+
/* MSDN says this is required to handle SIGFPE */
|
38
|
+
volatile double SIGFPE_REQ = 0.0f;
|
39
|
+
|
40
|
+
/* oh, the humanity! */
|
41
|
+
static int
|
42
|
+
ev_pipe (int filedes [2])
|
43
|
+
{
|
44
|
+
struct sockaddr_in addr = { 0 };
|
45
|
+
int addr_size = sizeof (addr);
|
46
|
+
SOCKET listener;
|
47
|
+
SOCKET sock [2] = { -1, -1 };
|
48
|
+
|
49
|
+
if ((listener = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
|
50
|
+
return -1;
|
51
|
+
|
52
|
+
addr.sin_family = AF_INET;
|
53
|
+
addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
54
|
+
addr.sin_port = 0;
|
55
|
+
|
56
|
+
if (bind (listener, (struct sockaddr *)&addr, addr_size))
|
57
|
+
goto fail;
|
58
|
+
|
59
|
+
if (getsockname(listener, (struct sockaddr *)&addr, &addr_size))
|
60
|
+
goto fail;
|
61
|
+
|
62
|
+
if (listen (listener, 1))
|
63
|
+
goto fail;
|
64
|
+
|
65
|
+
if ((sock [0] = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
|
66
|
+
goto fail;
|
67
|
+
|
68
|
+
if (connect (sock[0], (struct sockaddr *)&addr, addr_size))
|
69
|
+
goto fail;
|
70
|
+
|
71
|
+
if ((sock[1] = accept (listener, 0, 0)) < 0)
|
72
|
+
goto fail;
|
73
|
+
|
74
|
+
closesocket (listener);
|
75
|
+
|
76
|
+
#if EV_SELECT_IS_WINSOCKET
|
77
|
+
filedes [0] = _open_osfhandle (sock [0], 0);
|
78
|
+
filedes [1] = _open_osfhandle (sock [1], 0);
|
79
|
+
#else
|
80
|
+
/* when select isn't winsocket, we also expect socket, connect, accept etc.
|
81
|
+
* to work on fds */
|
82
|
+
filedes [0] = sock [0];
|
83
|
+
filedes [1] = sock [1];
|
84
|
+
#endif
|
85
|
+
|
86
|
+
return 0;
|
87
|
+
|
88
|
+
fail:
|
89
|
+
closesocket (listener);
|
90
|
+
|
91
|
+
if (sock [0] != INVALID_SOCKET) closesocket (sock [0]);
|
92
|
+
if (sock [1] != INVALID_SOCKET) closesocket (sock [1]);
|
93
|
+
|
94
|
+
return -1;
|
95
|
+
}
|
96
|
+
|
97
|
+
#undef pipe
|
98
|
+
#define pipe(filedes) ev_pipe (filedes)
|
99
|
+
|
100
|
+
static int
|
101
|
+
ev_gettimeofday (struct timeval *tv, struct timezone *tz)
|
102
|
+
{
|
103
|
+
struct _timeb tb;
|
104
|
+
|
105
|
+
_ftime (&tb);
|
106
|
+
|
107
|
+
tv->tv_sec = (long)tb.time;
|
108
|
+
tv->tv_usec = ((long)tb.millitm) * 1000;
|
109
|
+
|
110
|
+
return 0;
|
111
|
+
}
|
112
|
+
|
113
|
+
#undef gettimeofday
|
114
|
+
#define gettimeofday(tv,tz) ev_gettimeofday (tv, tz)
|
115
|
+
|
116
|
+
#endif
|
117
|
+
|
data/ext/libev/ev_wrap.h
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
/* DO NOT EDIT, automatically generated by update_ev_wrap */
|
2
|
+
#ifndef EV_WRAP_H
|
3
|
+
#define EV_WRAP_H
|
4
|
+
#define now_floor ((loop)->now_floor)
|
5
|
+
#define mn_now ((loop)->mn_now)
|
6
|
+
#define rtmn_diff ((loop)->rtmn_diff)
|
7
|
+
#define io_blocktime ((loop)->io_blocktime)
|
8
|
+
#define timeout_blocktime ((loop)->timeout_blocktime)
|
9
|
+
#define backend ((loop)->backend)
|
10
|
+
#define activecnt ((loop)->activecnt)
|
11
|
+
#define loop_count ((loop)->loop_count)
|
12
|
+
#define backend_fd ((loop)->backend_fd)
|
13
|
+
#define backend_fudge ((loop)->backend_fudge)
|
14
|
+
#define backend_modify ((loop)->backend_modify)
|
15
|
+
#define backend_poll ((loop)->backend_poll)
|
16
|
+
#define curpid ((loop)->curpid)
|
17
|
+
#define postfork ((loop)->postfork)
|
18
|
+
#define vec_ri ((loop)->vec_ri)
|
19
|
+
#define vec_ro ((loop)->vec_ro)
|
20
|
+
#define vec_wi ((loop)->vec_wi)
|
21
|
+
#define vec_wo ((loop)->vec_wo)
|
22
|
+
#define vec_max ((loop)->vec_max)
|
23
|
+
#define polls ((loop)->polls)
|
24
|
+
#define pollmax ((loop)->pollmax)
|
25
|
+
#define pollcnt ((loop)->pollcnt)
|
26
|
+
#define pollidxs ((loop)->pollidxs)
|
27
|
+
#define pollidxmax ((loop)->pollidxmax)
|
28
|
+
#define epoll_events ((loop)->epoll_events)
|
29
|
+
#define epoll_eventmax ((loop)->epoll_eventmax)
|
30
|
+
#define kqueue_changes ((loop)->kqueue_changes)
|
31
|
+
#define kqueue_changemax ((loop)->kqueue_changemax)
|
32
|
+
#define kqueue_changecnt ((loop)->kqueue_changecnt)
|
33
|
+
#define kqueue_events ((loop)->kqueue_events)
|
34
|
+
#define kqueue_eventmax ((loop)->kqueue_eventmax)
|
35
|
+
#define port_events ((loop)->port_events)
|
36
|
+
#define port_eventmax ((loop)->port_eventmax)
|
37
|
+
#define anfds ((loop)->anfds)
|
38
|
+
#define anfdmax ((loop)->anfdmax)
|
39
|
+
#define pendings ((loop)->pendings)
|
40
|
+
#define pendingmax ((loop)->pendingmax)
|
41
|
+
#define pendingcnt ((loop)->pendingcnt)
|
42
|
+
#define fdchanges ((loop)->fdchanges)
|
43
|
+
#define fdchangemax ((loop)->fdchangemax)
|
44
|
+
#define fdchangecnt ((loop)->fdchangecnt)
|
45
|
+
#define timers ((loop)->timers)
|
46
|
+
#define timermax ((loop)->timermax)
|
47
|
+
#define timercnt ((loop)->timercnt)
|
48
|
+
#define periodics ((loop)->periodics)
|
49
|
+
#define periodicmax ((loop)->periodicmax)
|
50
|
+
#define periodiccnt ((loop)->periodiccnt)
|
51
|
+
#define idles ((loop)->idles)
|
52
|
+
#define idlemax ((loop)->idlemax)
|
53
|
+
#define idlecnt ((loop)->idlecnt)
|
54
|
+
#define idleall ((loop)->idleall)
|
55
|
+
#define prepares ((loop)->prepares)
|
56
|
+
#define preparemax ((loop)->preparemax)
|
57
|
+
#define preparecnt ((loop)->preparecnt)
|
58
|
+
#define checks ((loop)->checks)
|
59
|
+
#define checkmax ((loop)->checkmax)
|
60
|
+
#define checkcnt ((loop)->checkcnt)
|
61
|
+
#define forks ((loop)->forks)
|
62
|
+
#define forkmax ((loop)->forkmax)
|
63
|
+
#define forkcnt ((loop)->forkcnt)
|
64
|
+
#define fs_fd ((loop)->fs_fd)
|
65
|
+
#define fs_w ((loop)->fs_w)
|
66
|
+
#define fs_hash ((loop)->fs_hash)
|
67
|
+
#else
|
68
|
+
#undef EV_WRAP_H
|
69
|
+
#undef now_floor
|
70
|
+
#undef mn_now
|
71
|
+
#undef rtmn_diff
|
72
|
+
#undef io_blocktime
|
73
|
+
#undef timeout_blocktime
|
74
|
+
#undef backend
|
75
|
+
#undef activecnt
|
76
|
+
#undef loop_count
|
77
|
+
#undef backend_fd
|
78
|
+
#undef backend_fudge
|
79
|
+
#undef backend_modify
|
80
|
+
#undef backend_poll
|
81
|
+
#undef curpid
|
82
|
+
#undef postfork
|
83
|
+
#undef vec_ri
|
84
|
+
#undef vec_ro
|
85
|
+
#undef vec_wi
|
86
|
+
#undef vec_wo
|
87
|
+
#undef vec_max
|
88
|
+
#undef polls
|
89
|
+
#undef pollmax
|
90
|
+
#undef pollcnt
|
91
|
+
#undef pollidxs
|
92
|
+
#undef pollidxmax
|
93
|
+
#undef epoll_events
|
94
|
+
#undef epoll_eventmax
|
95
|
+
#undef kqueue_changes
|
96
|
+
#undef kqueue_changemax
|
97
|
+
#undef kqueue_changecnt
|
98
|
+
#undef kqueue_events
|
99
|
+
#undef kqueue_eventmax
|
100
|
+
#undef port_events
|
101
|
+
#undef port_eventmax
|
102
|
+
#undef anfds
|
103
|
+
#undef anfdmax
|
104
|
+
#undef pendings
|
105
|
+
#undef pendingmax
|
106
|
+
#undef pendingcnt
|
107
|
+
#undef fdchanges
|
108
|
+
#undef fdchangemax
|
109
|
+
#undef fdchangecnt
|
110
|
+
#undef timers
|
111
|
+
#undef timermax
|
112
|
+
#undef timercnt
|
113
|
+
#undef periodics
|
114
|
+
#undef periodicmax
|
115
|
+
#undef periodiccnt
|
116
|
+
#undef idles
|
117
|
+
#undef idlemax
|
118
|
+
#undef idlecnt
|
119
|
+
#undef idleall
|
120
|
+
#undef prepares
|
121
|
+
#undef preparemax
|
122
|
+
#undef preparecnt
|
123
|
+
#undef checks
|
124
|
+
#undef checkmax
|
125
|
+
#undef checkcnt
|
126
|
+
#undef forks
|
127
|
+
#undef forkmax
|
128
|
+
#undef forkcnt
|
129
|
+
#undef fs_fd
|
130
|
+
#undef fs_w
|
131
|
+
#undef fs_hash
|
132
|
+
#endif
|
data/ext/rev/extconf.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
flags = []
|
4
|
+
|
5
|
+
unless have_func('rb_thread_blocking_region') and have_macro('RB_UBF_DFL', 'ruby.h')
|
6
|
+
abort "Rev requires (a fairly recent) Ruby 1.9 or greater"
|
7
|
+
end
|
8
|
+
|
9
|
+
if have_header('sys/select.h')
|
10
|
+
flags << '-DEV_USE_SELECT'
|
11
|
+
end
|
12
|
+
|
13
|
+
if have_header('poll.h')
|
14
|
+
flags << '-DEV_USE_POLL'
|
15
|
+
end
|
16
|
+
|
17
|
+
if have_header('sys/epoll.h')
|
18
|
+
flags << '-DEV_USE_EPOLL'
|
19
|
+
end
|
20
|
+
|
21
|
+
if have_header('sys/event.h') and have_header('sys/queue.h')
|
22
|
+
flags << '-DEV_USE_KQUEUE'
|
23
|
+
end
|
24
|
+
|
25
|
+
if have_header('port.h')
|
26
|
+
flags << '-DEV_USE_PORT'
|
27
|
+
end
|
28
|
+
|
29
|
+
if have_header('sys/inotify.h')
|
30
|
+
flags << '-DEV_USE_INOTIFY'
|
31
|
+
end
|
32
|
+
|
33
|
+
$CFLAGS << ' ' << flags.join(' ')
|
34
|
+
|
35
|
+
dir_config('rev_ext')
|
36
|
+
create_makefile('rev_ext')
|
data/ext/rev/rev.h
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) 2007 Tony Arcieri
|
3
|
+
* You may redistribute this under the terms of the Ruby license.
|
4
|
+
* See LICENSE for details
|
5
|
+
*/
|
6
|
+
|
7
|
+
#ifndef REV_H
|
8
|
+
#define REV_H
|
9
|
+
|
10
|
+
#include "ruby.h"
|
11
|
+
|
12
|
+
struct Rev_Event
|
13
|
+
{
|
14
|
+
/* These values are used to extract events from libev callbacks */
|
15
|
+
VALUE watcher;
|
16
|
+
int revents;
|
17
|
+
};
|
18
|
+
|
19
|
+
struct Rev_Loop
|
20
|
+
{
|
21
|
+
struct ev_loop *ev_loop;
|
22
|
+
int default_loop;
|
23
|
+
|
24
|
+
int events_received;
|
25
|
+
int eventbuf_size;
|
26
|
+
struct Rev_Event *eventbuf;
|
27
|
+
};
|
28
|
+
|
29
|
+
struct Rev_Watcher
|
30
|
+
{
|
31
|
+
union {
|
32
|
+
struct ev_io ev_io;
|
33
|
+
struct ev_timer ev_timer;
|
34
|
+
} event_types;
|
35
|
+
|
36
|
+
int enabled;
|
37
|
+
VALUE loop;
|
38
|
+
|
39
|
+
void (*dispatch_callback)(VALUE self, int revents);
|
40
|
+
};
|
41
|
+
|
42
|
+
void Rev_Loop_process_event(VALUE watcher, int revents);
|
43
|
+
|
44
|
+
#endif
|
data/ext/rev/rev_ext.c
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) 2007 Tony Arcieri
|
3
|
+
* You may redistribute this under the terms of the Ruby license.
|
4
|
+
* See LICENSE for details
|
5
|
+
*/
|
6
|
+
|
7
|
+
#include "ruby.h"
|
8
|
+
|
9
|
+
#define EV_STANDALONE 1
|
10
|
+
#include "../libev/ev.c"
|
11
|
+
|
12
|
+
#include "rev.h"
|
13
|
+
|
14
|
+
static VALUE mRev = Qnil;
|
15
|
+
|
16
|
+
void Init_rev_ext()
|
17
|
+
{
|
18
|
+
ev_set_allocator((void *(*)(void *, long))xrealloc);
|
19
|
+
mRev = rb_define_module("Rev");
|
20
|
+
|
21
|
+
/* Make libev version available in Ruby */
|
22
|
+
rb_define_const(mRev, "LIBEV_VERSION", rb_sprintf("%d.%d", ev_version_major(), ev_version_minor()));
|
23
|
+
|
24
|
+
/* Initializers for other modules */
|
25
|
+
Init_rev_loop();
|
26
|
+
Init_rev_watcher();
|
27
|
+
Init_rev_io_watcher();
|
28
|
+
Init_rev_timer_watcher();
|
29
|
+
}
|
@@ -0,0 +1,157 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) 2007 Tony Arcieri
|
3
|
+
* You may redistribute this under the terms of the Ruby license.
|
4
|
+
* See LICENSE for details
|
5
|
+
*/
|
6
|
+
|
7
|
+
#include "ruby.h"
|
8
|
+
#include "rubyio.h"
|
9
|
+
|
10
|
+
#define EV_STANDALONE 1
|
11
|
+
#include "../libev/ev.h"
|
12
|
+
|
13
|
+
#include "rev.h"
|
14
|
+
#include "rev_watcher.h"
|
15
|
+
|
16
|
+
/* Module and object handles */
|
17
|
+
static VALUE mRev = Qnil;
|
18
|
+
static VALUE cRev_Watcher = Qnil;
|
19
|
+
static VALUE cRev_Loop = Qnil;
|
20
|
+
static VALUE cRev_IOWatcher = Qnil;
|
21
|
+
|
22
|
+
/* Method implementations */
|
23
|
+
static VALUE Rev_IOWatcher_initialize(int argc, VALUE *argv, VALUE self);
|
24
|
+
static VALUE Rev_IOWatcher_attach(VALUE self, VALUE loop);
|
25
|
+
static VALUE Rev_IOWatcher_detach(VALUE self);
|
26
|
+
static VALUE Rev_IOWatcher_enable(VALUE self);
|
27
|
+
static VALUE Rev_IOWatcher_disable(VALUE self);
|
28
|
+
static VALUE Rev_IOWatcher_on_readable(VALUE self);
|
29
|
+
static VALUE Rev_IOWatcher_on_writable(VALUE self);
|
30
|
+
|
31
|
+
/* Callbacks */
|
32
|
+
static void Rev_IOWatcher_libev_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents);
|
33
|
+
static void Rev_IOWatcher_dispatch_callback(VALUE self, int revents);
|
34
|
+
|
35
|
+
void Init_rev_io_watcher()
|
36
|
+
{
|
37
|
+
mRev = rb_define_module("Rev");
|
38
|
+
cRev_Watcher = rb_define_class_under(mRev, "Watcher", rb_cObject);
|
39
|
+
cRev_IOWatcher = rb_define_class_under(mRev, "IOWatcher", cRev_Watcher);
|
40
|
+
cRev_Loop = rb_define_class_under(mRev, "Loop", rb_cObject);
|
41
|
+
|
42
|
+
rb_define_method(cRev_IOWatcher, "initialize", Rev_IOWatcher_initialize, -1);
|
43
|
+
rb_define_method(cRev_IOWatcher, "attach", Rev_IOWatcher_attach, 1);
|
44
|
+
rb_define_method(cRev_IOWatcher, "detach", Rev_IOWatcher_detach, 0);
|
45
|
+
rb_define_method(cRev_IOWatcher, "enable", Rev_IOWatcher_enable, 0);
|
46
|
+
rb_define_method(cRev_IOWatcher, "disable", Rev_IOWatcher_disable, 0);
|
47
|
+
rb_define_method(cRev_IOWatcher, "on_readable", Rev_IOWatcher_on_readable, 0);
|
48
|
+
rb_define_method(cRev_IOWatcher, "on_writable", Rev_IOWatcher_on_writable, 0);
|
49
|
+
}
|
50
|
+
|
51
|
+
/**
|
52
|
+
* call-seq:
|
53
|
+
* Rev::IOWatcher.initialize(IO, events = 'r') -> Rev::IOWatcher
|
54
|
+
*
|
55
|
+
* Create a new Rev::IOWatcher for the given IO object and add it to the given Rev::Loop
|
56
|
+
*/
|
57
|
+
static VALUE Rev_IOWatcher_initialize(int argc, VALUE *argv, VALUE self)
|
58
|
+
{
|
59
|
+
VALUE io, flags;
|
60
|
+
char *flags_str;
|
61
|
+
int events;
|
62
|
+
rb_io_t *fptr;
|
63
|
+
struct Rev_Watcher *watcher_data;
|
64
|
+
|
65
|
+
rb_scan_args(argc, argv, "11", &io, &flags);
|
66
|
+
|
67
|
+
if(flags != Qnil)
|
68
|
+
flags_str = RSTRING_PTR(rb_String(flags));
|
69
|
+
else
|
70
|
+
flags_str = "r";
|
71
|
+
|
72
|
+
if(!strcmp(flags_str, "r"))
|
73
|
+
events = EV_READ;
|
74
|
+
else if(!strcmp(flags_str, "w"))
|
75
|
+
events = EV_WRITE;
|
76
|
+
else if(!strcmp(flags_str, "rw"))
|
77
|
+
events = EV_READ | EV_WRITE;
|
78
|
+
else
|
79
|
+
rb_raise(rb_eArgError, "invalid event type: '%s' (must be 'r', 'w', or 'rw')", flags_str);
|
80
|
+
|
81
|
+
GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
|
82
|
+
Data_Get_Struct(self, struct Rev_Watcher, watcher_data);
|
83
|
+
|
84
|
+
watcher_data->dispatch_callback = Rev_IOWatcher_dispatch_callback;
|
85
|
+
ev_io_init(&watcher_data->event_types.ev_io, Rev_IOWatcher_libev_callback, fptr->fd, events);
|
86
|
+
watcher_data->event_types.ev_io.data = (void *)self;
|
87
|
+
|
88
|
+
return Qnil;
|
89
|
+
}
|
90
|
+
|
91
|
+
static VALUE Rev_IOWatcher_attach(VALUE self, VALUE loop)
|
92
|
+
{
|
93
|
+
Watcher_Attach(io, Rev_IOWatcher_detach, self, loop);
|
94
|
+
|
95
|
+
return self;
|
96
|
+
}
|
97
|
+
|
98
|
+
static VALUE Rev_IOWatcher_detach(VALUE self)
|
99
|
+
{
|
100
|
+
Watcher_Detach(io, self);
|
101
|
+
|
102
|
+
return self;
|
103
|
+
}
|
104
|
+
|
105
|
+
static VALUE Rev_IOWatcher_enable(VALUE self)
|
106
|
+
{
|
107
|
+
Watcher_Enable(io, self);
|
108
|
+
|
109
|
+
return self;
|
110
|
+
}
|
111
|
+
|
112
|
+
static VALUE Rev_IOWatcher_disable(VALUE self)
|
113
|
+
{
|
114
|
+
Watcher_Disable(io, self);
|
115
|
+
|
116
|
+
return self;
|
117
|
+
}
|
118
|
+
|
119
|
+
/**
|
120
|
+
* call-seq:
|
121
|
+
* Rev::IOWatcher#on_readable -> nil
|
122
|
+
*
|
123
|
+
* Called whenever the IO object associated with the IOWatcher is readable
|
124
|
+
*/
|
125
|
+
static VALUE Rev_IOWatcher_on_readable(VALUE self)
|
126
|
+
{
|
127
|
+
return Qnil;
|
128
|
+
}
|
129
|
+
|
130
|
+
/**
|
131
|
+
* call-seq:
|
132
|
+
* Rev::IOWatcher#on_writable -> nil
|
133
|
+
*
|
134
|
+
* Called whenever the IO object associated with the IOWatcher is writable
|
135
|
+
*/
|
136
|
+
|
137
|
+
static VALUE Rev_IOWatcher_on_writable(VALUE self)
|
138
|
+
{
|
139
|
+
return Qnil;
|
140
|
+
}
|
141
|
+
|
142
|
+
/* libev callback */
|
143
|
+
static void Rev_IOWatcher_libev_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents)
|
144
|
+
{
|
145
|
+
Rev_Loop_process_event((VALUE)io->data, revents);
|
146
|
+
}
|
147
|
+
|
148
|
+
/* Rev::Loop dispatch callback */
|
149
|
+
static void Rev_IOWatcher_dispatch_callback(VALUE self, int revents)
|
150
|
+
{
|
151
|
+
if(revents & EV_READ)
|
152
|
+
rb_funcall(self, rb_intern("on_readable"), 0, 0);
|
153
|
+
else if(revents & EV_WRITE)
|
154
|
+
rb_funcall(self, rb_intern("on_writable"), 0, 0);
|
155
|
+
else
|
156
|
+
rb_raise(rb_eRuntimeError, "unknown revents value for ev_io: %d", revents);
|
157
|
+
}
|