in wicket-core/src/main/java/org/apache/wicket/page/DefaultPageLockManager.java [87:177]
public void lockPage(int pageId) throws CouldNotLockPageException
{
final Thread thread = Thread.currentThread();
final PageAccessSynchronizer.PageLock lock = new PageAccessSynchronizer.PageLock(pageId, thread);
final Instant start = Instant.now();
boolean locked = false;
final boolean isDebugEnabled = logger.isDebugEnabled();
PageAccessSynchronizer.PageLock previous = null;
Duration pageTimeout = getTimeout(pageId);
while (!locked && Durations.elapsedSince(start).compareTo(pageTimeout) < 0)
{
if (isDebugEnabled)
{
logger.debug("'{}' attempting to acquire lock to page with id '{}'",
thread.getName(), pageId);
}
previous = locks.get().putIfAbsent(pageId, lock);
if (previous == null || previous.getThread() == thread)
{
// first thread to acquire lock or lock is already owned by this thread
locked = true;
}
else
{
// wait for a lock to become available
long remaining = remaining(start, pageTimeout);
if (remaining > 0)
{
previous.waitForRelease(remaining, isDebugEnabled);
}
}
}
if (locked)
{
if (isDebugEnabled)
{
logger.debug("{} acquired lock to page {}", thread.getName(), pageId);
}
}
else
{
final Thread previousThread = previous != null ? previous.getThread() : null;
final String previousThreadName = previousThread != null ? previousThread.getName() : "N/A";
if (logger.isWarnEnabled())
{
logger.warn(
"Thread '{}' failed to acquire lock to page with id '{}', attempted for {} out of allowed {}." +
" The thread that holds the lock has name '{}'.",
thread.getName(), pageId, Duration.between(start, Instant.now()), pageTimeout, previousThreadName);
if (Application.exists())
{
ExceptionSettings.ThreadDumpStrategy strategy = Application.get()
.getExceptionSettings()
.getThreadDumpStrategy();
switch (strategy)
{
case ALL_THREADS :
Threads.dumpAllThreads(logger);
break;
case THREAD_HOLDING_LOCK :
if (previousThread != null)
{
Threads.dumpSingleThread(logger, previousThread);
}
else
{
logger.warn("Cannot dump the stack of the previous thread because it is not available.");
}
break;
case NO_THREADS :
default :
// do nothing
}
}
}
if(previousThread != null)
{
var cause = new PageLockedException(previousThread, pageId);
throw new CouldNotLockPageException(pageId, thread.getName(), pageTimeout, cause);
}
throw new CouldNotLockPageException(pageId, thread.getName(), pageTimeout);
}
}