nio4r 0.4.3-java → 0.4.4-java

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.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,28 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nio4r
3
3
  version: !ruby/object:Gem::Version
4
+ version: 0.4.4
4
5
  prerelease:
5
- version: 0.4.3
6
6
  platform: java
7
7
  authors:
8
8
  - Tony Arcieri
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-21 00:00:00.000000000 Z
12
+ date: 2013-05-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler
16
16
  version_requirements: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ! '>='
18
+ - - ">="
19
19
  - !ruby/object:Gem::Version
20
20
  version: !binary |-
21
21
  MA==
22
22
  none: false
23
23
  requirement: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ! '>='
25
+ - - ">="
26
26
  - !ruby/object:Gem::Version
27
27
  version: !binary |-
28
28
  MA==
@@ -33,14 +33,14 @@ dependencies:
33
33
  name: rake
34
34
  version_requirements: !ruby/object:Gem::Requirement
35
35
  requirements:
36
- - - ! '>='
36
+ - - ">="
37
37
  - !ruby/object:Gem::Version
38
38
  version: !binary |-
39
39
  MA==
40
40
  none: false
41
41
  requirement: !ruby/object:Gem::Requirement
42
42
  requirements:
43
- - - ! '>='
43
+ - - ">="
44
44
  - !ruby/object:Gem::Version
45
45
  version: !binary |-
46
46
  MA==
@@ -51,14 +51,14 @@ dependencies:
51
51
  name: rspec
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
- - - ! '>='
54
+ - - ">="
55
55
  - !ruby/object:Gem::Version
56
56
  version: !binary |-
57
57
  MA==
58
58
  none: false
59
59
  requirement: !ruby/object:Gem::Requirement
60
60
  requirements:
61
- - - ! '>='
61
+ - - ">="
62
62
  - !ruby/object:Gem::Version
63
63
  version: !binary |-
64
64
  MA==
@@ -72,9 +72,9 @@ executables: []
72
72
  extensions: []
73
73
  extra_rdoc_files: []
74
74
  files:
75
- - .gitignore
76
- - .rspec
77
- - .travis.yml
75
+ - ".gitignore"
76
+ - ".rspec"
77
+ - ".travis.yml"
78
78
  - CHANGES.md
79
79
  - Gemfile
80
80
  - LICENSE.txt
@@ -128,21 +128,15 @@ require_paths:
128
128
  - lib
129
129
  required_ruby_version: !ruby/object:Gem::Requirement
130
130
  requirements:
131
- - - ! '>='
131
+ - - ">="
132
132
  - !ruby/object:Gem::Version
133
- segments:
134
- - 0
135
- hash: 2
136
133
  version: !binary |-
137
134
  MA==
138
135
  none: false
139
136
  required_rubygems_version: !ruby/object:Gem::Requirement
140
137
  requirements:
141
- - - ! '>='
138
+ - - ">="
142
139
  - !ruby/object:Gem::Version
143
- segments:
144
- - 0
145
- hash: 2
146
140
  version: !binary |-
147
141
  MA==
148
142
  none: false