code: public boolean acquireUpgradableLock(long timeout)
          throws InterruptedException, IllegalStateException
      {
          LockInfo info = (LockInfo)mLockInfoRef.get();
          int type = info.mType;
  
          if (type == READ) {
              throw new IllegalStateException
                  ("Cannot acquire an upgradable lock while thread holds " +
                   "only a read lock.");
          }
  
          if (type == NONE) {
              synchronized (this) {
                  if (!upgradableLockAvailable()) {
                      if (timeout < 0) {
                          while (true) {
                              wait();
                              if (upgradableLockAvailable()) {
                                  break;
                              }
                          }
                      }
                      else if (timeout > 0) {
                          long expire = System.currentTimeMillis() + timeout;
                          while (true) {
                              wait(timeout);
                              if (upgradableLockAvailable()) {
                                  break;
                              }
                              timeout = expire - System.currentTimeMillis();
                              if (timeout <= 0) {
                                  return false;
                              }
                          };
                      }
                      else {
                          return false;
                      }
                  }
                  mUpgradableLockHeld = Thread.currentThread();
              }
              info.mType = UPGRADABLE;
          }     
  
          info.mCount++;
          return true;
      }
docs: An upgradable lock is obtained when no threads currently hold write or
  upgradable locks. When a thread has an upgradable lock, it blocks
  threads that wish to acquire upgradable or write locks.
  <p>
  Upgradable locks are to be used when a thread needs a read lock, but
  while that read lock is held, it may need to be upgraded to a write
  lock. If a thread acquired a read lock and then attempted to
  acquire a write lock while the first lock was held, the thread
  would be deadlocked with itself.
  <p>
  To prevent deadlock, threads that may need to upgrade a read lock
  to a write lock should acquire an upgradable lock instead of a read
  lock. Upgradable locks will not block threads that wish to only read.
  <p>
  To perform an upgrade, call acquireWriteLock while the upgradable
  lock is still held.
  
  @param timeout milliseconds to wait for lock acquisition. If negative,
  timeout is infinite.
  @return true if the lock was acquired.
  @throws IllegalStateException if thread holds a read lock.