public void reserveCell() throws InterruptedException {
        logger.debug("reserve message.");
        if (used.get() == size) {
            synchronized (dispatcherLock) {
                while (used.get() == size) {
                    logger.debug("window is full.");
                    dispatcherLock.wait();
                }
            }
        }
        used.incrementAndGet();
        if (buffer.get(tail) != null) {
            logger.error("tail {} is not null {}", tail, buffer.get(tail));
        }
        if (tail == last) {
            base += size;
            logger.debug("new base {}. cell {} is reserved.", base, tail);
            tail = 0;
        } else {
            logger.debug("cell {} is reserved.", tail);
            ++tail;
        }
    }