use of net.openhft.chronicle.core.StackTrace in project Chronicle-Queue by OpenHFT.
the class TableStoreWriteLock method lock.
/**
* Guaranteed to succeed in getting the lock (may involve timeout and recovery) or else throw.
* <p>This is not re-entrant i.e. if you lock and try and lock again it will timeout and recover
*/
@Override
public void lock() {
throwExceptionIfClosed();
assert checkNotAlreadyLocked();
long currentLockValue = 0;
TimingPauser tlPauser = pauser.get();
try {
currentLockValue = lock.getVolatileValue();
while (!lock.compareAndSwapValue(UNLOCKED, PID)) {
if (Thread.currentThread().isInterrupted())
throw new InterruptedRuntimeException("Interrupted for the lock file:" + path);
tlPauser.pause(timeout, TimeUnit.MILLISECONDS);
currentLockValue = lock.getVolatileValue();
}
// noinspection ConstantConditions,AssertWithSideEffects
assert (lockedByThread = Thread.currentThread()) != null && (lockedHere = new StackTrace()) != null;
// success
} catch (TimeoutException e) {
final String lockedBy = getLockedBy(currentLockValue);
final String warningMsg = "Couldn't acquire write lock " + "after " + timeout + " ms " + "for the lock file:" + path + ". " + "Lock was held by " + lockedBy;
if (forceUnlockOnTimeoutWhen == UnlockMode.NEVER)
throw new UnrecoverableTimeoutException(new IllegalStateException(warningMsg + UNLOCK_MAIN_MSG));
else if (forceUnlockOnTimeoutWhen == UnlockMode.LOCKING_PROCESS_DEAD) {
if (forceUnlockIfProcessIsDead())
lock();
else
throw new UnrecoverableTimeoutException(new IllegalStateException(warningMsg + UNLOCK_MAIN_MSG));
} else {
warn().on(getClass(), warningMsg + UNLOCKING_FORCIBLY_MSG);
forceUnlock(currentLockValue);
lock();
}
} finally {
tlPauser.reset();
}
}
use of net.openhft.chronicle.core.StackTrace in project Chronicle-Queue by OpenHFT.
the class AbstractTSQueueLock method forceUnlock.
/**
* will only force unlock if you give it the correct pid
*/
protected void forceUnlock(long value) {
boolean unlocked = lock.compareAndSwapValue(value, UNLOCKED);
Jvm.warn().on(getClass(), "" + "Forced unlock for the " + "lock file:" + path + ", " + "lockKey: " + lockKey + ", " + "unlocked: " + unlocked, new StackTrace("Forced unlock"));
}
use of net.openhft.chronicle.core.StackTrace in project Chronicle-Queue by OpenHFT.
the class SingleTableStore method doWithLock.
// shared vs exclusive - see https://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileChannel.html
private static <T, R> R doWithLock(@NotNull final File file, @NotNull final Function<T, ? extends R> code, @NotNull final Supplier<T> target, final boolean shared) {
final String type = shared ? "shared" : "exclusive";
final StandardOpenOption readOrWrite = shared ? StandardOpenOption.READ : StandardOpenOption.WRITE;
final long timeoutAt = System.currentTimeMillis() + timeoutMS;
final long startMs = System.currentTimeMillis();
try (final FileChannel channel = FileChannel.open(file.toPath(), readOrWrite)) {
for (int count = 1; System.currentTimeMillis() < timeoutAt; count++) {
try (FileLock fileLock = channel.tryLock(EXCLUSIVE_LOCK_START, EXCLUSIVE_LOCK_SIZE, shared)) {
if (fileLock != null) {
return code.apply(target.get());
}
} catch (IOException | OverlappingFileLockException e) {
// failed to acquire the lock, wait until other operation completes
if (count > 9) {
if (Jvm.isDebugEnabled(SingleTableStore.class)) {
final long elapsedMs = System.currentTimeMillis() - startMs;
final String message = "Failed to acquire " + type + " lock on the table store file. Retrying, file=" + file.getAbsolutePath() + ", count=" + count + ", elapsed=" + elapsedMs + " ms";
Jvm.debug().on(SingleTableStore.class, "", new StackTrace(message));
}
}
}
int delay = Math.min(250, count * count);
sleep(delay, MILLISECONDS);
}
} catch (IOException e) {
throw new IllegalStateException("Couldn't perform operation with " + type + " file lock", e);
}
throw new IllegalStateException("Unable to claim exclusive " + type + " lock on file " + file);
}
use of net.openhft.chronicle.core.StackTrace in project Chronicle-Queue by OpenHFT.
the class SCQIndexing method printLinearScanTime.
private boolean printLinearScanTime(long toIndex, long fromKnownIndex, long start, long end, String desc) {
StackTrace st = null;
if (Jvm.isDebugEnabled(getClass())) {
int time = Jvm.isArm() ? 20_000_000 : 250_000;
// ignore the time for the first message
if (toIndex > 0 && end > start + time)
st = new StackTrace("This is a profile stack trace, not an ERROR");
}
long tookUS = (end - start) / 1000;
Jvm.perf().on(getClass(), "Took " + tookUS + " us to " + desc + " from " + fromKnownIndex + " to " + toIndex + " = (0x" + Long.toHexString(toIndex) + "-0x" + Long.toHexString(fromKnownIndex) + ")=" + (toIndex - fromKnownIndex), st);
return true;
}
Aggregations