rev 0.1.4 → 0.2.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/CHANGES ADDED
@@ -0,0 +1,102 @@
1
+ 0.2.0:
2
+
3
+ * Initial Ruby 1.8.6 support
4
+
5
+ * Omit Rev::LIBEV_VERSION constant
6
+
7
+ * Catch Errno::ECONNRESET when writing to sockets
8
+
9
+ * SSL support via Rev::SSL, with a small C extension subclassing Ruby's
10
+ OpenSSL::SSL::SSLSocket allowing for non-blocking SSL handshakes
11
+
12
+ * Initial Rev::Utils implementation with #ncpus and methods to query and
13
+ change the maximum number of file descriptors for the current process.
14
+
15
+ * Initial Rev::AsyncWatcher implementation for cross-thread signaling
16
+
17
+ * Handle unspecified Content-Length when encoding is identity in HttpClient
18
+
19
+ * Fix bug in HttpClient processing zero Content-Length
20
+
21
+ * Get rid of method_missing stuff in Rev::HttpClient
22
+
23
+ * Have Rev::HttpClient close the connection on error
24
+
25
+ * Allow Rev::TCPSocket#on_connect to be private when accepting connections
26
+ from a Rev::TCPServer
27
+
28
+ 0.1.4:
29
+
30
+ * Calibrate Rev::TimerWatchers against ev_time() and ev_now() when the watcher
31
+ is attached to the loop to ensure that the timeout interval is correct.
32
+
33
+ * Add check to ensure that a Rev::Loop cannot be run from within a callback
34
+
35
+ * Store Rev::Loop.default in a Thread-specific instance variable
36
+
37
+ * Upgrade libev to 0.3.0
38
+
39
+ * Rename BufferedIO to IO
40
+
41
+ * Fixed bug in BufferedIO#write_output_buffer causing it to spin endlessly on
42
+ an empty buffer.
43
+
44
+ * Added has_active_watchers? to Rev::Loop to check for active watchers
45
+
46
+ 0.1.3:
47
+
48
+ * Fixed bug in Rev::Buffer read_from and write_to: now rb_sys_fail on failed
49
+ reads/writes.
50
+
51
+ * Change Rev::Buffer memory pools to purge on a periodic interval, rather than
52
+ whenever the GC marks the object.
53
+
54
+ * Fix bug in tracking the active watcher count. Factor shared watcher behavior
55
+ from rev_watcher.h to rev_watcher.c.
56
+
57
+ 0.1.2:
58
+
59
+ * Commit initial specs
60
+
61
+ * Improve RDoc for the library
62
+
63
+ * Eliminate "zero copy" writes as they bypass the event loop
64
+
65
+ * Added Rev::Buffer C extension to provide high speed buffered writes
66
+
67
+ * Implement Rev::TCPSocket#peeraddr to improve compatibility with Ruby sockets
68
+
69
+ * Added Rev::Listener.close for clean shutdown of a listener
70
+
71
+ * Rev::Loop.default used to call ev_loop_default() (in C). However, this
72
+ registers signal handlers which conflict with Ruby's own. Now the behavior
73
+ has been changed to return a thread-local singleton of Rev::Loop.
74
+
75
+ * Creating a new Rev::TCPListener will disable reverse lookups in BasicSocket
76
+
77
+ * Made backlog for Rev::TCPListener user-definable
78
+
79
+ * Rev::TCPSocket now implements an on_resolve_failed callback for failed DNS
80
+ resolution. By default it's aliased to on_connect_failed.
81
+
82
+ * Changed event_callbacks to use instance_exec rather than passing the
83
+ watcher object as an argument. Documented use of defining an event
84
+ callback as a block
85
+
86
+ * Subsecond precision for Rev::TimerWatchers
87
+
88
+ 0.1.1:
89
+
90
+ * Added Rev::HttpClient, an asynchronous HTTP/1.1 client written on top of
91
+ the Rev::TCPSocket class
92
+
93
+ * Imported HTTP response parser from the RFuzz project
94
+
95
+ * Added exception handling for Errno::ECONNRESET and Errno::EAGAIN
96
+
97
+ * Fixed bugs in buffered writer which resulted in exceptions if all data
98
+ couldn't be written with a nonblocking write.
99
+
100
+ 0.1.0:
101
+
102
+ * Initial public release
data/README CHANGED
@@ -1,9 +1,9 @@
1
1
  = Rev
2
2
 
3
- Rev is a high performance event library for Ruby 1.9. It uses the libev C
4
- library to handle support for underlying system calls. This includes the
5
- epoll system call for Linux, the kqueue system call for BSDs and OS X, and the
6
- completion ports interface for Solaris.
3
+ Rev is an event library for Ruby, built on the libev event library which
4
+ provides a cross-platform interface to high performance system calls . This
5
+ includes the epoll system call for Linux, the kqueue system call for BSDs and
6
+ OS X, and the completion ports interface for Solaris.
7
7
 
8
8
  Rev also binds asynchronous wrappers to Ruby's core socket classes so you can
9
9
  use them in conjunction with Rev to build asynchronous event-driven
@@ -120,7 +120,7 @@ haven't overridden them in a subclass). This is especially useful for small
120
120
  one off programs or just experimenting with the API.
121
121
 
122
122
  Any callback (methods prefixed with on_*) can be set on the fly by passing it
123
- a block.
123
+ a block. (NOTE: Ruby 1.9 only)
124
124
 
125
125
  Below is an example of using this syntax. It implements an echo server
126
126
  identical to the one above:
@@ -0,0 +1,70 @@
1
+ require 'rake'
2
+ require 'rake/clean'
3
+ require 'rake/rdoctask'
4
+ require 'rake/gempackagetask'
5
+ require 'fileutils'
6
+ include FileUtils
7
+
8
+ # Load Rev Gemspec
9
+ load 'rev.gemspec'
10
+
11
+ # Default Rake task is compile
12
+ task :default => :compile
13
+
14
+ # RDoc
15
+ Rake::RDocTask.new(:rdoc) do |task|
16
+ task.rdoc_dir = 'doc'
17
+ task.title = 'Rev'
18
+ task.options = %w(--title Revactor --main README --line-numbers)
19
+ task.rdoc_files.include(['ext/rev/*.c', 'lib/**/*.rb'])
20
+ task.rdoc_files.include(['README', 'LICENSE'])
21
+ end
22
+
23
+ # Gem
24
+ Rake::GemPackageTask.new(GEMSPEC) do |pkg|
25
+ pkg.need_tar = true
26
+ end
27
+
28
+ def make(makedir)
29
+ Dir.chdir(makedir) { sh 'make' }
30
+ end
31
+
32
+ def extconf(dir)
33
+ Dir.chdir(dir) { ruby "extconf.rb" }
34
+ end
35
+
36
+ def setup_extension(dir, extension)
37
+ ext = "ext/#{dir}"
38
+ ext_so = "#{ext}/#{extension}.#{Config::CONFIG['DLEXT']}"
39
+ ext_files = FileList[
40
+ "#{ext}/*.c",
41
+ "#{ext}/*.h",
42
+ "#{ext}/extconf.rb",
43
+ "#{ext}/Makefile",
44
+ "lib"
45
+ ]
46
+
47
+ task "lib" do
48
+ directory "lib"
49
+ end
50
+
51
+ desc "Builds just the #{extension} extension"
52
+ task extension.to_sym => ["#{ext}/Makefile", ext_so ]
53
+
54
+ file "#{ext}/Makefile" => ["#{ext}/extconf.rb"] do
55
+ extconf "#{ext}"
56
+ end
57
+
58
+ file ext_so => ext_files do
59
+ make "#{ext}"
60
+ cp ext_so, "lib"
61
+ end
62
+ end
63
+
64
+ setup_extension("rev", "rev_ext")
65
+ setup_extension("http11_client", "http11_client")
66
+
67
+ task :compile => [:rev_ext, :http11_client]
68
+
69
+ CLEAN.include ['build/*', '**/*.o', '**/*.so', '**/*.a', '**/*.log', 'pkg']
70
+ CLEAN.include ['ext/rev/Makefile', 'lib/rev_ext.*', 'lib/http11_client.*']
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + '/../lib/rev'
2
+
3
+ ADDR = '127.0.0.1'
4
+ PORT = 4321
5
+
6
+ class EchoServerConnection < Rev::TCPSocket
7
+ def on_connect
8
+ puts "#{remote_addr}:#{remote_port} connected"
9
+ end
10
+
11
+ def on_close
12
+ puts "#{remote_addr}:#{remote_port} disconnected"
13
+ end
14
+
15
+ def on_read(data)
16
+ write data
17
+ end
18
+ end
19
+
20
+ event_loop = Rev::Loop.default
21
+ Rev::TCPServer.new(ADDR, PORT, EchoServerConnection).attach(event_loop)
22
+
23
+ puts "Echo server listening on #{ADDR}:#{PORT}"
24
+ event_loop.run
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Copyright (c) 2005 Zed A. Shaw
3
+ * You can redistribute it and/or modify it under the same terms as Ruby.
4
+ */
5
+
6
+ #include "http11_parser.h"
7
+ #include <stdio.h>
8
+ #include <assert.h>
9
+ #include <stdlib.h>
10
+ #include <ctype.h>
11
+ #include <string.h>
12
+
13
+ #define LEN(AT, FPC) (FPC - buffer - parser->AT)
14
+ #define MARK(M,FPC) (parser->M = (FPC) - buffer)
15
+ #define PTR_TO(F) (buffer + parser->F)
16
+ #define L(M) fprintf(stderr, "" # M "\n");
17
+
18
+
19
+ /** machine **/
20
+ %%{
21
+ machine httpclient_parser;
22
+
23
+ action mark {MARK(mark, fpc); }
24
+
25
+ action start_field { MARK(field_start, fpc); }
26
+
27
+ action write_field {
28
+ parser->field_len = LEN(field_start, fpc);
29
+ }
30
+
31
+ action start_value { MARK(mark, fpc); }
32
+
33
+ action write_value {
34
+ parser->http_field(parser->data, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, fpc));
35
+ }
36
+
37
+ action reason_phrase {
38
+ parser->reason_phrase(parser->data, PTR_TO(mark), LEN(mark, fpc));
39
+ }
40
+
41
+ action status_code {
42
+ parser->status_code(parser->data, PTR_TO(mark), LEN(mark, fpc));
43
+ }
44
+
45
+ action http_version {
46
+ parser->http_version(parser->data, PTR_TO(mark), LEN(mark, fpc));
47
+ }
48
+
49
+ action chunk_size {
50
+ parser->chunk_size(parser->data, PTR_TO(mark), LEN(mark, fpc));
51
+ }
52
+
53
+ action last_chunk {
54
+ parser->last_chunk(parser->data, NULL, 0);
55
+ }
56
+
57
+ action done {
58
+ parser->body_start = fpc - buffer + 1;
59
+ if(parser->header_done != NULL)
60
+ parser->header_done(parser->data, fpc + 1, pe - fpc - 1);
61
+ fbreak;
62
+ }
63
+
64
+ # line endings
65
+ CRLF = "\r\n";
66
+
67
+ # character types
68
+ CTL = (cntrl | 127);
69
+ tspecials = ("(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | "\"" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | " " | "\t");
70
+
71
+ # elements
72
+ token = (ascii -- (CTL | tspecials));
73
+
74
+ Reason_Phrase = (any -- CRLF)+ >mark %reason_phrase;
75
+ Status_Code = digit+ >mark %status_code;
76
+ http_number = (digit+ "." digit+) ;
77
+ HTTP_Version = ("HTTP/" http_number) >mark %http_version ;
78
+ Status_Line = HTTP_Version " " Status_Code " " Reason_Phrase :> CRLF;
79
+
80
+ field_name = token+ >start_field %write_field;
81
+ field_value = any* >start_value %write_value;
82
+ message_header = field_name ":" " "* field_value :> CRLF;
83
+
84
+ Response = Status_Line (message_header)* (CRLF @done);
85
+
86
+ chunk_ext_val = token+;
87
+ chunk_ext_name = token+;
88
+ chunk_extension = (";" chunk_ext_name >start_field %write_field %start_value ("=" chunk_ext_val >start_value)? %write_value )*;
89
+ last_chunk = "0"? chunk_extension :> (CRLF @last_chunk @done);
90
+ chunk_size = xdigit+;
91
+ chunk = chunk_size >mark %chunk_size chunk_extension :> (CRLF @done);
92
+ Chunked_Header = (chunk | last_chunk);
93
+
94
+ main := Response | Chunked_Header;
95
+ }%%
96
+
97
+ /** Data **/
98
+ %% write data;
99
+
100
+ int httpclient_parser_init(httpclient_parser *parser) {
101
+ int cs = 0;
102
+ %% write init;
103
+ parser->cs = cs;
104
+ parser->body_start = 0;
105
+ parser->content_len = 0;
106
+ parser->mark = 0;
107
+ parser->nread = 0;
108
+ parser->field_len = 0;
109
+ parser->field_start = 0;
110
+
111
+ return(1);
112
+ }
113
+
114
+
115
+ /** exec **/
116
+ size_t httpclient_parser_execute(httpclient_parser *parser, const char *buffer, size_t len, size_t off) {
117
+ const char *p, *pe;
118
+ int cs = parser->cs;
119
+
120
+ assert(off <= len && "offset past end of buffer");
121
+
122
+ p = buffer+off;
123
+ pe = buffer+len;
124
+
125
+ assert(*pe == '\0' && "pointer does not end on NUL");
126
+ assert(pe - p == len - off && "pointers aren't same distance");
127
+
128
+
129
+ %% write exec;
130
+
131
+ parser->cs = cs;
132
+ parser->nread += p - (buffer + off);
133
+
134
+ assert(p <= pe && "buffer overflow after parsing execute");
135
+ assert(parser->nread <= len && "nread longer than length");
136
+ assert(parser->body_start <= len && "body starts after buffer end");
137
+ assert(parser->mark < len && "mark is after buffer end");
138
+ assert(parser->field_len <= len && "field has length longer than whole buffer");
139
+ assert(parser->field_start < len && "field starts after buffer end");
140
+
141
+ if(parser->body_start) {
142
+ /* final \r\n combo encountered so stop right here */
143
+ %%write eof;
144
+ parser->nread++;
145
+ }
146
+
147
+ return(parser->nread);
148
+ }
149
+
150
+ int httpclient_parser_finish(httpclient_parser *parser)
151
+ {
152
+ int cs = parser->cs;
153
+
154
+ %%write eof;
155
+
156
+ parser->cs = cs;
157
+
158
+ if (httpclient_parser_has_error(parser) ) {
159
+ return -1;
160
+ } else if (httpclient_parser_is_finished(parser) ) {
161
+ return 1;
162
+ } else {
163
+ return 0;
164
+ }
165
+ }
166
+
167
+ int httpclient_parser_has_error(httpclient_parser *parser) {
168
+ return parser->cs == httpclient_parser_error;
169
+ }
170
+
171
+ int httpclient_parser_is_finished(httpclient_parser *parser) {
172
+ return parser->cs == httpclient_parser_first_final;
173
+ }
@@ -0,0 +1,40 @@
1
+ Revision history for libev, a high-performance and full-featured event loop
2
+
3
+ 3.0 Mon Jan 28 13:14:47 CET 2008
4
+ - API/ABI bump to version 3.0.
5
+ - ev++.h includes "ev.h" by default now, not <ev.h>.
6
+ - slightly improved documentation.
7
+ - speed up signal detection after a fork.
8
+ - only optionally return trace status changed in ev_child
9
+ watchers.
10
+ - experimental (and undocumented) loop wrappers for ev++.h.
11
+
12
+ 2.01 Tue Dec 25 08:04:41 CET 2007
13
+ - separate Changes file.
14
+ - fix ev_path_set => ev_stat_set typo.
15
+ - remove event_compat.h from the libev tarball.
16
+ - change how include files are found.
17
+ - doc updates.
18
+ - update licenses, explicitly allow for GPL relicensing.
19
+
20
+ 2.0 Sat Dec 22 17:47:03 CET 2007
21
+ - new ev_sleep, ev_set_(io|timeout)_collect_interval.
22
+ - removed epoll from embeddable fd set.
23
+ - fix embed watchers.
24
+ - renamed ev_embed.loop to other.
25
+ - added exported Symbol tables.
26
+ - undefine member wrapper macros at the end of ev.c.
27
+ - respect EV_H in ev++.h.
28
+
29
+ 1.86 Tue Dec 18 02:36:57 CET 2007
30
+ - fix memleak on loop destroy (not relevant for perl).
31
+
32
+ 1.85 Fri Dec 14 20:32:40 CET 2007
33
+ - fix some aliasing issues w.r.t. timers and periodics
34
+ (not relevant for perl).
35
+
36
+ (for historic versions refer to EV/Changes, found in the Perl interface)
37
+
38
+ 0.1 Wed Oct 31 21:31:48 CET 2007
39
+ - original version; hacked together in <24h.
40
+
@@ -0,0 +1,25 @@
1
+ All files in libev are Copyright (C)2007 Marc Alexander Lehmann.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions are
5
+ met:
6
+
7
+ * Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above
11
+ copyright notice, this list of conditions and the following
12
+ disclaimer in the documentation and/or other materials provided
13
+ with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.