rev 0.2.2 → 0.2.3
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 +11 -0
- data/README +10 -3
- data/Rakefile +2 -2
- data/examples/echo_client.rb +35 -0
- data/examples/google.rb +8 -0
- data/examples/httpclient.rb +35 -0
- data/ext/http11_client/Makefile +149 -0
- data/ext/http11_client/http11_client.bundle +0 -0
- data/ext/http11_client/http11_client.o +0 -0
- data/ext/http11_client/http11_parser.o +0 -0
- data/ext/http11_client/mkmf.log +12 -0
- data/ext/libev/Changes +114 -1
- data/ext/libev/ev.c +212 -97
- data/ext/libev/ev.h +13 -7
- data/ext/libev/ev_epoll.c +44 -11
- data/ext/libev/ev_kqueue.c +2 -2
- data/ext/libev/ev_poll.c +3 -1
- data/ext/libev/ev_port.c +4 -4
- data/ext/libev/ev_select.c +58 -19
- data/ext/libev/ev_vars.h +5 -1
- data/ext/libev/ev_win32.c +32 -3
- data/ext/libev/ev_wrap.h +4 -0
- data/ext/libev/test_libev_win32.c +123 -0
- data/ext/libev/update_ev_wrap +0 -0
- data/ext/rev/Makefile +149 -0
- data/ext/rev/ev_wrap.h +8 -0
- data/ext/rev/extconf.rb +17 -0
- data/ext/rev/libev.c +8 -0
- data/ext/rev/libev.o +0 -0
- data/ext/rev/mkmf.log +221 -0
- data/ext/rev/rev.h +8 -2
- data/ext/rev/rev_buffer.c +2 -3
- data/ext/rev/rev_buffer.o +0 -0
- data/ext/rev/rev_ext.bundle +0 -0
- data/ext/rev/rev_ext.c +4 -3
- data/ext/rev/rev_ext.o +0 -0
- data/ext/rev/rev_io_watcher.c +1 -2
- data/ext/rev/rev_io_watcher.o +0 -0
- data/ext/rev/rev_loop.c +4 -4
- data/ext/rev/rev_loop.o +0 -0
- data/ext/rev/rev_ssl.o +0 -0
- data/ext/rev/rev_timer_watcher.c +1 -2
- data/ext/rev/rev_timer_watcher.o +0 -0
- data/ext/rev/rev_utils.c +14 -0
- data/ext/rev/rev_utils.o +0 -0
- data/ext/rev/rev_watcher.c +7 -6
- data/ext/rev/rev_watcher.o +0 -0
- data/lib/http11_client.bundle +0 -0
- data/lib/rev.rb +1 -1
- data/lib/rev/dns_resolver.rb +29 -9
- data/lib/rev/io.rb +6 -4
- data/lib/rev/listener.rb +5 -1
- data/lib/rev/loop.rb +8 -4
- data/lib/rev/server.rb +3 -2
- data/lib/rev/socket.rb +14 -5
- data/lib/rev_ext.bundle +0 -0
- data/lib/revem.rb +210 -0
- data/rev.gemspec +2 -2
- metadata +29 -3
    
        data/ext/rev/rev.h
    CHANGED
    
    | @@ -10,10 +10,16 @@ | |
| 10 10 | 
             
            #include "ruby.h"
         | 
| 11 11 | 
             
            #include "rubyio.h"
         | 
| 12 12 |  | 
| 13 | 
            -
            # | 
| 14 | 
            -
            #define FPTR_TO_FD(fptr) fptr | 
| 13 | 
            +
            #ifdef GetReadFile
         | 
| 14 | 
            +
            #define FPTR_TO_FD(fptr) (fileno(GetReadFile(fptr)))
         | 
| 15 15 | 
             
            #else
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            #if !HAVE_RB_IO_T || (RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8)
         | 
| 16 18 | 
             
            #define FPTR_TO_FD(fptr) fileno(fptr->f)
         | 
| 19 | 
            +
            #else
         | 
| 20 | 
            +
            #define FPTR_TO_FD(fptr) fptr->fd
         | 
| 21 | 
            +
            #endif
         | 
| 22 | 
            +
             | 
| 17 23 | 
             
            #endif
         | 
| 18 24 |  | 
| 19 25 | 
             
            struct Rev_Event
         | 
    
        data/ext/rev/rev_buffer.c
    CHANGED
    
    | @@ -7,8 +7,7 @@ | |
| 7 7 | 
             
            #include "ruby.h"
         | 
| 8 8 | 
             
            #include "rubyio.h"
         | 
| 9 9 |  | 
| 10 | 
            -
            # | 
| 11 | 
            -
            #include "../libev/ev.h"
         | 
| 10 | 
            +
            #include "ev_wrap.h"
         | 
| 12 11 |  | 
| 13 12 | 
             
            #include "rev.h"
         | 
| 14 13 |  | 
| @@ -627,4 +626,4 @@ static int buffer_read_from(struct buffer *buf, int fd) | |
| 627 626 | 
             
            	} while(bytes_read == nbytes);
         | 
| 628 627 |  | 
| 629 628 | 
             
            	return total_bytes_read;
         | 
| 630 | 
            -
            }
         | 
| 629 | 
            +
            }
         | 
| Binary file | 
| Binary file | 
    
        data/ext/rev/rev_ext.c
    CHANGED
    
    | @@ -4,10 +4,11 @@ | |
| 4 4 | 
             
             * See LICENSE for details
         | 
| 5 5 | 
             
             */
         | 
| 6 6 |  | 
| 7 | 
            -
            #include "ruby.h"
         | 
| 8 7 |  | 
| 9 | 
            -
            # | 
| 10 | 
            -
             | 
| 8 | 
            +
            #include "ruby.h" // allow for an error "OpenFile redeclared" to not exist, somehow.
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            #include "ev_wrap.h"
         | 
| 11 | 
            +
             | 
| 11 12 |  | 
| 12 13 | 
             
            #include "rev.h"
         | 
| 13 14 |  | 
    
        data/ext/rev/rev_ext.o
    ADDED
    
    | Binary file | 
    
        data/ext/rev/rev_io_watcher.c
    CHANGED
    
    
| Binary file | 
    
        data/ext/rev/rev_loop.c
    CHANGED
    
    | @@ -8,8 +8,7 @@ | |
| 8 8 | 
             
            #include "ruby.h"
         | 
| 9 9 | 
             
            #include "rubysig.h"
         | 
| 10 10 |  | 
| 11 | 
            -
            # | 
| 12 | 
            -
            #include "../libev/ev.h"
         | 
| 11 | 
            +
            #include "ev_wrap.h"
         | 
| 13 12 |  | 
| 14 13 | 
             
            #include "rev.h"
         | 
| 15 14 |  | 
| @@ -208,7 +207,7 @@ static VALUE Rev_Loop_ev_loop_oneshot_blocking(void *ptr) | |
| 208 207 | 
             
            static void Rev_Loop_ev_loop_oneshot(struct Rev_Loop *loop_data)
         | 
| 209 208 | 
             
            {
         | 
| 210 209 | 
             
              /* Use Ruby 1.9's rb_thread_blocking_region call to make a blocking system call */
         | 
| 211 | 
            -
              rb_thread_blocking_region(Rev_Loop_ev_loop_oneshot_blocking, loop_data,  | 
| 210 | 
            +
              rb_thread_blocking_region(Rev_Loop_ev_loop_oneshot_blocking, loop_data, RUBY_UBF_IO, 0);
         | 
| 212 211 | 
             
            }
         | 
| 213 212 | 
             
            #endif
         | 
| 214 213 |  | 
| @@ -220,6 +219,7 @@ static void Rev_Loop_ev_loop_oneshot(struct Rev_Loop *loop_data) | |
| 220 219 | 
             
            /* Stub for scheduler's ev_timer callback */
         | 
| 221 220 | 
             
            static void timer_callback(struct ev_loop *ev_loop, struct ev_timer *timer, int revents)
         | 
| 222 221 | 
             
            {
         | 
| 222 | 
            +
               ev_timer_again (ev_loop, timer);
         | 
| 223 223 | 
             
            }
         | 
| 224 224 |  | 
| 225 225 | 
             
            /* Run the event loop, calling rb_thread_schedule every 10ms */
         | 
| @@ -284,4 +284,4 @@ static void Rev_Loop_dispatch_events(struct Rev_Loop *loop_data) | |
| 284 284 | 
             
                Data_Get_Struct(loop_data->eventbuf[i].watcher, struct Rev_Watcher, watcher_data);
         | 
| 285 285 | 
             
                watcher_data->dispatch_callback(loop_data->eventbuf[i].watcher, loop_data->eventbuf[i].revents);
         | 
| 286 286 | 
             
              }
         | 
| 287 | 
            -
            }
         | 
| 287 | 
            +
            }
         | 
    
        data/ext/rev/rev_loop.o
    ADDED
    
    | Binary file | 
    
        data/ext/rev/rev_ssl.o
    ADDED
    
    | Binary file | 
    
        data/ext/rev/rev_timer_watcher.c
    CHANGED
    
    
| Binary file | 
    
        data/ext/rev/rev_utils.c
    CHANGED
    
    | @@ -6,7 +6,9 @@ | |
| 6 6 |  | 
| 7 7 | 
             
            #include "ruby.h"
         | 
| 8 8 |  | 
| 9 | 
            +
            #ifdef HAVE_SYS_RESOURCE_H
         | 
| 9 10 | 
             
            #include <sys/resource.h>
         | 
| 11 | 
            +
            #endif
         | 
| 10 12 |  | 
| 11 13 | 
             
            #ifdef HAVE_SYS_SYSCTL_H
         | 
| 12 14 | 
             
            #include <sys/param.h>
         | 
| @@ -80,12 +82,18 @@ static VALUE Rev_Utils_ncpus(VALUE self) | |
| 80 82 | 
             
             */
         | 
| 81 83 | 
             
            static VALUE Rev_Utils_maxfds(VALUE self)
         | 
| 82 84 | 
             
            {
         | 
| 85 | 
            +
            #ifdef HAVE_SYS_RESOURCE_H
         | 
| 83 86 | 
             
              struct rlimit rlim;
         | 
| 84 87 |  | 
| 85 88 | 
             
              if(getrlimit(RLIMIT_NOFILE, &rlim) < 0)
         | 
| 86 89 | 
             
                rb_sys_fail("getrlimit");
         | 
| 87 90 |  | 
| 88 91 | 
             
              return INT2NUM(rlim.rlim_cur);
         | 
| 92 | 
            +
            #endif
         | 
| 93 | 
            +
             | 
| 94 | 
            +
            #ifndef HAVE_SYS_RESOURCE_H
         | 
| 95 | 
            +
              rb_raise(rb_eRuntimeError, "operation not supported");
         | 
| 96 | 
            +
            #endif
         | 
| 89 97 | 
             
            }
         | 
| 90 98 |  | 
| 91 99 | 
             
            /**
         | 
| @@ -97,6 +105,7 @@ static VALUE Rev_Utils_maxfds(VALUE self) | |
| 97 105 | 
             
             */
         | 
| 98 106 | 
             
            static VALUE Rev_Utils_setmaxfds(VALUE self, VALUE max)
         | 
| 99 107 | 
             
            {
         | 
| 108 | 
            +
            #ifdef HAVE_SYS_RESOURCE_H
         | 
| 100 109 | 
             
              struct rlimit rlim;
         | 
| 101 110 |  | 
| 102 111 | 
             
              rlim.rlim_cur = NUM2INT(max);
         | 
| @@ -105,4 +114,9 @@ static VALUE Rev_Utils_setmaxfds(VALUE self, VALUE max) | |
| 105 114 | 
             
                rb_sys_fail("setrlimit");
         | 
| 106 115 |  | 
| 107 116 | 
             
              return max;
         | 
| 117 | 
            +
            #endif
         | 
| 118 | 
            +
             | 
| 119 | 
            +
            #ifndef HAVE_SYS_RESOURCE_H
         | 
| 120 | 
            +
              rb_raise(rb_eRuntimeError, "operation not supported");
         | 
| 121 | 
            +
            #endif
         | 
| 108 122 | 
             
            }
         | 
    
        data/ext/rev/rev_utils.o
    ADDED
    
    | Binary file | 
    
        data/ext/rev/rev_watcher.c
    CHANGED
    
    | @@ -6,8 +6,7 @@ | |
| 6 6 |  | 
| 7 7 | 
             
            #include "ruby.h"
         | 
| 8 8 |  | 
| 9 | 
            -
            # | 
| 10 | 
            -
            #include "../libev/ev.h"
         | 
| 9 | 
            +
            #include "ev_wrap.h"
         | 
| 11 10 |  | 
| 12 11 | 
             
            #include "rev.h"
         | 
| 13 12 |  | 
| @@ -99,7 +98,8 @@ static VALUE Rev_Watcher_attach(VALUE self, VALUE loop) | |
| 99 98 | 
             
              loop_watchers = rb_iv_get(loop, "@watchers");
         | 
| 100 99 |  | 
| 101 100 | 
             
              if(loop_watchers == Qnil) {
         | 
| 102 | 
            -
                 | 
| 101 | 
            +
                /* we should never get here */
         | 
| 102 | 
            +
                loop_watchers = rb_hash_new();
         | 
| 103 103 | 
             
                rb_iv_set(loop, "@watchers", loop_watchers);
         | 
| 104 104 | 
             
              }
         | 
| 105 105 |  | 
| @@ -108,7 +108,7 @@ static VALUE Rev_Watcher_attach(VALUE self, VALUE loop) | |
| 108 108 | 
             
               * with a loop (and also lets you see within Ruby which watchers are
         | 
| 109 109 | 
             
               * associated with a given loop), but isn't really necessary for any 
         | 
| 110 110 | 
             
               * other reason */
         | 
| 111 | 
            -
               | 
| 111 | 
            +
              rb_hash_aset(loop_watchers, self, Qtrue);
         | 
| 112 112 |  | 
| 113 113 | 
             
              active_watchers = rb_iv_get(loop, "@active_watchers");
         | 
| 114 114 | 
             
              if(active_watchers == Qnil)
         | 
| @@ -142,8 +142,9 @@ static VALUE Rev_Watcher_detach(VALUE self) | |
| 142 142 |  | 
| 143 143 | 
             
              /* Remove us from the loop's array of active watchers.  This likely
         | 
| 144 144 | 
             
               * has negative performance and scalability characteristics as this
         | 
| 145 | 
            -
               * isn't an O(1) operation.  Hopefully there's a better way... | 
| 146 | 
            -
             | 
| 145 | 
            +
               * isn't an O(1) operation.  Hopefully there's a better way...
         | 
| 146 | 
            +
               * Trying a hash for now... */
         | 
| 147 | 
            +
              rb_hash_delete(loop_watchers, self);
         | 
| 147 148 |  | 
| 148 149 | 
             
              if(watcher_data->enabled) {
         | 
| 149 150 | 
             
                rb_iv_set(
         | 
| Binary file | 
| Binary file | 
    
        data/lib/rev.rb
    CHANGED
    
    | @@ -24,6 +24,6 @@ require File.dirname(__FILE__) + '/rev/server' | |
| 24 24 | 
             
            require File.dirname(__FILE__) + '/rev/http_client'
         | 
| 25 25 |  | 
| 26 26 | 
             
            module Rev
         | 
| 27 | 
            -
              Rev::VERSION = '0.2. | 
| 27 | 
            +
              Rev::VERSION = '0.2.3' unless defined? Rev::VERSION
         | 
| 28 28 | 
             
              def self.version() VERSION end
         | 
| 29 29 | 
             
            end
         | 
    
        data/lib/rev/dns_resolver.rb
    CHANGED
    
    | @@ -11,7 +11,6 @@ | |
| 11 11 | 
             
            #
         | 
| 12 12 | 
             
            # If you do know what you're doing with DNS, feel free to improve this! 
         | 
| 13 13 | 
             
            #++
         | 
| 14 | 
            -
             | 
| 15 14 | 
             
            module Rev
         | 
| 16 15 | 
             
              # A non-blocking DNS resolver.  It provides interfaces for querying both
         | 
| 17 16 | 
             
              # /etc/hosts and nameserves listed in /etc/resolv.conf, or nameservers of
         | 
| @@ -25,12 +24,16 @@ module Rev | |
| 25 24 | 
             
              # automatically detach themselves from the event loop and cannot be used
         | 
| 26 25 | 
             
              # again.
         | 
| 27 26 | 
             
              class DNSResolver < IOWatcher
         | 
| 27 | 
            +
               #--
         | 
| 28 | 
            +
               # TODO check if it's caching right
         | 
| 28 29 | 
             
                RESOLV_CONF = '/etc/resolv.conf'
         | 
| 29 30 | 
             
                HOSTS = '/etc/hosts'
         | 
| 30 31 | 
             
                DNS_PORT = 53
         | 
| 31 32 | 
             
                DATAGRAM_SIZE = 512
         | 
| 32 33 | 
             
                TIMEOUT = 3 # Retry timeout for each datagram sent
         | 
| 33 34 | 
             
                RETRIES = 4 # Number of retries to attempt
         | 
| 35 | 
            +
                # so currently total is 12s before it will err due to timeouts
         | 
| 36 | 
            +
                # if it errs due to inability to reach the DNS server [Errno::EHOSTUNREACH], same
         | 
| 34 37 |  | 
| 35 38 | 
             
                # Query /etc/hosts (or the specified hostfile) for the given host
         | 
| 36 39 | 
             
                def self.hosts(host, hostfile = HOSTS)
         | 
| @@ -50,8 +53,8 @@ module Rev | |
| 50 53 | 
             
                # use nameservers listed in /etc/resolv.conf
         | 
| 51 54 | 
             
                def initialize(hostname, *nameservers)
         | 
| 52 55 | 
             
                  if nameservers.empty?
         | 
| 53 | 
            -
                    nameservers = File.read(RESOLV_CONF).scan(/^\s*nameserver\s+([0-9.:]+)/).flatten
         | 
| 54 | 
            -
                    raise RuntimeError, "no nameservers found in #{RESOLV_CONF}" if nameservers.empty?
         | 
| 56 | 
            +
                    nameservers = File.read(RESOLV_CONF).scan(/^\s*nameserver\s+([0-9.:]+)/).flatten # TODO could optimize this to just read once
         | 
| 57 | 
            +
                    raise RuntimeError, "no nameservers found in #{RESOLV_CONF}" if nameservers.empty? # TODO just call resolve_failed, not raise [also handle Errno::ENOENT)]
         | 
| 55 58 | 
             
                  end
         | 
| 56 59 |  | 
| 57 60 | 
             
                  @nameservers = nameservers
         | 
| @@ -84,8 +87,10 @@ module Rev | |
| 84 87 | 
             
                def on_failure; end
         | 
| 85 88 | 
             
                event_callback :on_failure
         | 
| 86 89 |  | 
| 87 | 
            -
                # Called if we don't receive a response, defaults to on_failure
         | 
| 88 | 
            -
                 | 
| 90 | 
            +
                # Called if we don't receive a response, defaults to calling on_failure
         | 
| 91 | 
            +
                def on_timeout
         | 
| 92 | 
            +
            	on_failure
         | 
| 93 | 
            +
                end
         | 
| 89 94 |  | 
| 90 95 | 
             
                #########
         | 
| 91 96 | 
             
                protected
         | 
| @@ -93,13 +98,23 @@ module Rev | |
| 93 98 |  | 
| 94 99 | 
             
                # Send a request to the DNS server
         | 
| 95 100 | 
             
                def send_request
         | 
| 101 | 
            +
                  nameserver = @nameservers.shift
         | 
| 102 | 
            +
                  @nameservers << nameserver # rotate them
         | 
| 96 103 | 
             
                  @socket.connect @nameservers.first, DNS_PORT
         | 
| 97 | 
            -
                   | 
| 104 | 
            +
                  begin
         | 
| 105 | 
            +
                     @socket.send request_message, 0
         | 
| 106 | 
            +
                  rescue Errno::EHOSTUNREACH # TODO figure out why it has to be wrapper here, when the other wrapper should be wrapping this one!
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                  end   
         | 
| 98 109 | 
             
                end
         | 
| 99 110 |  | 
| 100 111 | 
             
                # Called by the subclass when the DNS response is available
         | 
| 101 112 | 
             
                def on_readable
         | 
| 102 | 
            -
                  datagram =  | 
| 113 | 
            +
                  datagram = nil
         | 
| 114 | 
            +
                  begin
         | 
| 115 | 
            +
            	datagram = @socket.recvfrom_nonblock(DATAGRAM_SIZE).first
         | 
| 116 | 
            +
                  rescue Errno::ECONNREFUSED
         | 
| 117 | 
            +
                  end
         | 
| 103 118 | 
             
                  address = response_address datagram rescue nil
         | 
| 104 119 | 
             
                  address ? on_success(address) : on_failure
         | 
| 105 120 | 
             
                  detach
         | 
| @@ -184,8 +199,13 @@ module Rev | |
| 184 199 |  | 
| 185 200 | 
             
                  def on_timer
         | 
| 186 201 | 
             
                    @attempts += 1
         | 
| 187 | 
            -
                     | 
| 188 | 
            -
             | 
| 202 | 
            +
                    if @attempts <= RETRIES
         | 
| 203 | 
            +
                      begin
         | 
| 204 | 
            +
                        return @resolver.__send__(:send_request)
         | 
| 205 | 
            +
                      rescue Errno::EHOSTUNREACH # if the DNS is toast try again after the timeout occurs again
         | 
| 206 | 
            +
                        return nil
         | 
| 207 | 
            +
                      end 
         | 
| 208 | 
            +
                    end
         | 
| 189 209 | 
             
                    @resolver.__send__(:on_timeout)
         | 
| 190 210 | 
             
                    @resolver.detach
         | 
| 191 211 | 
             
                  end
         | 
    
        data/lib/rev/io.rb
    CHANGED
    
    | @@ -21,7 +21,7 @@ module Rev | |
| 21 21 |  | 
| 22 22 | 
             
                def initialize(io)
         | 
| 23 23 | 
             
                  @_io = io
         | 
| 24 | 
            -
                  @_write_buffer   | 
| 24 | 
            +
                  @_write_buffer  ||= Rev::Buffer.new
         | 
| 25 25 | 
             
                  @_read_watcher  = Watcher.new(io, self, :r)
         | 
| 26 26 | 
             
                  @_write_watcher = Watcher.new(io, self, :w)
         | 
| 27 27 | 
             
                end
         | 
| @@ -31,10 +31,10 @@ module Rev | |
| 31 31 | 
             
                #
         | 
| 32 32 |  | 
| 33 33 | 
             
                # Attach to the event loop
         | 
| 34 | 
            -
                def attach(loop); @_read_watcher.attach loop; self; end
         | 
| 34 | 
            +
                def attach(loop); @_read_watcher.attach loop; schedule_write if !@_write_buffer.empty?; self; end
         | 
| 35 35 |  | 
| 36 36 | 
             
                # Detach from the event loop
         | 
| 37 | 
            -
                def detach; @_read_watcher.detach; self; end
         | 
| 37 | 
            +
                def detach; @_read_watcher.detach; self; end # TODO should these detect write buffers, as well?
         | 
| 38 38 |  | 
| 39 39 | 
             
                # Enable the watcher
         | 
| 40 40 | 
             
                def enable; @_read_watcher.enable; self; end
         | 
| @@ -128,6 +128,8 @@ module Rev | |
| 128 128 |  | 
| 129 129 | 
             
                # Schedule a write to be performed when the IO object becomes writable 
         | 
| 130 130 | 
             
                def schedule_write
         | 
| 131 | 
            +
                  return unless @_io # this would mean 'we are still pre DNS here'
         | 
| 132 | 
            +
                  return unless attached? # this would mean 'currently unattached' -- ie still pre DNS, or just plain not attached, which is ok
         | 
| 131 133 | 
             
                  begin
         | 
| 132 134 | 
             
                    enable_write_watcher      
         | 
| 133 135 | 
             
                  rescue IOError
         | 
| @@ -162,4 +164,4 @@ module Rev | |
| 162 164 | 
             
                  def on_writable; @rev_io.__send__(:on_writable); end
         | 
| 163 165 | 
             
                end
         | 
| 164 166 | 
             
              end
         | 
| 165 | 
            -
            end
         | 
| 167 | 
            +
            end
         | 
    
        data/lib/rev/listener.rb
    CHANGED
    
    | @@ -32,7 +32,11 @@ module Rev | |
| 32 32 |  | 
| 33 33 | 
             
                # Rev callback for handling new connections
         | 
| 34 34 | 
             
                def on_readable
         | 
| 35 | 
            -
                   | 
| 35 | 
            +
                  begin
         | 
| 36 | 
            +
                    on_connection @listen_socket.accept_nonblock
         | 
| 37 | 
            +
                  rescue Errno::EAGAIN
         | 
| 38 | 
            +
                    STDERR.puts "warning: listener socket spuriously readable"
         | 
| 39 | 
            +
                  end
         | 
| 36 40 | 
             
                end
         | 
| 37 41 | 
             
              end
         | 
| 38 42 |  | 
    
        data/lib/rev/loop.rb
    CHANGED
    
    | @@ -15,10 +15,8 @@ end | |
| 15 15 |  | 
| 16 16 | 
             
            module Rev
         | 
| 17 17 | 
             
              class Loop
         | 
| 18 | 
            -
                attr_reader :watchers
         | 
| 19 | 
            -
                
         | 
| 20 18 | 
             
                # In Ruby 1.9 we want a Rev::Loop per thread, but Ruby 1.8 is unithreaded
         | 
| 21 | 
            -
                if RUBY_VERSION | 
| 19 | 
            +
                if RUBY_VERSION >= "1.9.0"
         | 
| 22 20 | 
             
                  # Retrieve the default event loop for the current thread
         | 
| 23 21 | 
             
                  def self.default
         | 
| 24 22 | 
             
                    Thread.current._rev_loop
         | 
| @@ -49,7 +47,7 @@ module Rev | |
| 49 47 | 
             
                #     :port   (Solaris 10)
         | 
| 50 48 | 
             
                #
         | 
| 51 49 | 
             
                def initialize(options = {})
         | 
| 52 | 
            -
                  @watchers =  | 
| 50 | 
            +
                  @watchers = {}
         | 
| 53 51 | 
             
                  @active_watchers = 0
         | 
| 54 52 |  | 
| 55 53 | 
             
                  flags = 0
         | 
| @@ -97,6 +95,7 @@ module Rev | |
| 97 95 | 
             
                  while @running and not @active_watchers.zero?
         | 
| 98 96 | 
             
                    run_once
         | 
| 99 97 | 
             
                  end
         | 
| 98 | 
            +
                  @running = false
         | 
| 100 99 | 
             
                end
         | 
| 101 100 |  | 
| 102 101 | 
             
                # Stop the event loop if it's running
         | 
| @@ -110,6 +109,11 @@ module Rev | |
| 110 109 | 
             
                  @active_watchers > 0
         | 
| 111 110 | 
             
                end
         | 
| 112 111 |  | 
| 112 | 
            +
                # All watchers attached to the current loop
         | 
| 113 | 
            +
                def watchers
         | 
| 114 | 
            +
                  @watchers.keys
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
                
         | 
| 113 117 | 
             
                #######
         | 
| 114 118 | 
             
                private
         | 
| 115 119 | 
             
                #######
         | 
    
        data/lib/rev/server.rb
    CHANGED
    
    | @@ -39,7 +39,8 @@ module Rev | |
| 39 39 | 
             
              end
         | 
| 40 40 |  | 
| 41 41 | 
             
              # TCP server class.  Listens on the specified host and port and creates
         | 
| 42 | 
            -
              # new connection objects of the given class.
         | 
| 42 | 
            +
              # new connection objects of the given class. This is the most common server class.
         | 
| 43 | 
            +
              # Note that the new connection objects will be bound by default to the same event loop that the server is attached to.
         | 
| 43 44 | 
             
              class TCPServer < Server
         | 
| 44 45 | 
             
                def initialize(host, port, klass = TCPSocket, *args, &block)
         | 
| 45 46 | 
             
                  listen_socket = ::TCPServer.new(host, port)
         | 
| @@ -55,4 +56,4 @@ module Rev | |
| 55 56 | 
             
                  super(::UNIXServer.new(*args), klass, *args, &block)
         | 
| 56 57 | 
             
                end
         | 
| 57 58 | 
             
              end
         | 
| 58 | 
            -
            end
         | 
| 59 | 
            +
            end
         | 
    
        data/lib/rev/socket.rb
    CHANGED
    
    | @@ -10,6 +10,7 @@ require 'resolv' | |
| 10 10 | 
             
            module Rev
         | 
| 11 11 | 
             
              class Socket < IO    
         | 
| 12 12 | 
             
                def self.connect(socket, *args)
         | 
| 13 | 
            +
             | 
| 13 14 | 
             
                  new(socket, *args).instance_eval do
         | 
| 14 15 | 
             
                    @_connector = Connector.new(self, socket)
         | 
| 15 16 | 
             
                    self
         | 
| @@ -38,8 +39,10 @@ module Rev | |
| 38 39 | 
             
                event_callback :on_connect_failed
         | 
| 39 40 |  | 
| 40 41 | 
             
                # Called if a hostname failed to resolve when connecting
         | 
| 41 | 
            -
                # Defaults to  | 
| 42 | 
            -
                 | 
| 42 | 
            +
                # Defaults to  calling on_connect_failed
         | 
| 43 | 
            +
                def on_resolve_failed
         | 
| 44 | 
            +
                   on_connect_failed
         | 
| 45 | 
            +
                end
         | 
| 43 46 |  | 
| 44 47 | 
             
                #########
         | 
| 45 48 | 
             
                protected
         | 
| @@ -58,6 +61,9 @@ module Rev | |
| 58 61 | 
             
                    if connect_successful?
         | 
| 59 62 | 
             
                      @rev_socket.instance_eval { @_connector = nil }
         | 
| 60 63 | 
             
                      @rev_socket.attach(evl)
         | 
| 64 | 
            +
                      @ruby_socket.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, [1].pack("l"))
         | 
| 65 | 
            +
                      @ruby_socket.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_KEEPALIVE, true)
         | 
| 66 | 
            +
             | 
| 61 67 | 
             
                      @rev_socket.__send__(:on_connect)
         | 
| 62 68 | 
             
                    else
         | 
| 63 69 | 
             
                      @rev_socket.instance_eval { @_failed = true }
         | 
| @@ -93,6 +99,8 @@ module Rev | |
| 93 99 | 
             
                end
         | 
| 94 100 |  | 
| 95 101 | 
             
                # Perform a non-blocking connect to the given host and port
         | 
| 102 | 
            +
                # see examples/echo_client.rb
         | 
| 103 | 
            +
                # addr is a string, can be an IP address or a hostname.
         | 
| 96 104 | 
             
                def self.connect(addr, port, *args)
         | 
| 97 105 | 
             
                  family = nil
         | 
| 98 106 |  | 
| @@ -103,11 +111,11 @@ module Rev | |
| 103 111 | 
             
                  end
         | 
| 104 112 |  | 
| 105 113 | 
             
                  if family
         | 
| 106 | 
            -
                    return super(TCPConnectSocket.new(family, addr, port), *args)
         | 
| 114 | 
            +
                    return super(TCPConnectSocket.new(family, addr, port), *args) # this creates a 'real' write buffer so we're ok there with regards to already having a write buffer from the get go
         | 
| 107 115 | 
             
                  end
         | 
| 108 116 |  | 
| 109 117 | 
             
                  if host = Rev::DNSResolver.hosts(addr)
         | 
| 110 | 
            -
                    return connect(host, port, *args)
         | 
| 118 | 
            +
                    return connect(host, port, *args) # calls this same function
         | 
| 111 119 | 
             
                  end
         | 
| 112 120 |  | 
| 113 121 | 
             
                  precreate(addr, port, *args)
         | 
| @@ -115,6 +123,7 @@ module Rev | |
| 115 123 |  | 
| 116 124 | 
             
                # Called by precreate during asyncronous DNS resolution
         | 
| 117 125 | 
             
                def preinitialize(addr, port, *args)
         | 
| 126 | 
            +
                  @_write_buffer = Rev::Buffer.new # allow for writing BEFORE the DNS has resolved
         | 
| 118 127 | 
             
                  @remote_host, @remote_addr, @remote_port = addr, addr, port
         | 
| 119 128 | 
             
                  @_resolver = TCPConnectResolver.new(self, addr, port, *args)
         | 
| 120 129 | 
             
                end
         | 
| @@ -141,7 +150,7 @@ module Rev | |
| 141 150 |  | 
| 142 151 | 
             
                class TCPConnectSocket < ::Socket
         | 
| 143 152 | 
             
                  def initialize(family, addr, port, host = addr)
         | 
| 144 | 
            -
                    @host, | 
| 153 | 
            +
                    @host,  addr, @port = host, addr, port
         | 
| 145 154 | 
             
                    @address_family = nil
         | 
| 146 155 |  | 
| 147 156 | 
             
                    @socket = super(family, ::Socket::SOCK_STREAM, 0)
         |