/** * @return whether the stream is open */ public boolean isOpen() { try (LockResource lr = new LockResource(mLock)) { return !mClosed && !mCanceled && mError == null; } }
/** * Releases the lock and decrement the ref count if a ref counter was provided * at construction time. */ @Override public void close() { super.close(); mRefCount.decrementAndGet(); } }
@Test(timeout = 1000) public void referencedLockTest() throws InterruptedException { LockResource lock0 = mCache.get(0, LockMode.READ); LockResource lock1 = mCache.get(50, LockMode.READ); LockResource lock2 = mCache.get(100, LockMode.READ); for (int j = 0; j < 10; j++) { for (int i = 0; i < 100; i++) { mCache.get(i, LockMode.READ).close(); } } assertTrue(lock0.hasSameLock(mCache.get(0, LockMode.READ))); assertTrue(lock1.hasSameLock(mCache.get(50, LockMode.READ))); assertTrue(lock2.hasSameLock(mCache.get(100, LockMode.READ))); } }
@Override public final State getState() { try (LockResource lr = new LockResource(mStateLock)) { return mState; } }
@Override public void close() { mLockedInodes.clear(); mEntries.forEach(entry -> entry.mLock.close()); mEntries.clear(); }
/** * @return the set of threads present in the scheduler */ public static Set<String> getThreadNames() { try (LockResource r = new LockResource(sLock)) { return sTimers.keySet(); } }
/** * Unlocks the last locked edge. */ public void unlockLastEdge() { Preconditions.checkState(!endsInInode()); Preconditions.checkState(!mEntries.isEmpty()); mEntries.remove(mEntries.size() - 1).mLock.close(); mLockMode = LockMode.READ; }
@Override public final void waitForState(State state) throws InterruptedException { try (LockResource lr = new LockResource(mStateLock)) { while (mState != state) { mStateCond.await(); } } } }
@Override public void close() throws UnavailableException { try { mContext.close(); } finally { // The journal must be flushed before we can release the lock. mLockResource.close(); } } }
/** * Removes a timer name from the scheduler if it exists. * * @param name the name to clear */ public static void clearTimer(String name) { try (LockResource r = new LockResource(sLock)) { sTimers.remove(name); } }
/** * Unlocks the last locked inode. */ public void unlockLastInode() { Preconditions.checkState(endsInInode()); Preconditions.checkState(!mEntries.isEmpty()); mLockedInodes.remove(mLockedInodes.size() - 1); mEntries.remove(mEntries.size() - 1).mLock.close(); mLockMode = LockMode.READ; }
/** * @param clazz the class of the {@link Server} to add * @param server the {@link Server} to add * @param <W> the type of the {@link Server} to add */ public <W extends T> void add(Class<W> clazz, T server) { try (LockResource r = new LockResource(mLock)) { mRegistry.put(clazz, server); } }
/** * Downgrades the last inode from a write lock to a read lock. The read lock is acquired before * releasing the write lock. */ public void downgradeLastInode() { Preconditions.checkState(endsInInode()); Preconditions.checkState(!mEntries.isEmpty()); Preconditions.checkState(mLockMode == LockMode.WRITE); InodeEntry last = (InodeEntry) mEntries.get(mEntries.size() - 1); LockResource lock = mInodeLockManager.lockInode(last.getInode(), LockMode.READ); last.getLock().close(); mEntries.set(mEntries.size() - 1, new InodeEntry(lock, last.mInode)); mLockMode = LockMode.READ; }
/** * Waits for the given thread to be ready to be scheduled. * * @param name a name of the thread to wait for * @throws InterruptedException if the waiting thread is interrupted */ public static void await(String name) throws InterruptedException { try (LockResource r = new LockResource(sLock)) { while (!sTimers.containsKey(name)) { sCondition.await(); } } }
/** * Downgrades the edge at the specified entry index. */ private void downgradeEdge(int edgeEntryIndex) { EdgeEntry entry = (EdgeEntry) mEntries.get(edgeEntryIndex); LockResource lock = mInodeLockManager.lockEdge(entry.mEdge, LockMode.READ); entry.getLock().close(); mEntries.set(edgeEntryIndex, new EdgeEntry(lock, entry.getEdge())); }
protected final void setState(State state) { try (LockResource lr = new LockResource(mStateLock)) { mState = state; mStateCond.signalAll(); synchronized (mListeners) { mListeners.forEach(listener -> listener.get().accept(state)); } LOG.info("Primary selector transitioning to {}", state); } }
/** * Downgrades from edge write-locking to inode write-locking. This reduces the scope of the write * lock by pushing it forward one entry. * * For example, if the lock list is in write mode with entries [a, a->b, b, b->c], * downgradeEdgeToInode(c, mode) will change the list to [a, a->b, b, b->c, c], with b->c * downgraded to a read lock. c will be locked according to the mode. * * The read lock on the final edge is taken before releasing the write lock. * * @param inode the next inode in the lock list * @param mode the mode to downgrade to */ public void downgradeEdgeToInode(Inode inode, LockMode mode) { Preconditions.checkState(!endsInInode()); Preconditions.checkState(!mEntries.isEmpty()); Preconditions.checkState(mLockMode == LockMode.WRITE); EdgeEntry last = (EdgeEntry) mEntries.get(mEntries.size() - 1); LockResource inodeLock = mInodeLockManager.lockInode(inode, mode); LockResource edgeLock = mInodeLockManager.lockEdge(last.mEdge, LockMode.READ); last.getLock().close(); mEntries.set(mEntries.size() - 1, new EdgeEntry(edgeLock, last.getEdge())); mEntries.add(new InodeEntry(inodeLock, inode)); mLockedInodes.add(inode); mLockMode = mode; }
/** * Releases an object of type T, this must be called after the thread is done using a resource * obtained by acquire. * * @param resource the resource to be released, it should not be reused after calling this method */ @Override public void release(T resource) { if (resource != null) { mResources.add(resource); try (LockResource r = new LockResource(mTakeLock)) { mNotEmpty.signal(); } } }
private void edgeLockTest(LockMode take, LockMode tryToTake, boolean expectBlocking) throws Exception { InodeLockManager lockManager = new InodeLockManager(); AtomicBoolean threadFinished = new AtomicBoolean(false); LockResource lock = lockManager.lockEdge(new Edge(10, "name"), take); Thread t = new Thread(() -> { // Use a new Edge each time to make sure we aren't comparing edges by reference. try (LockResource lr = lockManager.lockEdge(new Edge(10, "name"), tryToTake)) { threadFinished.set(true); } }); t.start(); if (expectBlocking) { CommonUtils.sleepMs(20); assertFalse(threadFinished.get()); lock.close(); } CommonUtils.waitFor("lock to be acquired by the second thread", () -> threadFinished.get()); } }
/** * Waits until the given thread can be executed, throwing an unchecked exception of the given * timeout expires. * * @param name a name of the thread to wait for * @param time the maximum time to wait * @param unit the time unit of the {@code time} argument * @throws InterruptedException if the waiting thread is interrupted */ public static void await(String name, long time, TimeUnit unit) throws InterruptedException { try (LockResource r = new LockResource(sLock)) { while (!sTimers.containsKey(name)) { if (!sCondition.await(time, unit)) { throw new RuntimeException( "Timed out waiting for thread " + name + " to be ready for scheduling"); } } } }