bool doWaitOnMonitor()

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;
    }