/** This is the body of the listening thread */ public void run() { SocketAddress sender; checkBuffer(); try { listen: while (isListening) { try { byteBuf.clear(); // temporary until we work out a better way... // Fixed buffer size limits the maximum size of received packets // Seems there are always limitations and a default going back to the constant // DEFAULTBUFSIZE byte[] buffer = new byte[getBufferSize()]; DatagramPacket dp = new DatagramPacket(buffer, buffer.length); ms.receive(dp); byteBuf.put(buffer); sender = dp.getSocketAddress(); if (!isListening) break listen; if ((target != null)) continue listen; flipDecodeDispatch(sender); } catch (ClosedChannelException e1) { // bye bye, we have to quit if (isListening) { // System.err.println( e1 ); System.err.println( "OSCReceiver.run : " + e1.getClass().getName() + " : " + e1.getLocalizedMessage()); } return; } catch (IOException e1) { if (isListening) { System.err.println( "OSCReceiver.run : " + e1.getClass().getName() + " : " + e1.getLocalizedMessage()); // System.err.println( new OSCException( OSCException.RECEIVE, e1.toString() )); } } } // while( isListening ) } finally { synchronized (threadSync) { thread = null; threadSync.notifyAll(); // stopListening() might be waiting } } }
@JRubyMethod public IRubyObject register(ThreadContext context, IRubyObject io, IRubyObject interests) { Ruby runtime = context.getRuntime(); Channel rawChannel = RubyIO.convertToIO(context, io).getChannel(); if (!this.selector.isOpen()) { throw context.getRuntime().newIOError("selector is closed"); } if (!(rawChannel instanceof SelectableChannel)) { throw runtime.newArgumentError("not a selectable IO object"); } SelectableChannel channel = (SelectableChannel) rawChannel; try { channel.configureBlocking(false); } catch (IOException ie) { throw runtime.newIOError(ie.getLocalizedMessage()); } int interestOps = Nio4r.symbolToInterestOps(runtime, channel, interests); SelectionKey key; key = this.cancelledKeys.remove(channel); if (key != null) { key.interestOps(interestOps); } else { try { key = channel.register(this.selector, interestOps); } catch (java.lang.IllegalArgumentException ia) { throw runtime.newArgumentError("mode not supported for this object: " + interests); } catch (java.nio.channels.ClosedChannelException cce) { throw context.runtime.newIOError(cce.getLocalizedMessage()); } } RubyClass monitorClass = runtime.getModule("NIO").getClass("Monitor"); Monitor monitor = (Monitor) monitorClass.newInstance(context, io, interests, this, null); monitor.setSelectionKey(key); return monitor; }