in activemq-cpp/src/main/decaf/internal/util/concurrent/Threading.cpp [699:801]
bool doWaitOnMonitor(MonitorHandle* monitor, ThreadHandle* thread,
long long mills, int nanos, bool interruptible) {
int count = -1;
bool interrupted = false;
bool notified = false;
bool timedOut = false;
if (monitor->owner != thread) {
throw IllegalMonitorStateException(__FILE__, __LINE__, "Current Thread is not the lock holder.");
}
count = monitor->count;
PlatformThread::lockMutex(thread->mutex);
// Before we wait, check if we've already been either interrupted
if (interruptible && thread->interrupted) {
thread->interrupted = false;
PlatformThread::unlockMutex(thread->mutex);
throw InterruptedException(__FILE__, __LINE__, "Thread interrupted");
}
thread->waiting = true;
thread->interruptible = interruptible;
if (mills || nanos) {
thread->timerSet = true;
thread->state = Thread::TIMED_WAITING;
} else {
thread->state = Thread::WAITING;
}
thread->monitor = monitor;
PlatformThread::unlockMutex(thread->mutex);
monitor->owner = NULL;
monitor->count = 0;
PlatformThread::lockMutex(monitor->mutex);
// Release the lock and wake up any blocked threads.
PlatformThread::unlockMutex(monitor->lock);
unblockThreads(monitor->blocking);
// This thread now enters the wait queue.
enqueueThread(&monitor->waiting, thread);
MonitorWaitCompletionCondition completion(thread);
if (mills || nanos) {
timedOut = PlatformThread::interruptibleWaitOnCondition(thread->condition, monitor->mutex, mills, nanos, completion);
} else {
PlatformThread::interruptibleWaitOnCondition(thread->condition, monitor->mutex, completion);
}
dequeueThread(&monitor->waiting, thread);
PlatformThread::unlockMutex(monitor->mutex);
// We should own the Thread's mutex from the CompletionCondition locking it.
interrupted = thread->interrupted;
notified = thread->notified;
thread->waiting = false;
thread->notified = false;
thread->timerSet = false;
thread->interruptible = false;
thread->state = Thread::RUNNABLE;
if (interrupted && !notified) {
thread->interrupted = false;
}
if (thread->interruptingThread) {
PlatformThread::lockMutex(thread->interruptingThread->mutex);
thread->interruptingThread->canceled = true;
PlatformThread::unlockMutex(thread->interruptingThread->mutex);
thread->interruptingThread = NULL;
}
PlatformThread::unlockMutex(thread->mutex);
// Re-acquire the lock now and restore its old state.
doMonitorEnter(monitor, thread);
monitor->count = count;
if (notified) {
return false;
}
if (interrupted) {
throw InterruptedException(__FILE__, __LINE__, "Thread interrupted");
}
if (!timedOut) {
throw RuntimeException(__FILE__, __LINE__, "Invalid state detected at end of Monitor Wait");
}
return true;
}