code: public Node<E> offerAndGetNode(E e) {
          mPutLock.lock();
          try {
              Node newNode = mNodePool.borrowNode(e);
              if (mSize.get() > 0)
                  newNode.mPrev = mTail;
              mTail.mNext = newNode;
              if (mSize.get() <= 1) {
                  mPollLock.lock();
                  try {
                      if (mSize.get() == 0)
                          mHead.mNext = newNode;
                      else
                          mHead.mNext = newNode.mPrev;
                  }
                  finally {
                      mPollLock.unlock();
                  }
              }
              mSize.incrementAndGet();
              mTail = newNode;
              return newNode;
          }
          finally {
              mPutLock.unlock();
          }
      }
docs: Add a new item to the tail of the queue and return a Node reference.
  This reference can be used as a handle that can be passed to
  remove(Node) where constand time removes are necessary.  Calls to
  this method and poll() do not mutually block, however, concurrent
  calls to this method are serialized.