private List<Path> lockInternal(final Path[] uris, final boolean exclusive) { // Always try to lock a set of URIs in the same order to reduce chance of deadlocking. Arrays.sort(uris); final List<Path> claimedLocks = new ArrayList<Path>(uris.length); for (Path uri : uris) { final PathLock lock = getLock(uri); // Request lock object for path if (lock.tryLock(this.lockTimeoutSeconds, TimeUnit.SECONDS, exclusive)) { claimedLocks.add(uri); if (this.logger.isDebugEnabled()) { this.logger.debug("suceeded: locking " + uri); } } else { try { if (this.logger.isDebugEnabled()) { this.logger.debug( "failed: locking " + uri + (exclusive ? " in exclusive mode" : " in shared mode") + " due to interrupt or timeout (" + this.lockTimeoutSeconds + " seconds)"); } throw new RuntimeException( "Thread " + Thread.currentThread().getName() + " giving up locking " + uri + (exclusive ? " in exclusive mode " : " in shared mode") + " due to interrupt or timeout (" + this.lockTimeoutSeconds + " seconds)"); } finally { // Clean up, we failed. // Return current lock, so it may be disposed of. returnLock(lock); // Release any locks we managed to claim as well. unlock(claimedLocks, exclusive); } } } return Collections.unmodifiableList(claimedLocks); }
private void unlockInternal(Path uri, boolean exclusive) { PathLock lock = null; synchronized (this.locks) { lock = this.locks.get(uri); if (lock == null) { throw new IllegalStateException( "Thread " + Thread.currentThread().getName() + " tried to release lock on path '" + uri + "', but there is currently no registered lock for that path."); } if (logger.isDebugEnabled()) { logger.debug("releasing " + uri); } returnLock(lock); } lock.unlock(exclusive); // Allow other threads waiting for this lock to proceed }