rev 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +45 -9
- data/doc/rdoc/classes/Rev.html +368 -0
- data/doc/rdoc/classes/Rev.src/M000001.html +28 -0
- data/doc/rdoc/classes/Rev.src/M000002.html +35 -0
- data/doc/rdoc/classes/Rev.src/M000003.html +24 -0
- data/doc/rdoc/classes/Rev.src/M000004.html +28 -0
- data/doc/rdoc/classes/Rev.src/M000005.html +27 -0
- data/doc/rdoc/classes/Rev.src/M000006.html +33 -0
- data/doc/rdoc/classes/Rev.src/M000007.html +43 -0
- data/doc/rdoc/classes/Rev.src/M000008.html +16 -0
- data/doc/rdoc/classes/Rev/Buffer.html +354 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000019.html +17 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000020.html +29 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000021.html +27 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000022.html +27 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000023.html +31 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000024.html +31 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000025.html +30 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000026.html +50 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000027.html +22 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000028.html +24 -0
- data/doc/rdoc/classes/Rev/Buffer.src/M000029.html +24 -0
- data/doc/rdoc/classes/Rev/BufferedIO.html +397 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000095.html +23 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000096.html +16 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000097.html +16 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000098.html +16 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000099.html +18 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000100.html +18 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000101.html +23 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000102.html +18 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000103.html +20 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000104.html +24 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000105.html +23 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000106.html +22 -0
- data/doc/rdoc/classes/Rev/BufferedIO.src/M000107.html +29 -0
- data/doc/rdoc/classes/Rev/BufferedIO/Writer.html +154 -0
- data/doc/rdoc/classes/Rev/BufferedIO/Writer.src/M000108.html +19 -0
- data/doc/rdoc/classes/Rev/BufferedIO/Writer.src/M000109.html +18 -0
- data/doc/rdoc/classes/Rev/DNSResolver.html +401 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000124.html +25 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000125.html +29 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000126.html +20 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000127.html +19 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000128.html +16 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000129.html +16 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000131.html +19 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000132.html +21 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000133.html +27 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000134.html +28 -0
- data/doc/rdoc/classes/Rev/DNSResolver.src/M000135.html +55 -0
- data/doc/rdoc/classes/Rev/DNSResolver/Timeout.html +154 -0
- data/doc/rdoc/classes/Rev/DNSResolver/Timeout.src/M000136.html +20 -0
- data/doc/rdoc/classes/Rev/DNSResolver/Timeout.src/M000137.html +22 -0
- data/doc/rdoc/classes/Rev/HttpChunkHeader.html +156 -0
- data/doc/rdoc/classes/Rev/HttpChunkHeader.src/M000031.html +19 -0
- data/doc/rdoc/classes/Rev/HttpClient.html +460 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000042.html +18 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000043.html +27 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000044.html +24 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000045.html +19 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000046.html +17 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000047.html +19 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000048.html +18 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000049.html +18 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000050.html +19 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000051.html +19 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000052.html +19 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000053.html +41 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000054.html +18 -0
- data/doc/rdoc/classes/Rev/HttpClient.src/M000055.html +34 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.html +310 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000009.html +20 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000010.html +20 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000011.html +18 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000012.html +18 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000013.html +18 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000014.html +19 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000015.html +18 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000016.html +18 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000017.html +22 -0
- data/doc/rdoc/classes/Rev/HttpEncoding.src/M000018.html +18 -0
- data/doc/rdoc/classes/Rev/HttpResponseHeader.html +219 -0
- data/doc/rdoc/classes/Rev/HttpResponseHeader.src/M000032.html +18 -0
- data/doc/rdoc/classes/Rev/HttpResponseHeader.src/M000033.html +18 -0
- data/doc/rdoc/classes/Rev/HttpResponseHeader.src/M000034.html +18 -0
- data/doc/rdoc/classes/Rev/IOWatcher.html +285 -0
- data/doc/rdoc/classes/Rev/IOWatcher.src/M000079.html +17 -0
- data/doc/rdoc/classes/Rev/IOWatcher.src/M000080.html +27 -0
- data/doc/rdoc/classes/Rev/IOWatcher.src/M000081.html +26 -0
- data/doc/rdoc/classes/Rev/IOWatcher.src/M000082.html +27 -0
- data/doc/rdoc/classes/Rev/IOWatcher.src/M000083.html +27 -0
- data/doc/rdoc/classes/Rev/IOWatcher.src/M000084.html +24 -0
- data/doc/rdoc/classes/Rev/IOWatcher.src/M000085.html +25 -0
- data/doc/rdoc/classes/Rev/Listener.html +207 -0
- data/doc/rdoc/classes/Rev/Listener.src/M000065.html +19 -0
- data/doc/rdoc/classes/Rev/Listener.src/M000066.html +19 -0
- data/doc/rdoc/classes/Rev/Listener.src/M000067.html +16 -0
- data/doc/rdoc/classes/Rev/Listener.src/M000068.html +18 -0
- data/doc/rdoc/classes/Rev/Loop.html +395 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000070.html +25 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000071.html +45 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000072.html +18 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000073.html +23 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000074.html +19 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000075.html +17 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000076.html +27 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000077.html +32 -0
- data/doc/rdoc/classes/Rev/Loop.src/M000078.html +32 -0
- data/doc/rdoc/classes/Rev/Server.html +164 -0
- data/doc/rdoc/classes/Rev/Server.src/M000121.html +32 -0
- data/doc/rdoc/classes/Rev/Server.src/M000122.html +20 -0
- data/doc/rdoc/classes/Rev/Socket.html +213 -0
- data/doc/rdoc/classes/Rev/Socket.src/M000035.html +21 -0
- data/doc/rdoc/classes/Rev/Socket.src/M000036.html +25 -0
- data/doc/rdoc/classes/Rev/Socket.src/M000037.html +16 -0
- data/doc/rdoc/classes/Rev/Socket.src/M000038.html +16 -0
- data/doc/rdoc/classes/Rev/Socket/Connector.html +154 -0
- data/doc/rdoc/classes/Rev/Socket/Connector.src/M000040.html +19 -0
- data/doc/rdoc/classes/Rev/Socket/Connector.src/M000041.html +28 -0
- data/doc/rdoc/classes/Rev/TCPListener.html +161 -0
- data/doc/rdoc/classes/Rev/TCPListener.src/M000069.html +23 -0
- data/doc/rdoc/classes/Rev/TCPServer.html +147 -0
- data/doc/rdoc/classes/Rev/TCPServer.src/M000123.html +20 -0
- data/doc/rdoc/classes/Rev/TCPSocket.html +233 -0
- data/doc/rdoc/classes/Rev/TCPSocket.src/M000056.html +20 -0
- data/doc/rdoc/classes/Rev/TCPSocket.src/M000057.html +34 -0
- data/doc/rdoc/classes/Rev/TCPSocket.src/M000058.html +24 -0
- data/doc/rdoc/classes/Rev/TCPSocket.src/M000059.html +18 -0
- data/doc/rdoc/classes/Rev/TCPSocket/TCPConnectResolver.html +171 -0
- data/doc/rdoc/classes/Rev/TCPSocket/TCPConnectResolver.src/M000060.html +19 -0
- data/doc/rdoc/classes/Rev/TCPSocket/TCPConnectResolver.src/M000061.html +27 -0
- data/doc/rdoc/classes/Rev/TCPSocket/TCPConnectResolver.src/M000062.html +23 -0
- data/doc/rdoc/classes/Rev/TCPSocket/TCPConnectSocket.html +154 -0
- data/doc/rdoc/classes/Rev/TCPSocket/TCPConnectSocket.src/M000063.html +25 -0
- data/doc/rdoc/classes/Rev/TCPSocket/TCPConnectSocket.src/M000064.html +23 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.html +288 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.src/M000086.html +17 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.src/M000087.html +27 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.src/M000088.html +26 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.src/M000089.html +27 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.src/M000090.html +27 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.src/M000091.html +42 -0
- data/doc/rdoc/classes/Rev/TimerWatcher.src/M000092.html +24 -0
- data/doc/rdoc/classes/Rev/UNIXListener.html +147 -0
- data/doc/rdoc/classes/Rev/UNIXListener.src/M000120.html +18 -0
- data/doc/rdoc/classes/Rev/UNIXServer.html +147 -0
- data/doc/rdoc/classes/Rev/UNIXServer.src/M000030.html +18 -0
- data/doc/rdoc/classes/Rev/UNIXSocket.html +175 -0
- data/doc/rdoc/classes/Rev/UNIXSocket.src/M000093.html +18 -0
- data/doc/rdoc/classes/Rev/UNIXSocket.src/M000094.html +21 -0
- data/doc/rdoc/classes/Rev/Watcher.html +349 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000110.html +20 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000111.html +20 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000112.html +17 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000113.html +48 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000114.html +62 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000115.html +34 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000116.html +34 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000117.html +27 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000118.html +24 -0
- data/doc/rdoc/classes/Rev/Watcher.src/M000119.html +27 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/LICENSE.html +165 -0
- data/doc/rdoc/files/README.html +297 -0
- data/doc/rdoc/files/ext/rev/rev_buffer_c.html +101 -0
- data/doc/rdoc/files/ext/rev/rev_ext_c.html +101 -0
- data/doc/rdoc/files/ext/rev/rev_io_watcher_c.html +101 -0
- data/doc/rdoc/files/ext/rev/rev_loop_c.html +101 -0
- data/doc/rdoc/files/ext/rev/rev_timer_watcher_c.html +101 -0
- data/doc/rdoc/files/ext/rev/rev_watcher_c.html +101 -0
- data/doc/rdoc/files/lib/rev/buffered_io_rb.html +101 -0
- data/doc/rdoc/files/lib/rev/dns_resolver_rb.html +101 -0
- data/doc/rdoc/files/lib/rev/http_client_rb.html +101 -0
- data/doc/rdoc/files/lib/rev/io_watcher_rb.html +101 -0
- data/doc/rdoc/files/lib/rev/listener_rb.html +108 -0
- data/doc/rdoc/files/lib/rev/loop_rb.html +101 -0
- data/doc/rdoc/files/lib/rev/server_rb.html +101 -0
- data/doc/rdoc/files/lib/rev/socket_rb.html +109 -0
- data/doc/rdoc/files/lib/rev/timer_watcher_rb.html +101 -0
- data/doc/rdoc/files/lib/rev/watcher_rb.html +101 -0
- data/doc/rdoc/files/lib/rev_rb.html +101 -0
- data/doc/rdoc/fr_class_index.html +52 -0
- data/doc/rdoc/fr_file_index.html +45 -0
- data/doc/rdoc/fr_method_index.html +163 -0
- data/doc/rdoc/index.html +24 -0
- data/doc/rdoc/rdoc-style.css +208 -0
- data/ext/rev/extconf.rb +1 -1
- data/ext/rev/rev.h +0 -1
- data/ext/rev/rev_buffer.c +606 -0
- data/ext/rev/rev_ext.c +1 -0
- data/ext/rev/rev_io_watcher.c +53 -19
- data/ext/rev/rev_loop.c +12 -35
- data/ext/rev/rev_timer_watcher.c +45 -3
- data/ext/rev/rev_watcher.c +13 -1
- data/lib/http11_client.bundle +0 -0
- data/lib/rev.rb +1 -1
- data/lib/rev/buffered_io.rb +25 -22
- data/lib/rev/dns_resolver.rb +31 -14
- data/lib/rev/http_client.rb +88 -91
- data/lib/rev/listener.rb +22 -5
- data/lib/rev/loop.rb +13 -0
- data/lib/rev/server.rb +10 -3
- data/lib/rev/socket.rb +30 -9
- data/lib/rev/watcher.rb +4 -2
- data/lib/rev_ext.bundle +0 -0
- metadata +230 -2
data/ext/rev/rev_ext.c
CHANGED
data/ext/rev/rev_io_watcher.c
CHANGED
@@ -32,6 +32,13 @@ static VALUE Rev_IOWatcher_on_writable(VALUE self);
|
|
32
32
|
static void Rev_IOWatcher_libev_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents);
|
33
33
|
static void Rev_IOWatcher_dispatch_callback(VALUE self, int revents);
|
34
34
|
|
35
|
+
/*
|
36
|
+
* Rev::IOWatcher monitors Ruby IO objects for readability or writability.
|
37
|
+
* This allows your application to block while the kernel is writing out
|
38
|
+
* data and fill the read or write buffer whenever there is space available.
|
39
|
+
* It's used by the Rev::BufferedIO class to provide high performace I/O
|
40
|
+
* which is bound by the kernel's ability to read and write data.
|
41
|
+
*/
|
35
42
|
void Init_rev_io_watcher()
|
36
43
|
{
|
37
44
|
mRev = rb_define_module("Rev");
|
@@ -56,27 +63,27 @@ void Init_rev_io_watcher()
|
|
56
63
|
*/
|
57
64
|
static VALUE Rev_IOWatcher_initialize(int argc, VALUE *argv, VALUE self)
|
58
65
|
{
|
59
|
-
|
60
|
-
|
61
|
-
|
66
|
+
VALUE io, flags;
|
67
|
+
char *flags_str;
|
68
|
+
int events;
|
62
69
|
rb_io_t *fptr;
|
63
70
|
struct Rev_Watcher *watcher_data;
|
64
71
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
72
|
+
rb_scan_args(argc, argv, "11", &io, &flags);
|
73
|
+
|
74
|
+
if(flags != Qnil)
|
75
|
+
flags_str = RSTRING_PTR(rb_String(flags));
|
76
|
+
else
|
77
|
+
flags_str = "r";
|
78
|
+
|
79
|
+
if(!strcmp(flags_str, "r"))
|
80
|
+
events = EV_READ;
|
81
|
+
else if(!strcmp(flags_str, "w"))
|
82
|
+
events = EV_WRITE;
|
83
|
+
else if(!strcmp(flags_str, "rw"))
|
84
|
+
events = EV_READ | EV_WRITE;
|
85
|
+
else
|
86
|
+
rb_raise(rb_eArgError, "invalid event type: '%s' (must be 'r', 'w', or 'rw')", flags_str);
|
80
87
|
|
81
88
|
GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
|
82
89
|
Data_Get_Struct(self, struct Rev_Watcher, watcher_data);
|
@@ -85,9 +92,16 @@ static VALUE Rev_IOWatcher_initialize(int argc, VALUE *argv, VALUE self)
|
|
85
92
|
ev_io_init(&watcher_data->event_types.ev_io, Rev_IOWatcher_libev_callback, fptr->fd, events);
|
86
93
|
watcher_data->event_types.ev_io.data = (void *)self;
|
87
94
|
|
88
|
-
|
95
|
+
return Qnil;
|
89
96
|
}
|
90
97
|
|
98
|
+
/**
|
99
|
+
* call-seq:
|
100
|
+
* Rev::IOWatcher.attach(loop) -> Rev::IOWatcher
|
101
|
+
*
|
102
|
+
* Attach the IO watcher to the given Rev::Loop. If the watcher is already attached
|
103
|
+
* to a loop, detach it from the old one and attach it to the new one.
|
104
|
+
*/
|
91
105
|
static VALUE Rev_IOWatcher_attach(VALUE self, VALUE loop)
|
92
106
|
{
|
93
107
|
Watcher_Attach(io, Rev_IOWatcher_detach, self, loop);
|
@@ -95,6 +109,12 @@ static VALUE Rev_IOWatcher_attach(VALUE self, VALUE loop)
|
|
95
109
|
return self;
|
96
110
|
}
|
97
111
|
|
112
|
+
/**
|
113
|
+
* call-seq:
|
114
|
+
* Rev::IOWatcher.detach -> Rev::IOWatcher
|
115
|
+
*
|
116
|
+
* Detach the IO watcher from its current Rev::Loop.
|
117
|
+
*/
|
98
118
|
static VALUE Rev_IOWatcher_detach(VALUE self)
|
99
119
|
{
|
100
120
|
Watcher_Detach(io, self);
|
@@ -102,6 +122,13 @@ static VALUE Rev_IOWatcher_detach(VALUE self)
|
|
102
122
|
return self;
|
103
123
|
}
|
104
124
|
|
125
|
+
/**
|
126
|
+
* call-seq:
|
127
|
+
* Rev::IOWatcher.enable -> Rev::IOWatcher
|
128
|
+
*
|
129
|
+
* Re-enable an IO watcher which has been temporarily disabled. See the
|
130
|
+
* disable method for a more thorough explanation.
|
131
|
+
*/
|
105
132
|
static VALUE Rev_IOWatcher_enable(VALUE self)
|
106
133
|
{
|
107
134
|
Watcher_Enable(io, self);
|
@@ -109,6 +136,13 @@ static VALUE Rev_IOWatcher_enable(VALUE self)
|
|
109
136
|
return self;
|
110
137
|
}
|
111
138
|
|
139
|
+
/**
|
140
|
+
* call-seq:
|
141
|
+
* Rev::IOWatcher.disable -> Rev::IOWatcher
|
142
|
+
*
|
143
|
+
* Temporarily disable an IO watcher which is attached to a loop.
|
144
|
+
* This is useful if you wish to toggle event monitoring on and off.
|
145
|
+
*/
|
112
146
|
static VALUE Rev_IOWatcher_disable(VALUE self)
|
113
147
|
{
|
114
148
|
Watcher_Disable(io, self);
|
data/ext/rev/rev_loop.c
CHANGED
@@ -22,7 +22,7 @@ static void Rev_Loop_mark(struct Rev_Loop *loop);
|
|
22
22
|
static void Rev_Loop_free(struct Rev_Loop *loop);
|
23
23
|
|
24
24
|
/* Method implementations */
|
25
|
-
static VALUE
|
25
|
+
static VALUE Rev_Loop_initialize(VALUE self);
|
26
26
|
static VALUE Rev_Loop_ev_loop_new(VALUE self, VALUE flags);
|
27
27
|
static VALUE Rev_Loop_run_once(VALUE self);
|
28
28
|
static VALUE Rev_Loop_run_once_blocking(void *ptr);
|
@@ -32,18 +32,22 @@ static void Rev_Loop_dispatch_events(struct Rev_Loop *loop_data);
|
|
32
32
|
|
33
33
|
#define DEFAULT_EVENTBUF_SIZE 32
|
34
34
|
|
35
|
+
/*
|
36
|
+
* Rev::Loop represents an event loop. Event watchers can be attached and
|
37
|
+
* unattached. When an event loop is run, all currently attached watchers
|
38
|
+
* are monitored for events, and their respective callbacks are signaled
|
39
|
+
* whenever events occur.
|
40
|
+
*/
|
35
41
|
void Init_rev_loop()
|
36
42
|
{
|
37
43
|
mRev = rb_define_module("Rev");
|
38
44
|
cRev_Loop = rb_define_class_under(mRev, "Loop", rb_cObject);
|
39
45
|
rb_define_alloc_func(cRev_Loop, Rev_Loop_allocate);
|
40
|
-
|
41
|
-
|
46
|
+
|
47
|
+
rb_define_method(cRev_Loop, "initialize", Rev_Loop_initialize, 0);
|
42
48
|
rb_define_private_method(cRev_Loop, "ev_loop_new", Rev_Loop_ev_loop_new, 1);
|
43
49
|
rb_define_method(cRev_Loop, "run_once", Rev_Loop_run_once, 0);
|
44
50
|
rb_define_method(cRev_Loop, "run_nonblock", Rev_Loop_run_nonblock, 0);
|
45
|
-
|
46
|
-
rb_cv_set(cRev_Loop, "@@default_loop", Qnil);
|
47
51
|
}
|
48
52
|
|
49
53
|
static VALUE Rev_Loop_allocate(VALUE klass)
|
@@ -51,7 +55,6 @@ static VALUE Rev_Loop_allocate(VALUE klass)
|
|
51
55
|
struct Rev_Loop *loop = (struct Rev_Loop *)xmalloc(sizeof(struct Rev_Loop));
|
52
56
|
|
53
57
|
loop->ev_loop = 0;
|
54
|
-
loop->default_loop = 0;
|
55
58
|
|
56
59
|
loop->events_received = 0;
|
57
60
|
loop->eventbuf_size = DEFAULT_EVENTBUF_SIZE;
|
@@ -69,40 +72,15 @@ static void Rev_Loop_free(struct Rev_Loop *loop)
|
|
69
72
|
if(!loop->ev_loop)
|
70
73
|
return;
|
71
74
|
|
72
|
-
|
73
|
-
ev_default_destroy();
|
74
|
-
else
|
75
|
-
ev_loop_destroy(loop->ev_loop);
|
75
|
+
ev_loop_destroy(loop->ev_loop);
|
76
76
|
|
77
77
|
xfree(loop->eventbuf);
|
78
78
|
xfree(loop);
|
79
79
|
}
|
80
80
|
|
81
|
-
|
82
|
-
/**
|
83
|
-
* call-seq:
|
84
|
-
* Rev::Loop.default -> Rev::Loop
|
85
|
-
*
|
86
|
-
* Retrieve a singleton instance of the default loop for the application
|
87
|
-
*/
|
88
|
-
static VALUE Rev_Loop_default(VALUE klass)
|
81
|
+
static VALUE Rev_Loop_initialize(VALUE self)
|
89
82
|
{
|
90
|
-
|
91
|
-
VALUE default_loop = rb_cv_get(klass, "@@default_loop");
|
92
|
-
|
93
|
-
if(default_loop == Qnil) {
|
94
|
-
default_loop = rb_obj_alloc(klass);
|
95
|
-
Data_Get_Struct(default_loop, struct Rev_Loop, loop_data);
|
96
|
-
|
97
|
-
loop_data->ev_loop = ev_default_loop(0);
|
98
|
-
loop_data->default_loop = 1;
|
99
|
-
|
100
|
-
rb_cv_set(klass, "@@default_loop", default_loop);
|
101
|
-
rb_iv_set(default_loop, "@active_watchers", INT2NUM(0));
|
102
|
-
rb_iv_set(default_loop, "@watchers", rb_ary_new());
|
103
|
-
}
|
104
|
-
|
105
|
-
return default_loop;
|
83
|
+
Rev_Loop_ev_loop_new(self, INT2NUM(0));
|
106
84
|
}
|
107
85
|
|
108
86
|
/* Wrapper for populating a Rev_Loop struct with a new event loop */
|
@@ -115,7 +93,6 @@ static VALUE Rev_Loop_ev_loop_new(VALUE self, VALUE flags)
|
|
115
93
|
rb_raise(rb_eRuntimeError, "loop already initialized");
|
116
94
|
|
117
95
|
loop_data->ev_loop = ev_loop_new(NUM2INT(flags));
|
118
|
-
loop_data->default_loop = 0;
|
119
96
|
|
120
97
|
return Qnil;
|
121
98
|
}
|
data/ext/rev/rev_timer_watcher.c
CHANGED
@@ -31,6 +31,11 @@ static VALUE Rev_TimerWatcher_on_timer(VALUE self);
|
|
31
31
|
static void Rev_TimerWatcher_libev_callback(struct ev_loop *ev_loop, struct ev_timer *timer, int revents);
|
32
32
|
static void Rev_TimerWatcher_dispatch_callback(VALUE self, int revents);
|
33
33
|
|
34
|
+
/*
|
35
|
+
* Rev::TimerWatcher lets you create either one-shot or periodic timers which
|
36
|
+
* run within Rev's event loop. It's useful for creating timeouts or
|
37
|
+
* events which fire periodically.
|
38
|
+
*/
|
34
39
|
void Init_rev_timer_watcher()
|
35
40
|
{
|
36
41
|
mRev = rb_define_module("Rev");
|
@@ -51,7 +56,11 @@ void Init_rev_timer_watcher()
|
|
51
56
|
* call-seq:
|
52
57
|
* Rev::TimerWatcher.initialize(interval, repeating = false) -> Rev::TimerWatcher
|
53
58
|
*
|
54
|
-
* Create a new Rev::TimerWatcher for the given IO object and add it to the
|
59
|
+
* Create a new Rev::TimerWatcher for the given IO object and add it to the
|
60
|
+
* given Rev::Loop. Interval defines a duration in seconds to wait for events,
|
61
|
+
* and can be specified as an Integer or Float. Repeating is a boolean
|
62
|
+
* indicating whether the timer is one shot or should fire on the given
|
63
|
+
* interval.
|
55
64
|
*/
|
56
65
|
static VALUE Rev_TimerWatcher_initialize(int argc, VALUE *argv, VALUE self)
|
57
66
|
{
|
@@ -59,16 +68,29 @@ static VALUE Rev_TimerWatcher_initialize(int argc, VALUE *argv, VALUE self)
|
|
59
68
|
struct Rev_Watcher *watcher_data;
|
60
69
|
|
61
70
|
rb_scan_args(argc, argv, "11", &interval, &repeating);
|
62
|
-
|
71
|
+
interval = rb_convert_type(interval, T_FLOAT, "Float", "to_f");
|
72
|
+
|
63
73
|
Data_Get_Struct(self, struct Rev_Watcher, watcher_data);
|
64
74
|
|
65
75
|
watcher_data->dispatch_callback = Rev_TimerWatcher_dispatch_callback;
|
66
|
-
ev_timer_init(
|
76
|
+
ev_timer_init(
|
77
|
+
&watcher_data->event_types.ev_timer,
|
78
|
+
Rev_TimerWatcher_libev_callback,
|
79
|
+
RFLOAT_VALUE(interval),
|
80
|
+
repeating == Qtrue ? RFLOAT_VALUE(interval) : 0
|
81
|
+
);
|
67
82
|
watcher_data->event_types.ev_timer.data = (void *)self;
|
68
83
|
|
69
84
|
return Qnil;
|
70
85
|
}
|
71
86
|
|
87
|
+
/**
|
88
|
+
* call-seq:
|
89
|
+
* Rev::TimerWatcher.attach(loop) -> Rev::TimerWatcher
|
90
|
+
*
|
91
|
+
* Attach the timer watcher to the given Rev::Loop. If the watcher is already
|
92
|
+
* attached to a loop, detach it from the old one and attach it to the new one.
|
93
|
+
*/
|
72
94
|
static VALUE Rev_TimerWatcher_attach(VALUE self, VALUE loop)
|
73
95
|
{
|
74
96
|
Watcher_Attach(timer, Rev_TimerWatcher_detach, self, loop);
|
@@ -76,6 +98,12 @@ static VALUE Rev_TimerWatcher_attach(VALUE self, VALUE loop)
|
|
76
98
|
return self;
|
77
99
|
}
|
78
100
|
|
101
|
+
/**
|
102
|
+
* call-seq:
|
103
|
+
* Rev::TimerWatcher.detach -> Rev::TimerWatcher
|
104
|
+
*
|
105
|
+
* Detach the timer watcher from its current Rev::Loop.
|
106
|
+
*/
|
79
107
|
static VALUE Rev_TimerWatcher_detach(VALUE self)
|
80
108
|
{
|
81
109
|
Watcher_Detach(timer, self);
|
@@ -83,6 +111,13 @@ static VALUE Rev_TimerWatcher_detach(VALUE self)
|
|
83
111
|
return self;
|
84
112
|
}
|
85
113
|
|
114
|
+
/**
|
115
|
+
* call-seq:
|
116
|
+
* Rev::TimerWatcher.enable -> Rev::TimerWatcher
|
117
|
+
*
|
118
|
+
* Re-enable a timer watcher which has been temporarily disabled. See the
|
119
|
+
* disable method for a more thorough explanation.
|
120
|
+
*/
|
86
121
|
static VALUE Rev_TimerWatcher_enable(VALUE self)
|
87
122
|
{
|
88
123
|
Watcher_Enable(timer, self);
|
@@ -90,6 +125,13 @@ static VALUE Rev_TimerWatcher_enable(VALUE self)
|
|
90
125
|
return self;
|
91
126
|
}
|
92
127
|
|
128
|
+
/**
|
129
|
+
* call-seq:
|
130
|
+
* Rev::TimerWatcher.disable -> Rev::TimerWatcher
|
131
|
+
*
|
132
|
+
* Temporarily disable a timer watcher which is attached to a loop.
|
133
|
+
* This is useful if you wish to toggle event monitoring on and off.
|
134
|
+
*/
|
93
135
|
static VALUE Rev_TimerWatcher_disable(VALUE self)
|
94
136
|
{
|
95
137
|
Watcher_Disable(timer, self);
|
data/ext/rev/rev_watcher.c
CHANGED
@@ -30,6 +30,18 @@ static VALUE Rev_Watcher_evloop(VALUE self);
|
|
30
30
|
static VALUE Rev_Watcher_attached(VALUE self);
|
31
31
|
static VALUE Rev_Watcher_enabled(VALUE self);
|
32
32
|
|
33
|
+
/*
|
34
|
+
* Watchers are Rev's event observers. They contain a set of callback
|
35
|
+
* methods prefixed by on_* which fire whenever events occur.
|
36
|
+
*
|
37
|
+
* In order for a watcher to fire events it must be attached to a running
|
38
|
+
* loop. Every watcher has an attach and detach method to control which
|
39
|
+
* loop it's associated with.
|
40
|
+
*
|
41
|
+
* Watchers also have an enable and disable method. This allows a watcher
|
42
|
+
* to temporarily ignore certain events while remaining attached to a given
|
43
|
+
* loop. This is good for watchers which need to be toggled on and off.
|
44
|
+
*/
|
33
45
|
void Init_rev_watcher()
|
34
46
|
{
|
35
47
|
mRev = rb_define_module("Rev");
|
@@ -235,4 +247,4 @@ static VALUE Rev_Watcher_enabled(VALUE self)
|
|
235
247
|
Data_Get_Struct(self, struct Rev_Watcher, watcher_data);
|
236
248
|
|
237
249
|
return watcher_data->enabled ? Qtrue : Qfalse;
|
238
|
-
}
|
250
|
+
}
|
Binary file
|
data/lib/rev.rb
CHANGED
@@ -17,6 +17,6 @@ require File.dirname(__FILE__) + '/rev/server'
|
|
17
17
|
require File.dirname(__FILE__) + '/rev/http_client'
|
18
18
|
|
19
19
|
module Rev
|
20
|
-
Rev::VERSION = '0.1.
|
20
|
+
Rev::VERSION = '0.1.2' unless defined? Rev::VERSION
|
21
21
|
def self.version() VERSION end
|
22
22
|
end
|
data/lib/rev/buffered_io.rb
CHANGED
@@ -7,13 +7,21 @@
|
|
7
7
|
require File.dirname(__FILE__) + '/../rev'
|
8
8
|
|
9
9
|
module Rev
|
10
|
+
# A buffered I/O class witch fits into the Rev Watcher framework.
|
11
|
+
# It provides both an observer which reads data as it's received
|
12
|
+
# from the wire and a buffered writer which stores data and writes
|
13
|
+
# it out each time the socket becomes writable.
|
14
|
+
#
|
15
|
+
# This class is primarily meant as a base class for other streams
|
16
|
+
# which need non-blocking writing, and is used to implement Rev's
|
17
|
+
# Socket class and its associated subclasses.
|
10
18
|
class BufferedIO < IOWatcher
|
11
19
|
# Maximum number of bytes to consume at once
|
12
20
|
INPUT_SIZE = 16384
|
13
21
|
|
14
22
|
def initialize(io)
|
15
23
|
# Output buffer
|
16
|
-
@write_buffer =
|
24
|
+
@write_buffer = Rev::Buffer.new
|
17
25
|
|
18
26
|
# Coerce the argument into an IO object if possible
|
19
27
|
@io = IO.try_convert(io)
|
@@ -23,7 +31,7 @@ module Rev
|
|
23
31
|
#
|
24
32
|
# Callbacks for asynchronous events
|
25
33
|
#
|
26
|
-
|
34
|
+
|
27
35
|
# Called whenever the IO object receives data
|
28
36
|
def on_read(data); end
|
29
37
|
event_callback :on_read
|
@@ -42,23 +50,7 @@ module Rev
|
|
42
50
|
|
43
51
|
# Write data in a buffered, non-blocking manner
|
44
52
|
def write(data)
|
45
|
-
|
46
|
-
if @write_buffer.empty?
|
47
|
-
written = write_nonblock data
|
48
|
-
|
49
|
-
# If we lucked out and wrote out the whole buffer, return
|
50
|
-
if written == data.size
|
51
|
-
on_write_complete
|
52
|
-
return data.size
|
53
|
-
end
|
54
|
-
|
55
|
-
# Otherwise slice what we wrote out and begin buffered writing
|
56
|
-
data.slice!(0, written) if written
|
57
|
-
end
|
58
|
-
|
59
|
-
@write_buffer << data
|
60
|
-
schedule_write
|
61
|
-
data.size
|
53
|
+
buffered_write data
|
62
54
|
end
|
63
55
|
|
64
56
|
# Number of bytes are currently in the output buffer
|
@@ -73,19 +65,30 @@ module Rev
|
|
73
65
|
@io.close unless @io.closed?
|
74
66
|
|
75
67
|
on_close
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
|
71
|
+
# Is the IO object closed?
|
72
|
+
def closed?
|
73
|
+
@io.closed?
|
76
74
|
end
|
77
75
|
|
78
76
|
#########
|
79
77
|
protected
|
80
78
|
#########
|
81
79
|
|
80
|
+
# Buffered writer
|
81
|
+
def buffered_write(data)
|
82
|
+
@write_buffer << data
|
83
|
+
schedule_write
|
84
|
+
data.size
|
85
|
+
end
|
86
|
+
|
82
87
|
# Attempt to write the contents of the output buffer
|
83
88
|
def write_output_buffer
|
84
89
|
return if @write_buffer.empty?
|
85
90
|
|
86
|
-
|
87
|
-
@write_buffer.slice!(0, written) if written
|
88
|
-
|
91
|
+
@write_buffer.write_to(@io)
|
89
92
|
return unless @write_buffer.empty?
|
90
93
|
|
91
94
|
@writer.disable if @writer and @writer.enabled?
|
data/lib/rev/dns_resolver.rb
CHANGED
@@ -17,6 +17,17 @@ require File.dirname(__FILE__) + '/../rev'
|
|
17
17
|
#++
|
18
18
|
|
19
19
|
module Rev
|
20
|
+
# A non-blocking DNS resolver. It provides interfaces for querying both
|
21
|
+
# /etc/hosts and nameserves listed in /etc/resolv.conf, or nameservers of
|
22
|
+
# your choosing.
|
23
|
+
#
|
24
|
+
# Presently the client only supports UDP requests against your nameservers
|
25
|
+
# and cannot resolve anything with records larger than 512-bytes. Also,
|
26
|
+
# IPv6 is not presently supported.
|
27
|
+
#
|
28
|
+
# DNSResolver objects are one-shot. Once they resolve a domain name they
|
29
|
+
# automatically detach themselves from the event loop and cannot be used
|
30
|
+
# again.
|
20
31
|
class DNSResolver < IOWatcher
|
21
32
|
RESOLV_CONF = '/etc/resolv.conf'
|
22
33
|
HOSTS = '/etc/hosts'
|
@@ -25,9 +36,10 @@ module Rev
|
|
25
36
|
TIMEOUT = 3 # Retry timeout for each datagram sent
|
26
37
|
RETRIES = 4 # Number of retries to attempt
|
27
38
|
|
28
|
-
|
39
|
+
# Query /etc/hosts (or the specified hostfile) for the given host
|
40
|
+
def self.hosts(host, hostfile = HOSTS)
|
29
41
|
hosts = {}
|
30
|
-
File.open(
|
42
|
+
File.open(hostfile).each_line do |host_entry|
|
31
43
|
entries = host_entry.gsub(/#.*$/, '').gsub(/\s+/, ' ').split(' ')
|
32
44
|
addr = entries.shift
|
33
45
|
entries.each { |e| hosts[e] ||= addr }
|
@@ -36,6 +48,10 @@ module Rev
|
|
36
48
|
hosts[host]
|
37
49
|
end
|
38
50
|
|
51
|
+
# Create a new Rev::Watcher descended object to resolve the
|
52
|
+
# given hostname. If you so desire you can also specify a
|
53
|
+
# list of nameservers to query. By default the resolver will
|
54
|
+
# use nameservers listed in /etc/resolv.conf
|
39
55
|
def initialize(hostname, *nameservers)
|
40
56
|
if nameservers.empty?
|
41
57
|
nameservers = File.read(RESOLV_CONF).scan(/^\s*nameserver\s+([0-9.:]+)/).flatten
|
@@ -44,30 +60,26 @@ module Rev
|
|
44
60
|
|
45
61
|
@nameservers = nameservers
|
46
62
|
@question = request_question hostname
|
47
|
-
|
63
|
+
|
48
64
|
@socket = UDPSocket.new
|
49
65
|
@timer = Timeout.new(self)
|
50
66
|
|
51
67
|
super(@socket)
|
52
68
|
end
|
53
69
|
|
70
|
+
# Attach the DNSResolver to the given event loop
|
54
71
|
def attach(evloop)
|
55
72
|
send_request
|
56
73
|
@timer.attach(evloop)
|
57
74
|
super
|
58
75
|
end
|
59
76
|
|
77
|
+
# Detach the DNSResolver from the given event loop
|
60
78
|
def detach
|
61
79
|
@timer.detach if @timer.attached?
|
62
80
|
super
|
63
81
|
end
|
64
82
|
|
65
|
-
# Send a request to the DNS server
|
66
|
-
def send_request
|
67
|
-
@socket.connect @nameservers.first, DNS_PORT
|
68
|
-
@socket.send request_message, 0
|
69
|
-
end
|
70
|
-
|
71
83
|
# Called when the name has successfully resolved to an address
|
72
84
|
def on_success(address); end
|
73
85
|
event_callback :on_success
|
@@ -76,14 +88,19 @@ module Rev
|
|
76
88
|
def on_failure; end
|
77
89
|
event_callback :on_failure
|
78
90
|
|
79
|
-
# Called if we don't receive a response
|
80
|
-
|
81
|
-
event_callback :on_timeout
|
91
|
+
# Called if we don't receive a response, defaults to on_failure
|
92
|
+
alias_method :on_timeout, :on_failure
|
82
93
|
|
83
94
|
#########
|
84
95
|
protected
|
85
96
|
#########
|
86
97
|
|
98
|
+
# Send a request to the DNS server
|
99
|
+
def send_request
|
100
|
+
@socket.connect @nameservers.first, DNS_PORT
|
101
|
+
@socket.send request_message, 0
|
102
|
+
end
|
103
|
+
|
87
104
|
# Called by the subclass when the DNS response is available
|
88
105
|
def on_readable
|
89
106
|
datagram = @socket.recvfrom_nonblock(DATAGRAM_SIZE).first
|
@@ -169,11 +186,11 @@ module Rev
|
|
169
186
|
|
170
187
|
def on_timer
|
171
188
|
@attempts += 1
|
172
|
-
return @resolver.send_request if @attempts <= RETRIES
|
189
|
+
return @resolver.__send__(:send_request) if @attempts <= RETRIES
|
173
190
|
|
174
191
|
@resolver.__send__(:on_timeout)
|
175
192
|
@resolver.detach
|
176
193
|
end
|
177
194
|
end
|
178
195
|
end
|
179
|
-
end
|
196
|
+
end
|