Logo Search packages:      
Sourcecode: qt4-x11 version File versions

void QMutex::lock (  ) 

Locks the mutex. If another thread has locked the mutex then this call will block until that thread has unlocked it.

Calling this function multiple times on the same mutex from the same thread is allowed if this mutex is a {QMutex::Recursive}{recursive mutex}. If this mutex is a {QMutex::NonRecursive}{non-recursive mutex}, this function will dead-lock when the mutex is locked recursively.

See also:
unlock()

Definition at line 148 of file qmutex.cpp.

References QThread::currentThreadId().

Referenced by FortuneThread::run(), RenderThread::run(), RenderThread::stopProcess(), FortuneThread::~FortuneThread(), and RenderThread::~RenderThread().

{
    Qt::HANDLE self;

    if (d->recursive) {
        self = QThread::currentThreadId();
        if (d->owner == self) {
            ++d->count;
            Q_ASSERT_X(d->count != 0, "QMutex::lock", "Overflow in recursion counter");
            return;
        }

        bool isLocked = d->contenders.fetchAndAddAcquire(1) == 0;
        if (!isLocked) {
#ifndef QT_NO_DEBUG
            if (d->owner == self)
                qWarning("QMutex::lock: Deadlock detected in thread %ld",
                         long(d->owner));
#endif

            // didn't get the lock, wait for it
            isLocked = d->wait();
            Q_ASSERT_X(isLocked, "QMutex::lock",
                       "Internal error, infinite wait has timed out.");

            // don't need to wait for the lock anymore
            d->contenders.deref();
        }

        d->owner = self;
        ++d->count;
        Q_ASSERT_X(d->count != 0, "QMutex::lock", "Overflow in recursion counter");
        return;
    }

#ifndef QT_NO_DEBUG
    self = QThread::currentThreadId();
#endif

    bool isLocked = d->contenders == 0 && d->contenders.testAndSetAcquire(0, 1);
    if (!isLocked) {
        int spinCount = 0;
        int lastSpinCount = d->lastSpinCount;

        enum { AdditionalSpins = 20, SpinCountPenalizationDivisor = 4 };
        const int maximumSpinCount = lastSpinCount + AdditionalSpins;

        do {
            if (spinCount++ > maximumSpinCount) {
                // puts("spinning useless, sleeping");
                isLocked = d->contenders.fetchAndAddAcquire(1) == 0;
                if (!isLocked) {
#ifndef QT_NO_DEBUG
                    if (d->owner == self)
                        qWarning("QMutex::lock: Deadlock detected in thread %ld",
                                 long(d->owner));
#endif

                    // didn't get the lock, wait for it
                    isLocked = d->wait();
                    Q_ASSERT_X(isLocked, "QMutex::lock",
                               "Internal error, infinite wait has timed out.");

                    // don't need to wait for the lock anymore
                    d->contenders.deref();
                }
                // decrease the lastSpinCount since we didn't actually get the lock by spinning
                spinCount = -d->lastSpinCount / SpinCountPenalizationDivisor;
                break;
            }

            isLocked = d->contenders == 0 && d->contenders.testAndSetAcquire(0, 1);
        } while (!isLocked);

        // adjust the last spin lock count
        lastSpinCount = d->lastSpinCount;
        d->lastSpinCount = spinCount >= 0
                           ? qMax(lastSpinCount, spinCount)
                           : lastSpinCount + spinCount;
    }

#ifndef QT_NO_DEBUG
    d->owner = self;
#endif
}


Generated by  Doxygen 1.6.0   Back to index