/** * Add a route from one channel to another. An input can only have one output, but multiple inputs * can be routed to a single output (no order is imposed, though, so this is usually not a good * idea). The collection of routes is thread-safe, so it is legal to call this method after {@link * #run()} has been called. * * @param input This must be configured as non-blocking by using {@link * SelectableChannel#configureBlocking(boolean)} * @param output This must be configured as non-blocking in the same way as input */ public < T extends SelectableChannel & ReadableByteChannel, S extends SelectableChannel & WritableByteChannel> void addRoute(T input, S output) throws ClosedChannelException { // Must put into the maps before registering with the Selector in case // this thread is preempted by the input being available for read before // there's an output ready for it this.outputBuffers.put(output, ByteBuffer.allocate(BUFFER_SIZE)); this.outputs.put(input, output); // Register the output channel with the selector if it isn't already // registered, but don't register for any operations yet; this will be // used later to switch the output to and from selecting for writing in // the run loop. In addition, do this first so the output key is always // available in case data is immediately available on input to be read if (!(output.isRegistered())) output.register(this.selector, 0); input.register(this.selector, SelectionKey.OP_READ); }
/** {@inheritDoc} */ @Override public String toString() { return S.toString(IpcSharedMemoryServerEndpoint.class, this); }