code: public Reason wait(T waiter, long timeout, TimeUnit unit)
      {
          if (list == null)
          {
              return Reason.Release;
          }
          try
          {
              Locks.locked(lock, waiter, (w)->{list.add(w);});
              if (semaphore.tryAcquire(timeout, unit))
              {
                  return Reason.Release;
              }
              else
              {
                  list.remove(waiter);
                  return Reason.Timeout;
              }
          }
docs: Adds waiter to queue and waits until releaseAll method call or thread is
  interrupted or timeout.
  <p>If releaseAll is called already return Release.
  @param waiter
  @param timeout
  @param unit
  @return