nio4r 0.4.3 → 0.4.4

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2e3051116830dc9b33942397704ba51b61fa3516
4
+ data.tar.gz: a379f1a217877593d4b7443310b4c0509ea57153
5
+ SHA512:
6
+ metadata.gz: ab002f8623a84161e66e1eaab440cae28d900bb48fb0fe06759647123c85f095fa7e6481642e9d10e9606eec0388eca10d879ef812cb276b9c12dfe02ae21f3a
7
+ data.tar.gz: 3be3517573e66bef454a0894a93bdfba7ba087f00957c832a50526b19a9ea8a28fced1314568861b18c62aefcf5148718a01848b7e21b66256ac5591b407e6fb
data/CHANGES.md CHANGED
@@ -1,3 +1,7 @@
1
+ 0.4.4
2
+ -----
3
+ * Fix return values for Selector_synchronize and Selector_unlock
4
+
1
5
  0.4.3
2
6
  -----
3
7
  * REALLY have thread synchronization when closing selectors ;)
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
2
 
3
3
  gem 'jruby-openssl' if defined? JRUBY_VERSION
4
4
 
data/README.md CHANGED
@@ -121,7 +121,7 @@ selector.deregister(reader)
121
121
 
122
122
  Monitors provide methods which let you introspect on why a particular IO
123
123
  object was selected. These methods are not thread safe unless you are holding
124
- the selector lock (i.e. if you're in a block pased to #select). Only use them
124
+ the selector lock (i.e. if you're in a block passed to #select). Only use them
125
125
  if you aren't concerned with thread safety, or you're within a #select
126
126
  block:
127
127
 
@@ -231,7 +231,7 @@ public class Nio4r implements Library {
231
231
  @JRubyMethod
232
232
  public synchronized IRubyObject select(ThreadContext context, IRubyObject timeout, Block block) {
233
233
  Ruby runtime = context.getRuntime();
234
- int ready = doSelect(runtime, timeout);
234
+ int ready = doSelect(runtime, context, timeout);
235
235
 
236
236
  /* Timeout or wakeup */
237
237
  if(ready <= 0)
@@ -263,21 +263,26 @@ public class Nio4r implements Library {
263
263
  }
264
264
 
265
265
  /* Run the selector */
266
- private int doSelect(Ruby runtime, IRubyObject timeout) {
266
+ private int doSelect(Ruby runtime, ThreadContext context, IRubyObject timeout) {
267
+ int result;
268
+
267
269
  cancelKeys();
268
270
  try {
271
+ context.getThread().beforeBlockingCall();
269
272
  if(timeout.isNil()) {
270
- return this.selector.select();
273
+ result = this.selector.select();
271
274
  } else {
272
275
  double t = RubyNumeric.num2dbl(timeout);
273
276
  if(t == 0) {
274
- return this.selector.selectNow();
277
+ result = this.selector.selectNow();
275
278
  } else if(t < 0) {
276
279
  throw runtime.newArgumentError("time interval must be positive");
277
280
  } else {
278
- return this.selector.select((long)(t * 1000));
281
+ result = this.selector.select((long)(t * 1000));
279
282
  }
280
283
  }
284
+ context.getThread().afterBlockingCall();
285
+ return result;
281
286
  } catch(IOException ie) {
282
287
  throw runtime.newIOError(ie.getLocalizedMessage());
283
288
  }
@@ -170,7 +170,7 @@ static VALUE NIO_Selector_synchronize(VALUE self, VALUE (*func)(VALUE *args), VA
170
170
  return rb_ensure(func, (VALUE)args, NIO_Selector_unlock, self);
171
171
  } else {
172
172
  /* We already hold the selector lock, so no need to unlock it */
173
- func(args);
173
+ return func(args);
174
174
  }
175
175
  }
176
176
 
@@ -183,6 +183,8 @@ static VALUE NIO_Selector_unlock(VALUE self)
183
183
 
184
184
  lock = rb_ivar_get(self, rb_intern("lock"));
185
185
  rb_funcall(lock, rb_intern("unlock"), 0, 0);
186
+
187
+ return Qnil;
186
188
  }
187
189
 
188
190
  /* Register an IO object with the selector for the given interests */
data/lib/nio.rb CHANGED
@@ -11,7 +11,7 @@ module NIO
11
11
  def self.engine; ENGINE end
12
12
  end
13
13
 
14
- if ENV["NIO4R_PURE"]
14
+ if ENV["NIO4R_PURE"] || ENV["OS"] =~ /Windows/i
15
15
  require 'nio/monitor'
16
16
  require 'nio/selector'
17
17
  NIO::ENGINE = 'select'
@@ -18,7 +18,9 @@ module NIO
18
18
  # * :rw - is the IO either readable or writeable?
19
19
  def register(io, interest)
20
20
  @lock.synchronize do
21
- raise ArgumentError, "this IO is already registered with the selector" if @selectables[io]
21
+ if monitor = @selectables[io]
22
+ raise ArgumentError, "this IO is already registered with the selector as #{monitor.interests.inspect}"
23
+ end
22
24
 
23
25
  monitor = Monitor.new(io, interest, self)
24
26
  @selectables[io] = monitor
@@ -61,14 +63,7 @@ module NIO
61
63
  if io == @wakeup
62
64
  # Clear all wakeup signals we've received by reading them
63
65
  # Wakeups should have level triggered behavior
64
- begin
65
- @wakeup.read_nonblock(1024)
66
-
67
- # Loop until we've drained all incoming events
68
- redo
69
- rescue Errno::EWOULDBLOCK
70
- end
71
-
66
+ @wakeup.read(@wakeup.stat.size)
72
67
  return
73
68
  else
74
69
  monitor = @selectables[io]
@@ -107,7 +102,7 @@ module NIO
107
102
  # level-triggered behavior.
108
103
  def wakeup
109
104
  # Send the selector a signal in the form of writing data to a pipe
110
- @waker << "\0"
105
+ @waker.write "\0"
111
106
  nil
112
107
  end
113
108
 
@@ -1,3 +1,3 @@
1
1
  module NIO
2
- VERSION = "0.4.3"
2
+ VERSION = "0.4.4"
3
3
  end
@@ -6,12 +6,12 @@ describe NIO::Monitor do
6
6
  let(:writer) { pipes.last }
7
7
  let(:selector) { NIO::Selector.new }
8
8
 
9
- subject { selector.register(reader, :rw) }
9
+ subject { selector.register(reader, :r) }
10
10
  let(:peer) { selector.register(writer, :rw) }
11
11
  after { selector.close }
12
12
 
13
13
  it "knows its interests" do
14
- subject.interests.should == :rw
14
+ subject.interests.should == :r
15
15
  peer.interests.should == :rw
16
16
  end
17
17
 
@@ -18,8 +18,13 @@ describe "IO.pipe" do
18
18
  let :unwritable_subject do
19
19
  reader, pipe = IO.pipe
20
20
 
21
+ #HACK: On OS X 10.8, this str must be larger than PIPE_BUF. Otherwise,
22
+ # the write is atomic and select() will return writable but write()
23
+ # will throw EAGAIN if there is too little space to write the string
24
+ # TODO: Use FFI to lookup the platform-specific size of PIPE_BUF
25
+ str = "JUNK IN THE TUBES" * 10000
21
26
  begin
22
- pipe.write_nonblock "JUNK IN THE TUBES"
27
+ pipe.write_nonblock str
23
28
  _, writers = select [], [pipe], [], 0
24
29
  rescue Errno::EPIPE
25
30
  break
@@ -114,13 +114,25 @@ describe NIO::Selector do
114
114
  writer << "ohai"
115
115
  unready, _ = IO.pipe
116
116
 
117
- reader_monitor = subject.register(reader, :r)
117
+ reader_monitor = subject.register(reader, :r)
118
118
  unready_monitor = subject.register(unready, :r)
119
119
 
120
120
  selected = subject.select(0)
121
121
  selected.size.should == 1
122
- selected.should include(reader_monitor)
123
- selected.should_not include(unready_monitor)
122
+ selected.should include reader_monitor
123
+ selected.should_not include unready_monitor
124
+ end
125
+
126
+ it "selects closed IO objects" do
127
+ monitor = subject.register(reader, :r)
128
+ subject.select(0).should be_nil
129
+
130
+ thread = Thread.new { subject.select }
131
+ Thread.pass while thread.status && thread.status != "sleep"
132
+
133
+ writer.close
134
+ selected = thread.value
135
+ selected.should include monitor
124
136
  end
125
137
 
126
138
  it "iterates across selected objects with a block" do
@@ -140,9 +152,9 @@ describe NIO::Selector do
140
152
  result = subject.select { |monitor| readables << monitor }
141
153
  result.should == 2
142
154
 
143
- readables.should include(monitor1)
144
- readables.should include(monitor2)
145
- readables.should_not include(monitor3)
155
+ readables.should include monitor1
156
+ readables.should include monitor2
157
+ readables.should_not include monitor3
146
158
  end
147
159
  end
148
160
 
metadata CHANGED
@@ -1,62 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nio4r
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
5
- prerelease:
4
+ version: 0.4.4
6
5
  platform: ruby
7
6
  authors:
8
7
  - Tony Arcieri
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-11-21 00:00:00.000000000 Z
11
+ date: 2013-05-05 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rake-compiler
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rake
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rspec
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  description: New IO for Ruby
@@ -116,33 +109,26 @@ files:
116
109
  - tasks/rspec.rake
117
110
  homepage: https://github.com/tarcieri/nio4r
118
111
  licenses: []
112
+ metadata: {}
119
113
  post_install_message:
120
114
  rdoc_options: []
121
115
  require_paths:
122
116
  - lib
123
117
  required_ruby_version: !ruby/object:Gem::Requirement
124
- none: false
125
118
  requirements:
126
- - - ! '>='
119
+ - - '>='
127
120
  - !ruby/object:Gem::Version
128
121
  version: '0'
129
- segments:
130
- - 0
131
- hash: 1104474676653820230
132
122
  required_rubygems_version: !ruby/object:Gem::Requirement
133
- none: false
134
123
  requirements:
135
- - - ! '>='
124
+ - - '>='
136
125
  - !ruby/object:Gem::Version
137
126
  version: '0'
138
- segments:
139
- - 0
140
- hash: 1104474676653820230
141
127
  requirements: []
142
128
  rubyforge_project:
143
- rubygems_version: 1.8.24
129
+ rubygems_version: 2.0.3
144
130
  signing_key:
145
- specification_version: 3
131
+ specification_version: 4
146
132
  summary: NIO provides a high performance selector API for monitoring IO objects
147
133
  test_files:
148
134
  - spec/nio/acceptables_spec.rb