nio4r 1.2.1-java → 2.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -1
  3. data/.rubocop.yml +31 -38
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +15 -14
  6. data/CHANGES.md +75 -42
  7. data/Gemfile +10 -5
  8. data/Guardfile +10 -0
  9. data/LICENSE.txt +1 -1
  10. data/README.md +57 -161
  11. data/Rakefile +2 -1
  12. data/examples/echo_server.rb +1 -0
  13. data/ext/libev/Changes +4 -13
  14. data/ext/libev/ev.c +101 -74
  15. data/ext/libev/ev.h +3 -3
  16. data/ext/libev/ev_epoll.c +6 -3
  17. data/ext/libev/ev_kqueue.c +8 -4
  18. data/ext/libev/ev_poll.c +6 -3
  19. data/ext/libev/ev_port.c +8 -4
  20. data/ext/libev/ev_select.c +4 -2
  21. data/ext/nio4r/bytebuffer.c +421 -0
  22. data/ext/nio4r/extconf.rb +2 -10
  23. data/ext/nio4r/monitor.c +93 -46
  24. data/ext/nio4r/nio4r.h +11 -13
  25. data/ext/nio4r/org/nio4r/ByteBuffer.java +295 -0
  26. data/ext/nio4r/org/nio4r/Monitor.java +164 -0
  27. data/ext/nio4r/org/nio4r/Nio4r.java +22 -391
  28. data/ext/nio4r/org/nio4r/Selector.java +278 -0
  29. data/ext/nio4r/selector.c +55 -53
  30. data/lib/nio.rb +4 -3
  31. data/lib/nio/bytebuffer.rb +222 -0
  32. data/lib/nio/monitor.rb +64 -4
  33. data/lib/nio/selector.rb +52 -20
  34. data/lib/nio/version.rb +1 -1
  35. data/nio4r.gemspec +25 -19
  36. data/spec/nio/acceptables_spec.rb +6 -4
  37. data/spec/nio/bytebuffer_spec.rb +349 -0
  38. data/spec/nio/monitor_spec.rb +122 -79
  39. data/spec/nio/selectables/pipe_spec.rb +5 -1
  40. data/spec/nio/selectables/ssl_socket_spec.rb +15 -12
  41. data/spec/nio/selectables/tcp_socket_spec.rb +42 -31
  42. data/spec/nio/selectables/udp_socket_spec.rb +2 -0
  43. data/spec/nio/selector_spec.rb +10 -4
  44. data/spec/spec_helper.rb +24 -3
  45. data/spec/support/selectable_examples.rb +7 -5
  46. data/tasks/extension.rake +2 -0
  47. data/tasks/rspec.rake +2 -0
  48. data/tasks/rubocop.rake +2 -0
  49. metadata +21 -14
  50. data/.rubocop_todo.yml +0 -35
@@ -0,0 +1,164 @@
1
+ package org.nio4r;
2
+
3
+ import java.nio.channels.Channel;
4
+ import java.nio.channels.SelectableChannel;
5
+ import java.nio.channels.SelectionKey;
6
+
7
+ import org.jruby.Ruby;
8
+ import org.jruby.RubyClass;
9
+ import org.jruby.RubyIO;
10
+ import org.jruby.RubyObject;
11
+ import org.jruby.anno.JRubyMethod;
12
+ import org.jruby.runtime.ThreadContext;
13
+ import org.jruby.runtime.builtin.IRubyObject;
14
+
15
+ public class Monitor extends RubyObject {
16
+ private SelectionKey key;
17
+ private RubyIO io;
18
+ private IRubyObject interests, selector, value, closed;
19
+
20
+ public Monitor(final Ruby ruby, RubyClass rubyClass) {
21
+ super(ruby, rubyClass);
22
+ }
23
+
24
+ @JRubyMethod
25
+ public IRubyObject initialize(ThreadContext context, IRubyObject selectable, IRubyObject interests, IRubyObject selector) {
26
+ this.io = RubyIO.convertToIO(context, selectable);
27
+ this.interests = interests;
28
+ this.selector = selector;
29
+
30
+ this.value = context.nil;
31
+ this.closed = context.getRuntime().getFalse();
32
+
33
+ return context.nil;
34
+ }
35
+
36
+ public void setSelectionKey(SelectionKey key) {
37
+ this.key = key;
38
+ key.attach(this);
39
+ }
40
+
41
+ @JRubyMethod
42
+ public IRubyObject io(ThreadContext context) {
43
+ return io;
44
+ }
45
+
46
+ @JRubyMethod
47
+ public IRubyObject selector(ThreadContext context) {
48
+ return selector;
49
+ }
50
+
51
+ @JRubyMethod(name = "interests")
52
+ public IRubyObject getInterests(ThreadContext context) {
53
+ return interests;
54
+ }
55
+
56
+ @JRubyMethod(name = "interests=")
57
+ public IRubyObject setInterests(ThreadContext context, IRubyObject interests) {
58
+ if(this.closed == context.getRuntime().getTrue()) {
59
+ throw context.getRuntime().newEOFError("monitor is closed");
60
+ }
61
+
62
+ Ruby ruby = context.getRuntime();
63
+ SelectableChannel channel = (SelectableChannel)io.getChannel();
64
+
65
+ key.interestOps(Nio4r.symbolToInterestOps(ruby, channel, interests));
66
+ this.interests = interests;
67
+
68
+ return this.interests;
69
+ }
70
+
71
+ @JRubyMethod(name = "add_interest")
72
+ public IRubyObject addInterest(ThreadContext context, IRubyObject interest) {
73
+ if(this.closed == context.getRuntime().getTrue()) {
74
+ throw context.getRuntime().newEOFError("monitor is closed");
75
+ }
76
+
77
+ Ruby ruby = context.getRuntime();
78
+ SelectableChannel channel = (SelectableChannel)io.getChannel();
79
+ int newInterestOps = key.interestOps() | Nio4r.symbolToInterestOps(ruby, channel, interest);
80
+
81
+ key.interestOps(newInterestOps);
82
+ this.interests = Nio4r.interestOpsToSymbol(ruby, newInterestOps);
83
+
84
+ return this.interests;
85
+ }
86
+
87
+ @JRubyMethod(name = "remove_interest")
88
+ public IRubyObject removeInterest(ThreadContext context, IRubyObject interest) {
89
+ if(this.closed == context.getRuntime().getTrue()) {
90
+ throw context.getRuntime().newEOFError("monitor is closed");
91
+ }
92
+
93
+ Ruby ruby = context.getRuntime();
94
+ SelectableChannel channel = (SelectableChannel)io.getChannel();
95
+ int newInterestOps = key.interestOps() & ~Nio4r.symbolToInterestOps(ruby, channel, interest);
96
+
97
+ key.interestOps(newInterestOps);
98
+ this.interests = Nio4r.interestOpsToSymbol(ruby, newInterestOps);
99
+
100
+ return this.interests;
101
+ }
102
+
103
+ @JRubyMethod
104
+ public IRubyObject readiness(ThreadContext context) {
105
+ return Nio4r.interestOpsToSymbol(context.getRuntime(), key.readyOps());
106
+ }
107
+
108
+ @JRubyMethod(name = "readable?")
109
+ public IRubyObject isReadable(ThreadContext context) {
110
+ Ruby runtime = context.getRuntime();
111
+ int readyOps = this.key.readyOps();
112
+
113
+ if((readyOps & SelectionKey.OP_READ) != 0 || (readyOps & SelectionKey.OP_ACCEPT) != 0) {
114
+ return runtime.getTrue();
115
+ } else {
116
+ return runtime.getFalse();
117
+ }
118
+ }
119
+
120
+ @JRubyMethod(name = {"writable?", "writeable?"})
121
+ public IRubyObject writable(ThreadContext context) {
122
+ Ruby runtime = context.getRuntime();
123
+ int readyOps = this.key.readyOps();
124
+
125
+ if((readyOps & SelectionKey.OP_WRITE) != 0 || (readyOps & SelectionKey.OP_CONNECT) != 0) {
126
+ return runtime.getTrue();
127
+ } else {
128
+ return runtime.getFalse();
129
+ }
130
+ }
131
+
132
+ @JRubyMethod(name = "value")
133
+ public IRubyObject getValue(ThreadContext context) {
134
+ return this.value;
135
+ }
136
+
137
+ @JRubyMethod(name = "value=")
138
+ public IRubyObject setValue(ThreadContext context, IRubyObject obj) {
139
+ this.value = obj;
140
+ return context.nil;
141
+ }
142
+
143
+ @JRubyMethod
144
+ public IRubyObject close(ThreadContext context) {
145
+ return close(context, context.getRuntime().getTrue());
146
+ }
147
+
148
+ @JRubyMethod
149
+ public IRubyObject close(ThreadContext context, IRubyObject deregister) {
150
+ Ruby runtime = context.getRuntime();
151
+ this.closed = runtime.getTrue();
152
+
153
+ if(deregister == runtime.getTrue()) {
154
+ selector.callMethod(context, "deregister", io);
155
+ }
156
+
157
+ return context.nil;
158
+ }
159
+
160
+ @JRubyMethod(name = "closed?")
161
+ public IRubyObject isClosed(ThreadContext context) {
162
+ return this.closed;
163
+ }
164
+ }
@@ -1,26 +1,19 @@
1
1
  package org.nio4r;
2
2
 
3
- import java.util.Iterator;
4
- import java.util.Map;
5
- import java.util.HashMap;
6
- import java.io.IOException;
7
- import java.nio.channels.Channel;
8
- import java.nio.channels.SocketChannel;
9
3
  import java.nio.channels.SelectableChannel;
10
4
  import java.nio.channels.SelectionKey;
5
+ import java.nio.channels.SocketChannel;
6
+
11
7
  import org.jruby.Ruby;
12
- import org.jruby.RubyModule;
13
8
  import org.jruby.RubyClass;
14
- import org.jruby.RubyObject;
15
- import org.jruby.RubyIO;
16
- import org.jruby.RubyNumeric;
17
- import org.jruby.RubyArray;
18
- import org.jruby.anno.JRubyMethod;
9
+ import org.jruby.RubyModule;
19
10
  import org.jruby.runtime.ObjectAllocator;
20
- import org.jruby.runtime.ThreadContext;
21
11
  import org.jruby.runtime.load.Library;
22
12
  import org.jruby.runtime.builtin.IRubyObject;
23
- import org.jruby.runtime.Block;
13
+
14
+ import org.nio4r.ByteBuffer;
15
+ import org.nio4r.Monitor;
16
+ import org.nio4r.Selector;
24
17
 
25
18
  public class Nio4r implements Library {
26
19
  private Ruby ruby;
@@ -45,6 +38,19 @@ public class Nio4r implements Library {
45
38
  }, nio);
46
39
 
47
40
  monitor.defineAnnotatedMethods(Monitor.class);
41
+
42
+ RubyClass byteBuffer = ruby.defineClassUnder("ByteBuffer", ruby.getObject(), new ObjectAllocator() {
43
+ public IRubyObject allocate(Ruby ruby, RubyClass rc) {
44
+ return new ByteBuffer(ruby, rc);
45
+ }
46
+ }, nio);
47
+
48
+ byteBuffer.defineAnnotatedMethods(ByteBuffer.class);
49
+ byteBuffer.includeModule(ruby.getEnumerable());
50
+
51
+ ruby.defineClassUnder("OverflowError", ruby.getIOError(), ruby.getIOError().getAllocator(), byteBuffer);
52
+ ruby.defineClassUnder("UnderflowError", ruby.getIOError(), ruby.getIOError().getAllocator(), byteBuffer);
53
+ ruby.defineClassUnder("MarkUnsetError", ruby.getIOError(), ruby.getIOError().getAllocator(), byteBuffer);
48
54
  }
49
55
 
50
56
  public static int symbolToInterestOps(Ruby ruby, SelectableChannel channel, IRubyObject interest) {
@@ -89,385 +95,10 @@ public class Nio4r implements Library {
89
95
  case SelectionKey.OP_READ | SelectionKey.OP_CONNECT:
90
96
  case SelectionKey.OP_READ | SelectionKey.OP_WRITE:
91
97
  return ruby.newSymbol("rw");
98
+ case 0:
99
+ return ruby.getNil();
92
100
  default:
93
101
  throw ruby.newArgumentError("unknown interest op combination");
94
102
  }
95
103
  }
96
-
97
- public class Selector extends RubyObject {
98
- private java.nio.channels.Selector selector;
99
- private HashMap<SelectableChannel,SelectionKey> cancelledKeys;
100
-
101
- public Selector(final Ruby ruby, RubyClass rubyClass) {
102
- super(ruby, rubyClass);
103
- }
104
-
105
- @JRubyMethod
106
- public IRubyObject initialize(ThreadContext context) {
107
- this.cancelledKeys = new HashMap<SelectableChannel,SelectionKey>();
108
- try {
109
- this.selector = java.nio.channels.Selector.open();
110
- } catch(IOException ie) {
111
- throw context.runtime.newIOError(ie.getLocalizedMessage());
112
- }
113
-
114
- return context.nil;
115
- }
116
-
117
- @JRubyMethod
118
- public IRubyObject close(ThreadContext context) {
119
- try {
120
- this.selector.close();
121
- } catch(IOException ie) {
122
- throw context.runtime.newIOError(ie.getLocalizedMessage());
123
- }
124
-
125
- return context.nil;
126
- }
127
-
128
- @JRubyMethod(name = "closed?")
129
- public IRubyObject isClosed(ThreadContext context) {
130
- Ruby runtime = context.getRuntime();
131
- return this.selector.isOpen() ? runtime.getFalse() : runtime.getTrue();
132
- }
133
-
134
- @JRubyMethod(name = "empty?")
135
- public IRubyObject isEmpty(ThreadContext context) {
136
- Ruby runtime = context.getRuntime();
137
- return this.selector.keys().isEmpty() ? runtime.getTrue() : runtime.getFalse();
138
- }
139
-
140
- @JRubyMethod
141
- public IRubyObject register(ThreadContext context, IRubyObject io, IRubyObject interests) {
142
- Ruby runtime = context.getRuntime();
143
- Channel rawChannel = RubyIO.convertToIO(context, io).getChannel();
144
-
145
- if(!this.selector.isOpen()) {
146
- throw context.getRuntime().newIOError("selector is closed");
147
- }
148
-
149
- if(!(rawChannel instanceof SelectableChannel)) {
150
- throw runtime.newArgumentError("not a selectable IO object");
151
- }
152
-
153
- SelectableChannel channel = (SelectableChannel)rawChannel;
154
-
155
- try {
156
- channel.configureBlocking(false);
157
- } catch(IOException ie) {
158
- throw runtime.newIOError(ie.getLocalizedMessage());
159
- }
160
-
161
- int interestOps = Nio4r.symbolToInterestOps(runtime, channel, interests);
162
- SelectionKey key;
163
-
164
- key = this.cancelledKeys.remove(channel);
165
-
166
- if(key != null) {
167
- key.interestOps(interestOps);
168
- } else {
169
- try {
170
- key = channel.register(this.selector, interestOps);
171
- } catch(java.lang.IllegalArgumentException ia) {
172
- throw runtime.newArgumentError("mode not supported for this object: " + interests);
173
- } catch(java.nio.channels.ClosedChannelException cce) {
174
- throw context.runtime.newIOError(cce.getLocalizedMessage());
175
- }
176
- }
177
-
178
- RubyClass monitorClass = runtime.getModule("NIO").getClass("Monitor");
179
- Monitor monitor = (Monitor)monitorClass.newInstance(context, io, interests, this, null);
180
- monitor.setSelectionKey(key);
181
-
182
- return monitor;
183
- }
184
-
185
- @JRubyMethod
186
- public IRubyObject deregister(ThreadContext context, IRubyObject io) {
187
- Ruby runtime = context.getRuntime();
188
- Channel rawChannel = RubyIO.convertToIO(context, io).getChannel();
189
-
190
- if(!(rawChannel instanceof SelectableChannel)) {
191
- throw runtime.newArgumentError("not a selectable IO object");
192
- }
193
-
194
- SelectableChannel channel = (SelectableChannel)rawChannel;
195
- SelectionKey key = channel.keyFor(this.selector);
196
-
197
- if(key == null)
198
- return context.nil;
199
-
200
- Monitor monitor = (Monitor)key.attachment();
201
- monitor.close(context, runtime.getFalse());
202
- cancelledKeys.put(channel, key);
203
-
204
- return monitor;
205
- }
206
-
207
- @JRubyMethod(name = "registered?")
208
- public IRubyObject isRegistered(ThreadContext context, IRubyObject io) {
209
- Ruby runtime = context.getRuntime();
210
- Channel rawChannel = RubyIO.convertToIO(context, io).getChannel();
211
-
212
- if(!(rawChannel instanceof SelectableChannel)) {
213
- throw runtime.newArgumentError("not a selectable IO object");
214
- }
215
-
216
- SelectableChannel channel = (SelectableChannel)rawChannel;
217
- SelectionKey key = channel.keyFor(this.selector);
218
-
219
- if(key == null)
220
- return context.nil;
221
-
222
-
223
- if(((Monitor)key.attachment()).isClosed(context) == runtime.getTrue()) {
224
- return runtime.getFalse();
225
- } else {
226
- return runtime.getTrue();
227
- }
228
- }
229
-
230
- @JRubyMethod
231
- public synchronized IRubyObject select(ThreadContext context, Block block) {
232
- return select(context, context.nil, block);
233
- }
234
-
235
- @JRubyMethod
236
- public synchronized IRubyObject select(ThreadContext context, IRubyObject timeout, Block block) {
237
- Ruby runtime = context.getRuntime();
238
-
239
- if(!this.selector.isOpen()) {
240
- throw context.getRuntime().newIOError("selector is closed");
241
- }
242
-
243
- int ready = doSelect(runtime, context, timeout);
244
-
245
- /* Timeout or wakeup */
246
- if(ready <= 0)
247
- return context.nil;
248
-
249
- RubyArray array = null;
250
- if(!block.isGiven()) {
251
- array = runtime.newArray(this.selector.selectedKeys().size());
252
- }
253
-
254
- Iterator selectedKeys = this.selector.selectedKeys().iterator();
255
- while(selectedKeys.hasNext()) {
256
- SelectionKey key = (SelectionKey)selectedKeys.next();
257
- processKey(key);
258
- selectedKeys.remove();
259
-
260
- if(block.isGiven()) {
261
- block.call(context, (IRubyObject)key.attachment());
262
- } else {
263
- array.add(key.attachment());
264
- }
265
- }
266
-
267
- if(block.isGiven()) {
268
- return RubyNumeric.int2fix(runtime, ready);
269
- } else {
270
- return array;
271
- }
272
- }
273
-
274
- /* Run the selector */
275
- private int doSelect(Ruby runtime, ThreadContext context, IRubyObject timeout) {
276
- int result;
277
-
278
- cancelKeys();
279
- try {
280
- context.getThread().beforeBlockingCall();
281
- if(timeout.isNil()) {
282
- result = this.selector.select();
283
- } else {
284
- double t = RubyNumeric.num2dbl(timeout);
285
- if(t == 0) {
286
- result = this.selector.selectNow();
287
- } else if(t < 0) {
288
- throw runtime.newArgumentError("time interval must be positive");
289
- } else {
290
- long timeoutMilliSeconds = (long)(t * 1000);
291
- if(timeoutMilliSeconds == 0) {
292
- result = this.selector.selectNow();
293
- } else {
294
- result = this.selector.select(timeoutMilliSeconds);
295
- }
296
- }
297
- }
298
- context.getThread().afterBlockingCall();
299
- return result;
300
- } catch(IOException ie) {
301
- throw runtime.newIOError(ie.getLocalizedMessage());
302
- }
303
- }
304
-
305
- /* Flush our internal buffer of cancelled keys */
306
- private void cancelKeys() {
307
- Iterator cancelledKeys = this.cancelledKeys.entrySet().iterator();
308
- while(cancelledKeys.hasNext()) {
309
- Map.Entry entry = (Map.Entry)cancelledKeys.next();
310
- SelectionKey key = (SelectionKey)entry.getValue();
311
- key.cancel();
312
- cancelledKeys.remove();
313
- }
314
- }
315
-
316
- // Remove connect interest from connected sockets
317
- // See: http://stackoverflow.com/questions/204186/java-nio-select-returns-without-selected-keys-why
318
- private void processKey(SelectionKey key) {
319
- if((key.readyOps() & SelectionKey.OP_CONNECT) != 0) {
320
- int interestOps = key.interestOps();
321
-
322
- interestOps &= ~SelectionKey.OP_CONNECT;
323
- interestOps |= SelectionKey.OP_WRITE;
324
-
325
- key.interestOps(interestOps);
326
- }
327
- }
328
-
329
- @JRubyMethod
330
- public IRubyObject wakeup(ThreadContext context) {
331
- if(!this.selector.isOpen()) {
332
- throw context.getRuntime().newIOError("selector is closed");
333
- }
334
-
335
- this.selector.wakeup();
336
- return context.nil;
337
- }
338
- }
339
-
340
- public class Monitor extends RubyObject {
341
- private SelectionKey key;
342
- private RubyIO io;
343
- private IRubyObject interests, selector, value, closed;
344
-
345
- public Monitor(final Ruby ruby, RubyClass rubyClass) {
346
- super(ruby, rubyClass);
347
- }
348
-
349
- @JRubyMethod
350
- public IRubyObject initialize(ThreadContext context, IRubyObject selectable, IRubyObject interests, IRubyObject selector) {
351
- this.io = RubyIO.convertToIO(context, selectable);
352
- this.interests = interests;
353
- this.selector = selector;
354
-
355
- this.value = context.nil;
356
- this.closed = context.getRuntime().getFalse();
357
-
358
- return context.nil;
359
- }
360
-
361
- public void setSelectionKey(SelectionKey key) {
362
- this.key = key;
363
- key.attach(this);
364
- }
365
-
366
- @JRubyMethod(name = "interests=")
367
- public IRubyObject setInterests(ThreadContext context, IRubyObject interests) {
368
- if(this.closed == context.getRuntime().getTrue()) {
369
- throw context.getRuntime().newTypeError("monitor is already closed");
370
- }
371
-
372
- int interestOps = 0;
373
- Ruby runtime = context.getRuntime();
374
- Channel rawChannel = io.getChannel();
375
- SelectableChannel channel = (SelectableChannel)rawChannel;
376
-
377
- this.interests = interests;
378
-
379
- if(interests == ruby.newSymbol("r")) {
380
- interestOps = SelectionKey.OP_READ;
381
- } else if(interests == ruby.newSymbol("w")) {
382
- interestOps = SelectionKey.OP_WRITE;
383
- } else if(interests == ruby.newSymbol("rw")) {
384
- interestOps = SelectionKey.OP_READ|SelectionKey.OP_WRITE;
385
- }
386
-
387
- if((interestOps & ~(channel.validOps())) == 0) {
388
- key.interestOps(interestOps);
389
- } else {
390
- throw context.getRuntime().newArgumentError("given interests not supported for this IO object");
391
- }
392
-
393
- return this.interests;
394
- }
395
-
396
- @JRubyMethod
397
- public IRubyObject io(ThreadContext context) {
398
- return io;
399
- }
400
-
401
- @JRubyMethod
402
- public IRubyObject selector(ThreadContext context) {
403
- return selector;
404
- }
405
-
406
- @JRubyMethod
407
- public IRubyObject interests(ThreadContext context) {
408
- return interests;
409
- }
410
-
411
- @JRubyMethod
412
- public IRubyObject readiness(ThreadContext context) {
413
- return Nio4r.interestOpsToSymbol(context.getRuntime(), key.readyOps());
414
- }
415
-
416
- @JRubyMethod(name = "readable?")
417
- public IRubyObject isReadable(ThreadContext context) {
418
- Ruby runtime = context.getRuntime();
419
- int readyOps = this.key.readyOps();
420
-
421
- if((readyOps & SelectionKey.OP_READ) != 0 || (readyOps & SelectionKey.OP_ACCEPT) != 0) {
422
- return runtime.getTrue();
423
- } else {
424
- return runtime.getFalse();
425
- }
426
- }
427
-
428
- @JRubyMethod(name = {"writable?", "writeable?"})
429
- public IRubyObject writable(ThreadContext context) {
430
- Ruby runtime = context.getRuntime();
431
- int readyOps = this.key.readyOps();
432
-
433
- if((readyOps & SelectionKey.OP_WRITE) != 0 || (readyOps & SelectionKey.OP_CONNECT) != 0) {
434
- return runtime.getTrue();
435
- } else {
436
- return runtime.getFalse();
437
- }
438
- }
439
-
440
- @JRubyMethod(name = "value")
441
- public IRubyObject getValue(ThreadContext context) {
442
- return this.value;
443
- }
444
-
445
- @JRubyMethod(name = "value=")
446
- public IRubyObject setValue(ThreadContext context, IRubyObject obj) {
447
- this.value = obj;
448
- return context.nil;
449
- }
450
-
451
- @JRubyMethod
452
- public IRubyObject close(ThreadContext context) {
453
- return close(context, context.getRuntime().getTrue());
454
- }
455
-
456
- @JRubyMethod
457
- public IRubyObject close(ThreadContext context, IRubyObject deregister) {
458
- Ruby runtime = context.getRuntime();
459
- this.closed = runtime.getTrue();
460
-
461
- if(deregister == runtime.getTrue()) {
462
- selector.callMethod(context, "deregister", io);
463
- }
464
-
465
- return context.nil;
466
- }
467
-
468
- @JRubyMethod(name = "closed?")
469
- public IRubyObject isClosed(ThreadContext context) {
470
- return this.closed;
471
- }
472
- }
473
104
  }