@Override public void close() { _isClosed = true; for (Monitor monitor : _entries.values()) { monitor.close(); } _inner.close(); }
/** * This method is used to write the zero length chunk. Writing the zero length chunk tells the * client that the response has been fully sent, and the next sequence of bytes from the HTTP * pipeline is the start of the next response. This will signal to the server kernel that the next * request is read to read. */ private void finish() throws IOException { try { sender.send(zero); monitor.ready(sender); } catch (Exception cause) { if (sender != null) { monitor.close(sender); } throw new ProducerException("Error flushing response", cause); } }
/** * This method is used to flush the contents of the buffer to the client. This method will block * until such time as all of the data has been sent to the client. If at any point there is an * error sending the content an exception is thrown. */ public void flush() throws IOException { try { if (!monitor.isClosed()) { sender.flush(); } } catch (Exception cause) { if (sender != null) { monitor.close(sender); } throw new ProducerException("Error sending response", cause); } }
@JRubyMethod public IRubyObject deregister(ThreadContext context, IRubyObject io) { Ruby runtime = context.getRuntime(); Channel rawChannel = RubyIO.convertToIO(context, io).getChannel(); if (!(rawChannel instanceof SelectableChannel)) { throw runtime.newArgumentError("not a selectable IO object"); } SelectableChannel channel = (SelectableChannel) rawChannel; SelectionKey key = channel.keyFor(this.selector); if (key == null) return context.nil; Monitor monitor = (Monitor) key.attachment(); monitor.close(context, runtime.getFalse()); cancelledKeys.put(channel, key); return monitor; }