private E parkUntilNext(E[] buffer, long cIndex, long offset, long timeoutNs) throws InterruptedException {
        E e;
        final long pIndex = lvProducerIndex();
        if (cIndex == pIndex && // queue is empty
            casProducerIndex(pIndex, pIndex + 1)) // we announce ourselves as parked by setting parity
        {
            // producers only try a wakeup when both the index and the blocked thread are visible, otherwise they spin
            soBlocked(Thread.currentThread());
            // ignore deadline when it's forever
            final long deadlineNs = timeoutNs == Long.MAX_VALUE ? 0 : System.nanoTime() + timeoutNs;

            try
            {
                while (true)
                {
                    LockSupport.parkNanos(this, timeoutNs);
                    if (Thread.interrupted())
                    {
                        casProducerIndex(pIndex + 1, pIndex);
                        throw new InterruptedException();
                    }
                    if ((lvProducerIndex() & 1) == 0) {
                        break;
                    }
                    // ignore deadline when it's forever
                    timeoutNs = timeoutNs == Long.MAX_VALUE ? Long.MAX_VALUE : deadlineNs - System.nanoTime();
                    if (timeoutNs <= 0)
                    {
                        if (casProducerIndex(pIndex + 1, pIndex))
                        {
                            // ran out of time and the producer has not moved the index
                            return null;
                        }

                        break; // just in the nick of time
                    }
                }
            }
            finally
            {
                soBlocked(null);
            }
        }
        // producer index is visible before element, so if we wake up between the index moving and the element
        // store we could see a null.
        e = spinWaitForElement(buffer, offset);

        soRefElement(buffer, offset, null); // release element null
        soConsumerIndex(cIndex + 2); // release cIndex

        return e;
    }
{@inheritDoc}
<p>
This implementation is correct for single consumer thread use only.
jctools-core/src/main/java/org/jctools/queues/MpscBlockingConsumerArrayQueue.java