cool.io 1.9.5 → 1.10.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/ext/libev/ev_wrap.h CHANGED
@@ -98,6 +98,8 @@
98
98
  #define vec_ro ((loop)->vec_ro)
99
99
  #define vec_wi ((loop)->vec_wi)
100
100
  #define vec_wo ((loop)->vec_wo)
101
+ #define win32_fs ((loop)->win32_fs)
102
+ #define win32_fs_disabled ((loop)->win32_fs_disabled)
101
103
  #else
102
104
  #undef EV_WRAP_H
103
105
  #undef acquire_cb
@@ -197,4 +199,6 @@
197
199
  #undef vec_ro
198
200
  #undef vec_wi
199
201
  #undef vec_wo
202
+ #undef win32_fs
203
+ #undef win32_fs_disabled
200
204
  #endif
@@ -218,6 +218,7 @@ module Coolio
218
218
  while not message.empty?
219
219
  type = message[2..3].unpack('n').first.to_i
220
220
  rdlength = message[10..11].unpack('n').first.to_i
221
+ return if message.bytesize < 12 + rdlength
221
222
  rdata = message[12..(12 + rdlength - 1)]
222
223
  message.slice!(0, 12 + rdlength)
223
224
 
data/lib/cool.io/loop.rb CHANGED
@@ -38,6 +38,10 @@ module Coolio
38
38
  # :kqueue (BSD/Mac OS X)
39
39
  # :port (Solaris 10)
40
40
  #
41
+ # Raises RuntimeError if none of the selected backends is usable.
42
+ # Unless :skip_environment is true, $LIBEV_FLAGS can override the
43
+ # backend selection and cause the same error.
44
+ #
41
45
  def initialize(options = {})
42
46
  @watchers = {}
43
47
  @active_watchers = 0
@@ -47,7 +51,7 @@ module Coolio
47
51
  options.each do |option, value|
48
52
  case option
49
53
  when :skip_environment
50
- flags |= EVFLAG_NOEV if value
54
+ flags |= EVFLAG_NOENV if value
51
55
  when :fork_check
52
56
  flags |= EVFLAG_FORKCHECK if value
53
57
  when :backend
@@ -1,5 +1,5 @@
1
1
  module Coolio
2
- VERSION = "1.9.5"
2
+ VERSION = "1.10.0"
3
3
 
4
4
  def self.version
5
5
  VERSION
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Cool.io::Loop do
4
- # An IOWatcher that drains its pipe and then runs a user-supplied block,
4
+ # An IOWatcher that drains its socket and then runs a user-supplied block,
5
5
  # receiving itself as the argument.
6
6
  class Victim < Cool.io::IOWatcher
7
7
  def initialize(io, &on_readable)
@@ -34,16 +34,21 @@ describe Cool.io::Loop do
34
34
  # crashed intermittently on macOS.
35
35
  it "does not raise when a watcher with a pending event is detached during dispatch" do
36
36
  iterations = 200
37
+ # Winsock select monitors sockets, not IO.pipe handles. TCP connections
38
+ # exercise the same queued-event scenario on every supported platform.
39
+ listener = TCPServer.new('127.0.0.1', 0)
37
40
 
38
- expect {
39
- iterations.times do
40
- coolio_loop = Cool.io::Loop.new
41
- pipes = []
42
- watchers = []
41
+ iterations.times do
42
+ coolio_loop = Cool.io::Loop.new
43
+ connections = []
44
+ watchers = []
43
45
 
46
+ begin
44
47
  5.times do
45
- r, w = IO.pipe
46
- pipes << [r, w]
48
+ w = TCPSocket.new('127.0.0.1', listener.addr[1])
49
+ connections << [nil, w]
50
+ r = listener.accept
51
+ connections.last[0] = r
47
52
 
48
53
  watcher = Victim.new(r) do |fired|
49
54
  # Detach every other watcher whose event is already queued for this
@@ -58,16 +63,23 @@ describe Cool.io::Loop do
58
63
  w.write("dummy\n") # make the read end readable so an event is pending
59
64
  end
60
65
 
66
+ # TCP delivery is asynchronous. Ensure all five read ends are ready
67
+ # before libev collects the events, without consuming their data.
68
+ connections.each do |r, _|
69
+ expect(IO.select([r], nil, nil, 2)).not_to be_nil
70
+ end
61
71
  coolio_loop.run_once
62
72
 
63
73
  # Only the first dispatched watcher runs; it detaches the other four,
64
74
  # whose pending events are then skipped.
65
75
  expect(watchers.count(&:attached?)).to eq(1)
66
-
76
+ ensure
67
77
  watchers.each { |watcher| watcher.detach if watcher.attached? }
68
- pipes.each { |r, w| r.close; w.close }
78
+ connections.each { |r, w| r.close if r; w.close }
69
79
  end
70
- }.not_to raise_error
80
+ end
81
+ ensure
82
+ listener.close if listener
71
83
  end
72
84
 
73
85
  class HttpHandler < Coolio::IO
data/spec/dns_spec.rb CHANGED
@@ -211,6 +211,17 @@ describe "DNS" do
211
211
  resolver.__send__(:on_readable)
212
212
  end
213
213
 
214
+ it "fails a response whose A record is shorter than its RDLENGTH instead of resolving a bogus address" do
215
+ truncated = dns_response_for(resolver, address: "1.2.3.4")[0...-4]
216
+ allow(resolver.instance_variable_get(:@socket)).to receive(:recvfrom_nonblock).and_return([truncated, sender])
217
+
218
+ expect(resolver).to_not receive(:on_success)
219
+ expect(resolver).to receive(:on_failure)
220
+ expect(resolver).to receive(:detach)
221
+
222
+ resolver.__send__(:on_readable)
223
+ end
224
+
214
225
  it "ignores a spoofed response instead of resolving or failing it" do
215
226
  forged = dns_response_for(resolver, address: "6.6.6.6")
216
227
  allow(resolver.instance_variable_get(:@socket)).to receive(:recvfrom_nonblock)