cool.io 1.0.0 → 1.9.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.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/test.yaml +54 -0
  3. data/.gitignore +30 -0
  4. data/.rspec +3 -0
  5. data/{CHANGES → CHANGES.md} +175 -79
  6. data/{README.markdown → README.md} +43 -49
  7. data/Rakefile +44 -69
  8. data/appveyor.yml +18 -0
  9. data/cool.io.gemspec +18 -131
  10. data/examples/callbacked_echo_server.rb +24 -0
  11. data/ext/cool.io/buffer.c +781 -0
  12. data/ext/cool.io/cool.io.h +13 -0
  13. data/ext/cool.io/cool.io_ext.c +1 -0
  14. data/ext/cool.io/ev_wrap.h +4 -2
  15. data/ext/cool.io/extconf.rb +27 -16
  16. data/ext/cool.io/iowatcher.c +17 -8
  17. data/ext/cool.io/loop.c +36 -84
  18. data/ext/cool.io/stat_watcher.c +103 -25
  19. data/ext/cool.io/timer_watcher.c +3 -3
  20. data/ext/cool.io/utils.c +5 -0
  21. data/ext/cool.io/watcher.h +1 -1
  22. data/ext/libev/Changes +152 -3
  23. data/ext/libev/LICENSE +2 -1
  24. data/ext/libev/README +8 -8
  25. data/ext/libev/ev.c +1719 -348
  26. data/ext/libev/ev.h +146 -118
  27. data/ext/libev/ev_epoll.c +71 -20
  28. data/ext/libev/ev_kqueue.c +36 -16
  29. data/ext/libev/ev_poll.c +14 -11
  30. data/ext/libev/ev_port.c +43 -18
  31. data/ext/libev/ev_select.c +82 -25
  32. data/ext/libev/ev_vars.h +28 -21
  33. data/ext/libev/ev_win32.c +19 -10
  34. data/ext/libev/ev_wrap.h +166 -152
  35. data/ext/libev/test_libev_win32.c +1 -1
  36. data/gems.rb +9 -0
  37. data/lib/cool.io/async_watcher.rb +1 -1
  38. data/lib/cool.io/custom_require.rb +9 -0
  39. data/lib/cool.io/dns_resolver.rb +30 -22
  40. data/lib/cool.io/dsl.rb +32 -28
  41. data/lib/cool.io/io.rb +55 -35
  42. data/lib/cool.io/iowatcher.rb +1 -1
  43. data/lib/cool.io/listener.rb +35 -17
  44. data/lib/cool.io/loop.rb +17 -25
  45. data/lib/cool.io/meta.rb +6 -5
  46. data/lib/cool.io/server.rb +5 -4
  47. data/lib/cool.io/socket.rb +41 -30
  48. data/lib/cool.io/timer_watcher.rb +1 -1
  49. data/lib/cool.io/version.rb +7 -0
  50. data/lib/cool.io.rb +11 -10
  51. data/lib/coolio.rb +1 -1
  52. data/libev_ruby_gil.diff +175 -0
  53. data/libev_win_select.diff +130 -0
  54. data/spec/async_watcher_spec.rb +5 -5
  55. data/spec/dns_spec.rb +27 -8
  56. data/spec/iobuffer_spec.rb +147 -0
  57. data/spec/spec_helper.rb +15 -1
  58. data/spec/stat_watcher_spec.rb +81 -0
  59. data/spec/tcp_server_spec.rb +225 -0
  60. data/spec/tcp_socket_spec.rb +185 -0
  61. data/spec/timer_watcher_spec.rb +23 -19
  62. data/spec/udp_socket_spec.rb +58 -0
  63. data/spec/unix_listener_spec.rb +8 -8
  64. data/spec/unix_server_spec.rb +10 -8
  65. metadata +109 -112
  66. data/VERSION +0 -1
  67. data/examples/httpclient.rb +0 -38
  68. data/ext/http11_client/.gitignore +0 -5
  69. data/ext/http11_client/LICENSE +0 -31
  70. data/ext/http11_client/ext_help.h +0 -14
  71. data/ext/http11_client/extconf.rb +0 -6
  72. data/ext/http11_client/http11_client.c +0 -300
  73. data/ext/http11_client/http11_parser.c +0 -403
  74. data/ext/http11_client/http11_parser.h +0 -48
  75. data/ext/http11_client/http11_parser.rl +0 -173
  76. data/lib/cool.io/eventmachine.rb +0 -234
  77. data/lib/cool.io/http_client.rb +0 -419
  78. data/lib/rev.rb +0 -4
  79. data/spec/possible_tests/schedules_other_threads.rb +0 -48
  80. data/spec/possible_tests/test_on_resolve_failed.rb +0 -9
  81. data/spec/possible_tests/test_resolves.rb +0 -27
  82. data/spec/possible_tests/test_write_during_resolve.rb +0 -27
  83. data/spec/possible_tests/works_straight.rb +0 -71
data/lib/cool.io/io.rb CHANGED
@@ -15,13 +15,13 @@ module Coolio
15
15
  # Socket class and its associated subclasses.
16
16
  class IO
17
17
  extend Meta
18
-
18
+
19
19
  # Maximum number of bytes to consume at once
20
20
  INPUT_SIZE = 16384
21
21
 
22
22
  def initialize(io)
23
23
  @_io = io
24
- @_write_buffer ||= ::IO::Buffer.new
24
+ @_write_buffer ||= ::Coolio::Buffer.new
25
25
  @_read_watcher = Watcher.new(io, self, :r)
26
26
  @_write_watcher = Watcher.new(io, self, :w)
27
27
  end
@@ -29,32 +29,52 @@ module Coolio
29
29
  #
30
30
  # Watcher methods, delegated to @_read_watcher
31
31
  #
32
-
32
+
33
33
  # Attach to the event loop
34
- def attach(loop); @_read_watcher.attach loop; schedule_write if !@_write_buffer.empty?; self; end
35
-
34
+ def attach(loop)
35
+ @_read_watcher.attach(loop)
36
+ schedule_write if !@_write_buffer.empty?
37
+ self
38
+ end
39
+
36
40
  # Detach from the event loop
37
- def detach; @_read_watcher.detach; self; end # TODO should these detect write buffers, as well?
38
-
41
+ def detach
42
+ # TODO should these detect write buffers, as well?
43
+ @_read_watcher.detach
44
+ self
45
+ end
46
+
39
47
  # Enable the watcher
40
- def enable; @_read_watcher.enable; self; end
41
-
48
+ def enable
49
+ @_read_watcher.enable
50
+ self
51
+ end
52
+
42
53
  # Disable the watcher
43
- def disable; @_read_watcher.disable; self; end
44
-
54
+ def disable
55
+ @_read_watcher.disable
56
+ self
57
+ end
58
+
45
59
  # Is the watcher attached?
46
- def attached?; @_read_watcher.attached?; end
47
-
60
+ def attached?
61
+ @_read_watcher.attached?
62
+ end
63
+
48
64
  # Is the watcher enabled?
49
- def enabled?; @_read_watcher.enabled?; end
50
-
65
+ def enabled?
66
+ @_read_watcher.enabled?
67
+ end
68
+
51
69
  # Obtain the event loop associated with this object
52
- def evloop; @_read_watcher.evloop; end
53
-
70
+ def evloop
71
+ @_read_watcher.evloop
72
+ end
73
+
54
74
  #
55
75
  # Callbacks for asynchronous events
56
76
  #
57
-
77
+
58
78
  # Called whenever the IO object receives data
59
79
  def on_read(data); end
60
80
  event_callback :on_read
@@ -78,16 +98,11 @@ module Coolio
78
98
  data.size
79
99
  end
80
100
 
81
- # Number of bytes are currently in the output buffer
82
- def output_buffer_size
83
- @_write_buffer.size
84
- end
85
-
86
101
  # Close the IO stream
87
102
  def close
88
103
  detach if attached?
89
104
  detach_write_watcher
90
- @_io.close unless @_io.closed?
105
+ @_io.close unless closed?
91
106
 
92
107
  on_close
93
108
  nil
@@ -114,7 +129,7 @@ module Coolio
114
129
  close
115
130
  end
116
131
  end
117
-
132
+
118
133
  # Write the contents of the output buffer
119
134
  def on_writable
120
135
  begin
@@ -126,23 +141,23 @@ module Coolio
126
141
  rescue SystemCallError, IOError, SocketError
127
142
  return close
128
143
  end
129
-
144
+
130
145
  if @_write_buffer.empty?
131
146
  disable_write_watcher
132
147
  on_write_complete
133
148
  end
134
149
  end
135
150
 
136
- # Schedule a write to be performed when the IO object becomes writable
151
+ # Schedule a write to be performed when the IO object becomes writable
137
152
  def schedule_write
138
153
  return unless @_io # this would mean 'we are still pre DNS here'
139
- return unless attached? # this would mean 'currently unattached' -- ie still pre DNS, or just plain not attached, which is ok
154
+ return unless @_read_watcher.attached? # this would mean 'currently unattached' -- ie still pre DNS, or just plain not attached, which is ok
140
155
  begin
141
- enable_write_watcher
156
+ enable_write_watcher
142
157
  rescue IOError
143
158
  end
144
159
  end
145
-
160
+
146
161
  def enable_write_watcher
147
162
  if @_write_watcher.attached?
148
163
  @_write_watcher.enable unless @_write_watcher.enabled?
@@ -150,15 +165,15 @@ module Coolio
150
165
  @_write_watcher.attach(evloop)
151
166
  end
152
167
  end
153
-
168
+
154
169
  def disable_write_watcher
155
170
  @_write_watcher.disable if @_write_watcher and @_write_watcher.enabled?
156
171
  end
157
-
172
+
158
173
  def detach_write_watcher
159
174
  @_write_watcher.detach if @_write_watcher and @_write_watcher.attached?
160
175
  end
161
-
176
+
162
177
  # Internal class implementing watchers used by Coolio::IO
163
178
  class Watcher < IOWatcher
164
179
  def initialize(ruby_io, coolio_io, flags)
@@ -167,8 +182,13 @@ module Coolio
167
182
  end
168
183
 
169
184
  # Configure IOWatcher event callbacks to call the method passed to #initialize
170
- def on_readable; @coolio_io.__send__(:on_readable); end
171
- def on_writable; @coolio_io.__send__(:on_writable); end
185
+ def on_readable
186
+ @coolio_io.__send__(:on_readable)
187
+ end
188
+
189
+ def on_writable
190
+ @coolio_io.__send__(:on_writable)
191
+ end
172
192
  end
173
193
  end
174
194
  end
@@ -5,7 +5,7 @@
5
5
  #++
6
6
 
7
7
  module Coolio
8
- class IOWatcher
8
+ class IOWatcher
9
9
  # The actual implementation of this class resides in the C extension
10
10
  # Here we metaprogram proper event_callbacks for the callback methods
11
11
  # These can take a block and store it to be called when the event
@@ -21,6 +21,10 @@ module Coolio
21
21
  @listen_socket.fileno
22
22
  end
23
23
 
24
+ def listen(backlog)
25
+ @listen_socket.listen(backlog)
26
+ end
27
+
24
28
  # Close the listener
25
29
  def close
26
30
  detach if attached?
@@ -36,26 +40,38 @@ module Coolio
36
40
  #########
37
41
 
38
42
  # Coolio callback for handling new connections
39
- def on_readable
40
- begin
41
- on_connection @listen_socket.accept_nonblock
42
- rescue Errno::EAGAIN, Errno::ECONNABORTED
43
- # EAGAIN can be triggered here if the socket is shared between
44
- # multiple processes and a thundering herd is woken up to accept
45
- # one connection, only one process will get the connection and
46
- # the others will be awoken.
47
- # ECONNABORTED is documented in accept() manpages but modern TCP
48
- # stacks with syncookies and/or accept()-filtering for DoS
49
- # protection do not see it. In any case this error is harmless
50
- # and we should instead spend our time with clients that follow
51
- # through on connection attempts.
43
+ unless RUBY_PLATFORM =~ /mingw|mswin/
44
+ def on_readable
45
+ begin
46
+ on_connection @listen_socket.accept_nonblock
47
+ rescue Errno::EAGAIN, Errno::ECONNABORTED
48
+ # EAGAIN can be triggered here if the socket is shared between
49
+ # multiple processes and a thundering herd is woken up to accept
50
+ # one connection, only one process will get the connection and
51
+ # the others will be awoken.
52
+ # ECONNABORTED is documented in accept() manpages but modern TCP
53
+ # stacks with syncookies and/or accept()-filtering for DoS
54
+ # protection do not see it. In any case this error is harmless
55
+ # and we should instead spend our time with clients that follow
56
+ # through on connection attempts.
57
+ end
58
+ end
59
+ else
60
+ def on_readable
61
+ begin
62
+ # In Windows, accept_nonblock() with multiple processes
63
+ # causes thundering herd problem.
64
+ # To avoid this, we need to use accept().
65
+ on_connection @listen_socket.accept
66
+ rescue Errno::EAGAIN, Errno::ECONNABORTED
67
+ end
52
68
  end
53
69
  end
54
70
  end
55
71
 
72
+ DEFAULT_BACKLOG = 1024
73
+
56
74
  class TCPListener < Listener
57
- DEFAULT_BACKLOG = 1024
58
-
59
75
  # Create a new Coolio::TCPListener on the specified address and port.
60
76
  # Accepts the following options:
61
77
  #
@@ -68,7 +84,7 @@ module Coolio
68
84
  def initialize(addr, port = nil, options = {})
69
85
  BasicSocket.do_not_reverse_lookup = true unless options[:reverse_lookup]
70
86
  options[:backlog] ||= DEFAULT_BACKLOG
71
-
87
+
72
88
  listen_socket = if ::TCPServer === addr
73
89
  addr
74
90
  else
@@ -87,7 +103,9 @@ module Coolio
87
103
  # Optionally, it can also take anyn existing UNIXServer object
88
104
  # and create a Coolio::UNIXListener out of it.
89
105
  def initialize(*args)
90
- super(::UNIXServer === args.first ? args.first : ::UNIXServer.new(*args))
106
+ s = ::UNIXServer === args.first ? args.first : ::UNIXServer.new(*args)
107
+ s.instance_eval { listen(DEFAULT_BACKLOG) }
108
+ super(s)
91
109
  end
92
110
  end
93
111
  end
data/lib/cool.io/loop.rb CHANGED
@@ -15,17 +15,9 @@ end
15
15
 
16
16
  module Coolio
17
17
  class Loop
18
- # In Ruby 1.9 we want a Coolio::Loop per thread, but Ruby 1.8 is unithreaded
19
- if RUBY_VERSION >= "1.9.0"
20
- # Retrieve the default event loop for the current thread
21
- def self.default
22
- Thread.current._coolio_loop
23
- end
24
- else
25
- # Retrieve the default event loop
26
- def self.default
27
- @@_coolio_loop ||= Coolio::Loop.new
28
- end
18
+ # Retrieve the default event loop for the current thread
19
+ def self.default
20
+ Thread.current._coolio_loop
29
21
  end
30
22
 
31
23
  # Create a new Coolio::Loop
@@ -35,7 +27,7 @@ module Coolio
35
27
  # :skip_environment (boolean)
36
28
  # Ignore the $LIBEV_FLAGS environment variable
37
29
  #
38
- # :fork_check (boolean)
30
+ # :fork_check (boolean)
39
31
  # Enable autodetection of forks
40
32
  #
41
33
  # :backend
@@ -49,7 +41,7 @@ module Coolio
49
41
  def initialize(options = {})
50
42
  @watchers = {}
51
43
  @active_watchers = 0
52
-
44
+
53
45
  flags = 0
54
46
 
55
47
  options.each do |option, value|
@@ -76,7 +68,7 @@ module Coolio
76
68
 
77
69
  @loop = ev_loop_new(flags)
78
70
  end
79
-
71
+
80
72
  # Attach a watcher to the loop
81
73
  def attach(watcher)
82
74
  watcher.attach self
@@ -86,14 +78,14 @@ module Coolio
86
78
  # are no watchers associated with the event loop it will return
87
79
  # immediately. Otherwise, run will continue blocking and making
88
80
  # event callbacks to watchers until all watchers associated with
89
- # the loop have been disabled or detached. The loop may be
81
+ # the loop have been disabled or detached. The loop may be
90
82
  # explicitly stopped by calling the stop method on the loop object.
91
- def run
83
+ def run(timeout = nil)
92
84
  raise RuntimeError, "no watchers for this loop" if @watchers.empty?
93
85
 
94
86
  @running = true
95
87
  while @running and not @active_watchers.zero?
96
- run_once
88
+ run_once(timeout)
97
89
  end
98
90
  @running = false
99
91
  end
@@ -103,28 +95,28 @@ module Coolio
103
95
  raise RuntimeError, "loop not running" unless @running
104
96
  @running = false
105
97
  end
106
-
98
+
107
99
  # Does the loop have any active watchers?
108
100
  def has_active_watchers?
109
101
  @active_watchers > 0
110
102
  end
111
-
103
+
112
104
  # All watchers attached to the current loop
113
105
  def watchers
114
106
  @watchers.keys
115
107
  end
116
-
108
+
117
109
  #######
118
110
  private
119
111
  #######
120
-
112
+
121
113
  EVFLAG_NOENV = 0x1000000 # do NOT consult environment
122
114
  EVFLAG_FORKCHECK = 0x2000000 # check for a fork in each iteration
123
115
 
124
- EVBACKEND_SELECT = 0x00000001 # supported about anywhere
125
- EVBACKEND_POLL = 0x00000002 # !win
126
- EVBACKEND_EPOLL = 0x00000004 # linux
127
- EVBACKEND_KQUEUE = 0x00000008 # bsd
116
+ EVBACKEND_SELECT = 0x00000001 # supported about anywhere
117
+ EVBACKEND_POLL = 0x00000002 # !win
118
+ EVBACKEND_EPOLL = 0x00000004 # linux
119
+ EVBACKEND_KQUEUE = 0x00000008 # bsd
128
120
  EVBACKEND_PORT = 0x00000020 # solaris 10
129
121
  end
130
122
  end
data/lib/cool.io/meta.rb CHANGED
@@ -11,10 +11,10 @@ module Coolio
11
11
  # an event to occur before the current watcher can be used in earnest,
12
12
  # such as making an outgoing TCP connection.
13
13
  def watcher_delegate(proxy_var)
14
- %w{attach detach enable disable}.each do |method|
14
+ %w{attach attached? detach enable disable}.each do |method|
15
15
  module_eval <<-EOD
16
16
  def #{method}(*args)
17
- if #{proxy_var}
17
+ if defined? #{proxy_var} and #{proxy_var}
18
18
  #{proxy_var}.#{method}(*args)
19
19
  return self
20
20
  end
@@ -32,14 +32,15 @@ module Coolio
32
32
  def event_callback(*methods)
33
33
  methods.each do |method|
34
34
  module_eval <<-EOD
35
+ remove_method "#{method}"
35
36
  def #{method}(*args, &block)
36
37
  if block
37
38
  @#{method}_callback = block
38
39
  return
39
40
  end
40
-
41
- if @#{method}_callback
42
- instance_exec(*args, &@#{method}_callback)
41
+
42
+ if defined? @#{method}_callback and @#{method}_callback
43
+ @#{method}_callback.call(*args)
43
44
  end
44
45
  end
45
46
  EOD
@@ -20,9 +20,9 @@ module Coolio
20
20
  expected = arity >= 0 ? arity : -(arity + 1)
21
21
 
22
22
  if (arity >= 0 and args.size + 1 != expected) or (arity < 0 and args.size + 1 < expected)
23
- raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size+1} for #{expected})"
23
+ raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size+1} for #{expected})"
24
24
  end
25
-
25
+
26
26
  @klass, @args, @block = klass, args, block
27
27
  super(listen_socket)
28
28
  end
@@ -35,7 +35,7 @@ module Coolio
35
35
  #########
36
36
  protected
37
37
  #########
38
-
38
+
39
39
  def on_connection(socket)
40
40
  connection = @klass.new(socket, *@args).attach(evloop)
41
41
  connection.__send__(:on_connect)
@@ -56,7 +56,7 @@ module Coolio
56
56
  raise ArgumentError, "port must be an integer" if nil == port
57
57
  ::TCPServer.new(host, port)
58
58
  end
59
- listen_socket.instance_eval { listen(1024) } # Change listen backlog to 1024
59
+ listen_socket.instance_eval { listen(DEFAULT_BACKLOG) } # Change listen backlog to 1024
60
60
  super(listen_socket, klass, *args, &block)
61
61
  end
62
62
  end
@@ -68,6 +68,7 @@ module Coolio
68
68
  class UNIXServer < Server
69
69
  def initialize(path, klass = UNIXSocket, *args, &block)
70
70
  s = ::UNIXServer === path ? path : ::UNIXServer.new(path)
71
+ s.instance_eval { listen(DEFAULT_BACKLOG) }
71
72
  super(s, klass, *args, &block)
72
73
  end
73
74
  end
@@ -8,7 +8,7 @@ require 'socket'
8
8
  require 'resolv'
9
9
 
10
10
  module Coolio
11
- class Socket < IO
11
+ class Socket < IO
12
12
  def self.connect(socket, *args)
13
13
 
14
14
  new(socket, *args).instance_eval do
@@ -16,42 +16,51 @@ module Coolio
16
16
  self
17
17
  end
18
18
  end
19
-
19
+
20
+ # Just initializes some instance variables to avoid
21
+ # warnings and calls super().
22
+ def initialize *args
23
+ @_failed = nil
24
+ @_connector = nil
25
+ super
26
+ end
27
+
20
28
  watcher_delegate :@_connector
21
29
 
30
+ remove_method :attach
22
31
  def attach(evloop)
23
32
  raise RuntimeError, "connection failed" if @_failed
24
-
33
+
25
34
  if @_connector
26
35
  @_connector.attach(evloop)
27
36
  return self
28
37
  end
29
-
38
+
30
39
  super
31
40
  end
32
41
 
33
42
  # Called upon completion of a socket connection
34
43
  def on_connect; end
35
44
  event_callback :on_connect
36
-
45
+
37
46
  # Called if a socket connection failed to complete
38
47
  def on_connect_failed; end
39
48
  event_callback :on_connect_failed
40
-
49
+
41
50
  # Called if a hostname failed to resolve when connecting
42
51
  # Defaults to calling on_connect_failed
43
52
  alias_method :on_resolve_failed, :on_connect_failed
44
-
53
+
45
54
  #########
46
55
  protected
47
56
  #########
48
-
57
+
49
58
  class Connector < IOWatcher
50
59
  def initialize(coolio_socket, ruby_socket)
51
60
  @coolio_socket, @ruby_socket = coolio_socket, ruby_socket
52
61
  super(ruby_socket, :w)
53
62
  end
54
-
63
+
55
64
  def on_writable
56
65
  evl = evloop
57
66
  detach
@@ -67,7 +76,7 @@ module Coolio
67
76
  @coolio_socket.instance_eval { @_failed = true }
68
77
  @coolio_socket.__send__(:on_connect_failed)
69
78
  end
70
- end
79
+ end
71
80
 
72
81
  #######
73
82
  private
@@ -80,11 +89,11 @@ module Coolio
80
89
  end
81
90
  end
82
91
  end
83
-
92
+
84
93
  class TCPSocket < Socket
85
94
  attr_reader :remote_host, :remote_addr, :remote_port, :address_family
86
95
  watcher_delegate :@_resolver
87
-
96
+
88
97
  # Similar to .new, but used in cases where the resulting object is in a
89
98
  # "half-open" state. This is primarily used for when asynchronous
90
99
  # DNS resolution is taking place. We don't actually have a handle to
@@ -95,7 +104,7 @@ module Coolio
95
104
  obj.__send__(:preinitialize, *args, &block)
96
105
  obj
97
106
  end
98
-
107
+
99
108
  # Perform a non-blocking connect to the given host and port
100
109
  # see examples/echo_client.rb
101
110
  # addr is a string, can be an IP address or a hostname.
@@ -107,7 +116,7 @@ module Coolio
107
116
  elsif(Resolv::IPv6.create(addr) rescue nil)
108
117
  family = ::Socket::AF_INET6
109
118
  end
110
-
119
+
111
120
  if family
112
121
  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
113
122
  end
@@ -118,37 +127,39 @@ module Coolio
118
127
 
119
128
  precreate(addr, port, *args)
120
129
  end
121
-
130
+
122
131
  # Called by precreate during asyncronous DNS resolution
123
132
  def preinitialize(addr, port, *args)
124
- @_write_buffer = ::IO::Buffer.new # allow for writing BEFORE DNS has resolved
133
+ @_write_buffer = ::Coolio::Buffer.new # allow for writing BEFORE DNS has resolved
125
134
  @remote_host, @remote_addr, @remote_port = addr, addr, port
126
135
  @_resolver = TCPConnectResolver.new(self, addr, port, *args)
127
136
  end
128
-
137
+
129
138
  private :preinitialize
130
-
139
+
140
+ PEERADDR_FAILED = ["?", 0, "name resolusion failed", "?"]
141
+
131
142
  def initialize(socket)
132
143
  unless socket.is_a?(::TCPSocket) or socket.is_a?(TCPConnectSocket)
133
144
  raise TypeError, "socket must be a TCPSocket"
134
145
  end
135
-
146
+
136
147
  super
137
-
138
- @address_family, @remote_port, @remote_host, @remote_addr = socket.peeraddr
148
+
149
+ @address_family, @remote_port, @remote_host, @remote_addr = (socket.peeraddr rescue PEERADDR_FAILED)
139
150
  end
140
-
151
+
141
152
  def peeraddr
142
153
  [@address_family, @remote_port, @remote_host, @remote_addr]
143
154
  end
144
-
155
+
145
156
  #########
146
157
  protected
147
158
  #########
148
159
 
149
160
  class TCPConnectSocket < ::Socket
150
161
  def initialize(family, addr, port, host = addr)
151
- @host, addr, @port = host, addr, port
162
+ @host, @addr, @port = host, addr, port
152
163
  @address_family = nil
153
164
 
154
165
  super(family, ::Socket::SOCK_STREAM, 0)
@@ -195,26 +206,26 @@ module Coolio
195
206
 
196
207
  def on_failure
197
208
  @sock.__send__(:on_resolve_failed)
198
- @sock.instance_eval do
199
- @_resolver = nil
209
+ @sock.instance_eval do
210
+ @_resolver = nil
200
211
  @_failed = true
201
212
  end
202
213
  return
203
214
  end
204
215
  end
205
216
  end
206
-
217
+
207
218
  class UNIXSocket < Socket
208
219
  attr_reader :path, :address_family
209
-
220
+
210
221
  # Connect to the given UNIX domain socket
211
222
  def self.connect(path, *args)
212
223
  new(::UNIXSocket.new(path), *args)
213
224
  end
214
-
225
+
215
226
  def initialize(socket)
216
227
  raise ArgumentError, "socket must be a UNIXSocket" unless socket.is_a? ::UNIXSocket
217
-
228
+
218
229
  super
219
230
  @address_family, @path = socket.peeraddr
220
231
  end
@@ -10,7 +10,7 @@ module Coolio
10
10
  # Here we metaprogram proper event_callbacks for the callback methods
11
11
  # These can take a block and store it to be called when the event
12
12
  # is actually fired.
13
-
13
+
14
14
  extend Meta
15
15
  event_callback :on_timer
16
16
  end
@@ -0,0 +1,7 @@
1
+ module Coolio
2
+ VERSION = "1.9.0"
3
+
4
+ def self.version
5
+ VERSION
6
+ end
7
+ end
data/lib/cool.io.rb CHANGED
@@ -1,12 +1,13 @@
1
1
  #--
2
- # Copyright (C)2007-10 Tony Arcieri
2
+ # Copyright (C)2011 Tony Arcieri
3
3
  # You can redistribute this under the terms of the Ruby license
4
4
  # See file LICENSE for details
5
5
  #++
6
6
 
7
- require 'iobuffer'
7
+ require "cool.io/version"
8
+ require "cool.io/custom_require"
9
+ cool_require "cool.io_ext"
8
10
 
9
- require "cool.io_ext"
10
11
  require "cool.io/loop"
11
12
  require "cool.io/meta"
12
13
  require "cool.io/io"
@@ -17,16 +18,16 @@ require "cool.io/listener"
17
18
  require "cool.io/dns_resolver"
18
19
  require "cool.io/socket"
19
20
  require "cool.io/server"
20
- require "cool.io/http_client"
21
- require "cool.io/dsl"
22
21
 
23
22
  module Coolio
24
- VERSION = File.read(File.expand_path('../../VERSION', __FILE__)).strip
25
- def self.version; VERSION; end
26
- def self.inspect; "Cool.io"; end
23
+ def self.inspect
24
+ "Cool.io"
25
+ end
27
26
  end
28
27
 
29
28
  module Cool
30
29
  # Allow Coolio module to be referenced as Cool.io
31
- def self.io; Coolio; end
32
- end
30
+ def self.io
31
+ Coolio
32
+ end
33
+ end