rev 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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.