rev 0.1.1 → 0.1.2
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/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
|