From 0ead764edf043e4faa5da814f1128d4158d645ad Mon Sep 17 00:00:00 2001 From: leventov Date: Mon, 18 Jan 2016 17:34:14 +0300 Subject: [PATCH] BigSegmentHeader: try deregister wait on try-upgrade-update-to-write procedure, if it sees unexpected state (update lock is not held) --- .../chronicle/hash/impl/BigSegmentHeader.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/hash/impl/BigSegmentHeader.java b/src/main/java/net/openhft/chronicle/hash/impl/BigSegmentHeader.java index 5d3abef8a..375eb94d8 100644 --- a/src/main/java/net/openhft/chronicle/hash/impl/BigSegmentHeader.java +++ b/src/main/java/net/openhft/chronicle/hash/impl/BigSegmentHeader.java @@ -427,7 +427,7 @@ public final class BigSegmentHeader implements SegmentHeader { long end = System.nanoTime() + timeInNanos; registerWait(address); do { - if (LOCK.tryUpgradeUpdateToWriteLockAndDeregisterWait(A, null, address + LOCK_OFFSET)) + if (tryUpgradeUpdateToWriteLockAndDeregisterWait0(address)) return true; detectInterruptionAndDeregisterWait(address, interruptible); } while (System.nanoTime() <= end); @@ -443,7 +443,7 @@ public final class BigSegmentHeader implements SegmentHeader { long lastTime = System.currentTimeMillis(); registerWait(address); do { - if (LOCK.tryUpgradeUpdateToWriteLockAndDeregisterWait(A, null, address + LOCK_OFFSET)) + if (tryUpgradeUpdateToWriteLockAndDeregisterWait0(address)) return true; detectInterruptionAndDeregisterWait(address, interruptible); long now = System.currentTimeMillis(); @@ -456,6 +456,22 @@ public final class BigSegmentHeader implements SegmentHeader { return false; } + private static boolean tryUpgradeUpdateToWriteLockAndDeregisterWait0(long address) { + try { + if (LOCK.tryUpgradeUpdateToWriteLockAndDeregisterWait(A, null, address + LOCK_OFFSET)) { + return true; + } + } catch (IllegalMonitorStateException e) { + try { + deregisterWait(address); + } catch (Throwable suppressed) { + e.addSuppressed(suppressed); + } + throw e; + } + return false; + } + @Override public void readUnlock(long address) { LOCK.readUnlock(A, null, address + LOCK_OFFSET);