Package freenet.store.saltedhash

Source Code of freenet.store.saltedhash.LockManager

/* This code is part of Freenet. It is distributed under the GNU General
* Public License, version 2 (or at your option any later version). See
* http://www.gnu.org/ for further details of the GPL. */
package freenet.store.saltedhash;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import freenet.support.Logger;
import freenet.support.Logger.LogLevel;

/**
* Lock Manager
*
* Handle locking/unlocking of individual offsets.
*
* @author sdiz
*/
public class LockManager {
  private static boolean logDEBUG;
  private volatile boolean shutdown;
  private Lock entryLock = new ReentrantLock();
  private Map<Long, Condition> lockMap = new HashMap<Long, Condition>();

  LockManager() {
    logDEBUG = Logger.shouldLog(LogLevel.DEBUG, this);
  }

  /**
   * Lock the entry
   *
   * This lock is <strong>not</strong> re-entrance. No threads except Cleaner should hold more
   * then one lock at a time (or deadlock may occur).
   */
  Condition lockEntry(long offset) {
    if (logDEBUG)
      Logger.debug(this, "try locking " + offset, new Exception());

    Condition condition;
    try {
      entryLock.lock();
      try {
        do {
          if (shutdown)
            return null;

          Condition lockCond = lockMap.get(offset);
          if (lockCond != null)
            lockCond.await(10, TimeUnit.SECONDS); // 10s for checking shutdown
          else
            break;
        } while (true);
        condition = entryLock.newCondition();
        lockMap.put(offset, condition);
      } finally {
        entryLock.unlock();
      }
    } catch (InterruptedException e) {
      Logger.error(this, "lock interrupted", e);
      return null;
    }

    if (logDEBUG)
      Logger.debug(this, "locked " + offset, new Exception());
    return condition;
  }

  /**
   * Unlock the entry
   */
  void unlockEntry(long offset, Condition condition) {
    if (logDEBUG)
      Logger.debug(this, "unlocking " + offset, new Exception("debug"));

    entryLock.lock();
    try {
      Condition cond = lockMap.remove(offset);
      assert cond == condition;
      cond.signal();
    } finally {
      entryLock.unlock();
    }
  }

  /**
   * Shutdown and wait for all entries unlocked
   */
  void shutdown() {
    shutdown = true;
    entryLock.lock();
    try {
      while (!lockMap.isEmpty()) {
        Condition cond = lockMap.values().iterator().next();
        cond.awaitUninterruptibly();
      }
    } finally {
      entryLock.unlock();
    }
  }
}
TOP

Related Classes of freenet.store.saltedhash.LockManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.