public void unlock() {
   Thread caller = Thread.currentThread();
   for (; ; ) {
     WaitQueue.WaitNode w = getSignallee(caller);
     if (w == null) return; // no one to signal
     if (w.signal(this)) return; // notify if still waiting, else skip
   }
 }
 public void lock() {
   Thread caller = Thread.currentThread();
   synchronized (this) {
     if (owner_ == null) {
       owner_ = caller;
       holds_ = 1;
       return;
     } else if (caller == owner_) {
       incHolds();
       return;
     }
   }
   WaitQueue.WaitNode n = new WaitQueue.WaitNode();
   n.doWaitUninterruptibly(this);
 }
 public boolean tryLock(long nanos) throws InterruptedException {
   if (Thread.interrupted()) throw new InterruptedException();
   Thread caller = Thread.currentThread();
   synchronized (this) {
     if (owner_ == null) {
       owner_ = caller;
       holds_ = 1;
       return true;
     } else if (caller == owner_) {
       incHolds();
       return true;
     }
   }
   WaitQueue.WaitNode n = new WaitQueue.WaitNode();
   return n.doTimedWait(this, nanos);
 }
 public void lockInterruptibly() throws InterruptedException {
   if (Thread.interrupted()) throw new InterruptedException();
   Thread caller = Thread.currentThread();
   synchronized (this) {
     if (owner_ == null) {
       owner_ = caller;
       holds_ = 1;
       return;
     } else if (caller == owner_) {
       incHolds();
       return;
     }
   }
   WaitQueue.WaitNode n = new WaitQueue.WaitNode();
   n.doWait(this);
 }
 public synchronized void takeOver(WaitQueue.WaitNode node) {
   // assert (holds_ == 1 && owner_ == Thread.currentThread()
   owner_ = node.getOwner();
 }