Skip to content

Commit 7032e19

Browse files
authored
Improve DebugAwareFunctionalLock (#3098)
1 parent 2ac422c commit 7032e19

2 files changed

Lines changed: 25 additions & 48 deletions

File tree

engine/updategraph/src/main/java/io/deephaven/engine/updategraph/UpdateGraphLock.java

Lines changed: 21 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@
88
import io.deephaven.internal.log.LoggerFactory;
99
import io.deephaven.io.logger.Logger;
1010
import io.deephaven.util.FunctionalInterfaces;
11-
import io.deephaven.util.SafeCloseable;
1211
import io.deephaven.util.locks.AwareFunctionalLock;
1312
import org.apache.commons.lang3.exception.ExceptionUtils;
1413
import org.apache.commons.lang3.mutable.MutableBoolean;
1514
import org.jetbrains.annotations.NotNull;
1615
import org.jetbrains.annotations.Nullable;
1716

18-
import java.util.ArrayDeque;
1917
import java.util.Deque;
18+
import java.util.concurrent.ConcurrentLinkedDeque;
2019
import java.util.concurrent.TimeUnit;
2120
import java.util.concurrent.locks.Condition;
2221
import java.util.concurrent.locks.Lock;
@@ -105,13 +104,8 @@ public static void installInstrumentation(@Nullable final Instrumentation instru
105104
rwLock = new ReentrantReadWriteLock(true);
106105
readLock = rwLock.readLock();
107106
writeLock = rwLock.writeLock();
108-
if (allowUnitTestMode) {
109-
sharedLock = new DebugAwareFunctionalLock(new SharedLock());
110-
exclusiveLock = new DebugAwareFunctionalLock(new ExclusiveLock());
111-
} else {
112-
sharedLock = new SharedLock();
113-
exclusiveLock = new ExclusiveLock();
114-
}
107+
sharedLock = new SharedLock();
108+
exclusiveLock = allowUnitTestMode ? new DebugAwareFunctionalLock(new ExclusiveLock()) : new ExclusiveLock();
115109
this.allowUnitTestMode = allowUnitTestMode;
116110
}
117111

@@ -306,10 +300,10 @@ public final Condition newCondition() {
306300

307301
// region DebugLock
308302
class DebugAwareFunctionalLock implements AwareFunctionalLock {
309-
private final AwareFunctionalLock delegate;
310-
private final Deque<Throwable> lockingContext = new ArrayDeque<>();
303+
private final ExclusiveLock delegate;
304+
private final Deque<Throwable> lockingContext = new ConcurrentLinkedDeque<>();
311305

312-
DebugAwareFunctionalLock(AwareFunctionalLock delegate) {
306+
DebugAwareFunctionalLock(ExclusiveLock delegate) {
313307
this.delegate = delegate;
314308
}
315309

@@ -321,19 +315,19 @@ public boolean isHeldByCurrentThread() {
321315
@Override
322316
public void lock() {
323317
delegate.lock();
324-
lockingContext.push(new Throwable());
318+
pushContext();
325319
}
326320

327321
@Override
328322
public void lockInterruptibly() throws InterruptedException {
329323
delegate.lockInterruptibly();
330-
lockingContext.push(new Throwable());
324+
pushContext();
331325
}
332326

333327
@Override
334328
public boolean tryLock() {
335329
if (delegate.tryLock()) {
336-
lockingContext.push(new Throwable());
330+
pushContext();
337331
return true;
338332
}
339333
return false;
@@ -342,16 +336,16 @@ public boolean tryLock() {
342336
@Override
343337
public boolean tryLock(long time, @NotNull TimeUnit unit) throws InterruptedException {
344338
if (delegate.tryLock(time, unit)) {
345-
lockingContext.push(new Throwable());
339+
pushContext();
346340
return true;
347341
}
348342
return false;
349343
}
350344

351345
@Override
352346
public void unlock() {
353-
delegate.unlock();
354347
lockingContext.pop();
348+
delegate.unlock();
355349
}
356350

357351
@NotNull
@@ -360,37 +354,20 @@ public Condition newCondition() {
360354
return delegate.newCondition();
361355
}
362356

363-
@Override
364-
public <EXCEPTION_TYPE extends Exception> void doLocked(
365-
@NotNull FunctionalInterfaces.ThrowingRunnable<EXCEPTION_TYPE> runnable) throws EXCEPTION_TYPE {
366-
delegate.doLocked(runnable);
367-
}
368-
369-
@Override
370-
public <EXCEPTION_TYPE extends Exception> void doLockedInterruptibly(
371-
@NotNull FunctionalInterfaces.ThrowingRunnable<EXCEPTION_TYPE> runnable)
372-
throws InterruptedException, EXCEPTION_TYPE {
373-
delegate.doLockedInterruptibly(runnable);
374-
}
375-
376-
@Override
377-
public <RESULT_TYPE, EXCEPTION_TYPE extends Exception> RESULT_TYPE computeLocked(
378-
@NotNull FunctionalInterfaces.ThrowingSupplier<RESULT_TYPE, EXCEPTION_TYPE> supplier)
379-
throws EXCEPTION_TYPE {
380-
return delegate.computeLocked(supplier);
381-
}
382-
383-
@Override
384-
public <RESULT_TYPE, EXCEPTION_TYPE extends Exception> RESULT_TYPE computeLockedInterruptibly(
385-
@NotNull FunctionalInterfaces.ThrowingSupplier<RESULT_TYPE, EXCEPTION_TYPE> supplier)
386-
throws InterruptedException, EXCEPTION_TYPE {
387-
return delegate.computeLockedInterruptibly(supplier);
388-
}
389-
390357
String getDebugMessage() {
391358
final Throwable item = lockingContext.peek();
392359
return item == null ? "locking context is empty" : ExceptionUtils.getStackTrace(item);
393360
}
361+
362+
private void pushContext() {
363+
// Implementation must have already acquired lock
364+
try {
365+
lockingContext.push(new Throwable());
366+
} catch (Throwable t) {
367+
delegate.unlock();
368+
throw t;
369+
}
370+
}
394371
}
395372
// endregion DebugLock
396373

engine/updategraph/src/main/java/io/deephaven/engine/updategraph/UpdateGraphProcessor.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -575,16 +575,16 @@ public void enableUnitTestMode() {
575575
}
576576

577577
private void assertLockAvailable(@NotNull final String action) {
578-
if (!UpdateGraphProcessor.DEFAULT.exclusiveLock().tryLock()) {
578+
final AwareFunctionalLock exclusiveLock = UpdateGraphProcessor.DEFAULT.exclusiveLock();
579+
if (!exclusiveLock.tryLock()) {
579580
log.error().append("Lock is held when ").append(action).append(", with previous holder: ")
580581
.append(unitTestModeHolder).endl();
581582
ThreadDump.threadDump(System.err);
582-
UpdateGraphLock.DebugAwareFunctionalLock lock =
583-
(UpdateGraphLock.DebugAwareFunctionalLock) UpdateGraphProcessor.DEFAULT.exclusiveLock();
583+
UpdateGraphLock.DebugAwareFunctionalLock lock = (UpdateGraphLock.DebugAwareFunctionalLock) exclusiveLock;
584584
throw new IllegalStateException(
585585
"Lock is held when " + action + ", with previous holder: " + lock.getDebugMessage());
586586
}
587-
UpdateGraphProcessor.DEFAULT.exclusiveLock().unlock();
587+
exclusiveLock.unlock();
588588
}
589589

590590
/**

0 commit comments

Comments
 (0)