private FetchEmitTuple pollNext() throws TikaTimeoutException {

            FetchEmitTuple t = null;
            long start = System.currentTimeMillis();
            try {
                long elapsed = System.currentTimeMillis() - start;
                while (t == null && elapsed < maxWaitMs) {
                    checkThreadOk();
                    t = queue.poll(100, TimeUnit.MILLISECONDS);
                    elapsed = System.currentTimeMillis() - start;
                }
            } catch (InterruptedException e) {
                LOGGER.warn("interrupted");
                return COMPLETED_SEMAPHORE;
            }
            if (t == null) {
                throw new TikaTimeoutException(
                        "waited longer than " + maxWaitMs + "ms for the next tuple");
            }
            return t;
        }
Abstract class that handles the testing for timeouts/thread safety
issues.  Concrete classes implement the blocking {@link #enqueue()}.
If there's an exception in the enqueuing thread, this will throw
a RuntimeException.  It will throw an IllegalStateException if
next() is called after hasNext() has returned false.
tika-core/src/main/java/org/apache/tika/pipes/pipesiterator/PipesIterator.java