/** * Sets the Listener that will be triggered for completed write operations on the matching * {@link Sink} and upon close and exhaustion. * * <p>Note that this Listener MAY NOT under any circumstances throw an exception. If it does so, * it will NOT be propagated outside of the Pipe, since the concurrent nature of this interface * makes it unreasonable to try to choose a relevant stack to propagate such an exception up * through. */ public void setListener(Listener<ReadHead<$T>> $el) { DataPipe.this.$el = $el; // it's possible that there wasn't a listener before this, and we need to make sure we fire an // event now in case there aren't any more writes forthcoming for a while (if indeed ever). // this can be "spurious", since it doesn't actually come as news of a write, but it's // terribly important not to ignore this. boolean $mustSpur = false; lockWrite(); if (SRC.hasNext()) $mustSpur = true; unlockWrite(); /* we prefer to release locks before we let the listener go on a tear, just as a matter of best/simplest practice. */ if ($mustSpur) invokeListener(DataPipe.this.$el); }
/** * Closes the pipe. No more data will be allowed to be written to this Pipe's WriteHead. Any * blocked {@link DataPipe.Source#readAll()} will return whatever data they can, and other * blocked {@link DataPipe.Source#read()} will immediately return null following this call even * if they cannot get data (these two processes still happen in fair order). All subsequent * reads (blocking or nonblocking) will either return data immediately as long as any is still * buffered in the pipe, and then forevermore immediately return null once all buffered data is * depleted. */ public void close() { SRC.close(); }