@Test public void multipleThreadsOfCurrentJvmSameVersion() throws Exception { final PathLocker<SrcVersion> pathLocker = new PathLocker<>(); final Path dir1 = lockerDirectory.resolve(UUID.randomUUID().toString()); final SrcVersion srcVersion = SrcVersion.parse("1.2.3-SRC-revision-deadbeef"); Future<PathLock> concurrLockFuture = null; try (PathLock lock1 = pathLocker.lockDirectory("org.srcdeps.example", dir1, srcVersion)) { try { concurrLockFuture = lockConcurrently(pathLocker, dir1, srcVersion); concurrLockFuture.get(1, TimeUnit.SECONDS); Assert.fail("TimeoutException expected"); } catch (InterruptedException e) { throw e; } catch (ExecutionException e) { throw e; } catch (TimeoutException e) { } } PathLock lock2 = concurrLockFuture.get(1, TimeUnit.SECONDS); Assert.assertNotNull(lock2); }
public PathLock lockDirectory(String requestId, Path path, M pathMetadata) throws IOException, CannotAcquireLockException { SrcdepsCoreUtils.ensureDirectoryExists(path); final LockMetadataPair<M> newPair = new LockMetadataPair<M>(new ReentrantLock(), pathMetadata); final LockMetadataPair<M> oldPair = locks.putIfAbsent(path, newPair); final LockMetadataPair<M> mdPair = oldPair == null ? newPair : oldPair; synchronized (mdPair) { final ReentrantLock lock = mdPair.getLock(); final M oldMd = mdPair.getMetadata(); if (oldMd.equals(pathMetadata)) { lock.lock(); log.debug("srcdeps[{}]: Locked on thread level [{}]", requestId, path); return lockInFilesystem(requestId, path, lock); } else { if (lock.tryLock()) { log.debug("srcdeps[{}]: Locked on thread level [{}]", requestId, path); mdPair.setMetadata(pathMetadata); return lockInFilesystem(requestId, path, lock); } else { throw new CannotAcquireLockException( String.format("Path [%s] is locked by another thread for [%s]", path, oldPair)); } } } }
PathLocker { public PathLock lockDirectory(String requestId, Path path, M pathMetadata) throws IOException, CannotAcquireLockException { SrcdepsCoreUtils.ensureDirectoryExists(path); final LockMetadataPair<M> newPair = new LockMetadataPair<M>(new ReentrantLock(), pathMetadata); final LockMetadataPair<M> oldPair = locks.putIfAbsent(path, newPair); final LockMetadataPair<M> mdPair = oldPair == null ? newPair : oldPair; synchronized (mdPair) { final ReentrantLock lock = mdPair.getLock(); final M oldMd = mdPair.getMetadata(); if (oldMd.equals(pathMetadata)) { lock.lock(); log.debug("srcdeps[{}]: Locked on thread level [{}]", requestId, path); return lockInFilesystem(requestId, path, lock); } else { if (lock.tryLock()) { log.debug("srcdeps[{}]: Locked on thread level [{}]", requestId, path); mdPair.setMetadata(pathMetadata); return lockInFilesystem(requestId, path, lock); } else { throw new CannotAcquireLockException( String.format("Path [%s] is locked by another thread for [%s]", path, oldPair)); } } } } }
PathLocker { public PathLock lockDirectory(String requestId, Path path, M pathMetadata) throws IOException, CannotAcquireLockException { SrcdepsCoreUtils.ensureDirectoryExists(path); final LockMetadataPair<M> newPair = new LockMetadataPair<M>(new ReentrantLock(), pathMetadata); final LockMetadataPair<M> oldPair = locks.putIfAbsent(path, newPair); final LockMetadataPair<M> mdPair = oldPair == null ? newPair : oldPair; synchronized (mdPair) { final ReentrantLock lock = mdPair.getLock(); final M oldMd = mdPair.getMetadata(); if (oldMd.equals(pathMetadata)) { lock.lock(); log.debug("srcdeps[{}]: Locked on thread level [{}]", requestId, path); return lockInFilesystem(requestId, path, lock); } else { if (lock.tryLock()) { log.debug("srcdeps[{}]: Locked on thread level [{}]", requestId, path); mdPair.setMetadata(pathMetadata); return lockInFilesystem(requestId, path, lock); } else { throw new CannotAcquireLockException( String.format("Path [%s] is locked by another thread for [%s]", path, oldPair)); } } } }  }
PathLocker { public PathLock lockDirectory(String requestId, Path path, M pathMetadata) throws IOException, CannotAcquireLockException { SrcdepsCoreUtils.ensureDirectoryExists(path); final LockMetadataPair<M> newPair = new LockMetadataPair<M>(new ReentrantLock(), pathMetadata); final LockMetadataPair<M> oldPair = locks.putIfAbsent(path, newPair); final LockMetadataPair<M> mdPair = oldPair == null ? newPair : oldPair; synchronized (mdPair) { final ReentrantLock lock = mdPair.getLock(); final M oldMd = mdPair.getMetadata(); if (oldMd.equals(pathMetadata)) { lock.lock(); log.debug("srcdeps[{}]: Locked on thread level [{}]", requestId, path); return lockInFilesystem(requestId, path, lock); } else { if (lock.tryLock()) { log.debug("srcdeps[{}]: Locked on thread level [{}]", requestId, path); mdPair.setMetadata(pathMetadata); return lockInFilesystem(requestId, path, lock); } else { throw new CannotAcquireLockException( String.format("Path [%s] is locked by another thread for [%s]", path, oldPair)); } } } }  PathLock lockDirectory(String requestId, Path path, M pathMetadata); }
PathLocker { public PathLock lockDirectory(String requestId, Path path, M pathMetadata) throws IOException, CannotAcquireLockException { SrcdepsCoreUtils.ensureDirectoryExists(path); final LockMetadataPair<M> newPair = new LockMetadataPair<M>(new ReentrantLock(), pathMetadata); final LockMetadataPair<M> oldPair = locks.putIfAbsent(path, newPair); final LockMetadataPair<M> mdPair = oldPair == null ? newPair : oldPair; synchronized (mdPair) { final ReentrantLock lock = mdPair.getLock(); final M oldMd = mdPair.getMetadata(); if (oldMd.equals(pathMetadata)) { lock.lock(); log.debug("srcdeps[{}]: Locked on thread level [{}]", requestId, path); return lockInFilesystem(requestId, path, lock); } else { if (lock.tryLock()) { log.debug("srcdeps[{}]: Locked on thread level [{}]", requestId, path); mdPair.setMetadata(pathMetadata); return lockInFilesystem(requestId, path, lock); } else { throw new CannotAcquireLockException( String.format("Path [%s] is locked by another thread for [%s]", path, oldPair)); } } } }  PathLock lockDirectory(String requestId, Path path, M pathMetadata);  }