docs: public T take() throws Throwable {
      dataLock.lock();      
      try {
        while(data == null && error == null) {
          try {
            availableCondition.await();
          } catch(InterruptedException e) {
            // ignore and re-loop in case of spurious wake-ups
          }
        }
        
        // should only get to here if data or error is non-null
        return getAndClearUnderLock();
      } finally {
        dataLock.unlock();
      }
    }