/* $Id$ */ package ibis.ipl.impl.nio; import java.io.IOException; import java.nio.channels.ReadableByteChannel; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Dissipator which reads from a single channel, with the channel normally in * non-blocking mode. */ final class NonBlockingChannelNioDissipator extends NioDissipator { private static Logger logger = LoggerFactory.getLogger(NonBlockingChannelNioDissipator.class); Selector selector; NonBlockingChannelNioDissipator(ReadableByteChannel channel) throws IOException { super(channel); if (!(channel instanceof SelectableChannel)) { throw new IOException("wrong type of channel given on creation of" + " ChannelNioDissipator"); } selector = Selector.open(); SelectableChannel sc = (SelectableChannel) this.channel; sc.configureBlocking(false); sc.register(selector, SelectionKey.OP_READ); } /** * fills the buffer upto at least "minimum" bytes. * */ protected void fillBuffer(int minimum) throws IOException { if (logger.isDebugEnabled()) { logger.debug("filling buffer"); } // Always do one read, even if it isn't strictly needed // and without looking if we're going to get any data. readFromChannel(); while (unUsedLength() < minimum) { if (logger.isDebugEnabled()) { logger.debug("doing a select for data"); } selector.select(); selector.selectedKeys().clear(); readFromChannel(); } if (logger.isDebugEnabled()) { logger.debug("filled buffer"); } } public void close() throws IOException { selector.close(); super.close(); } }