1

Under Linux qt 4.7.4 using gcc 4.4.3 the following code compiles fine and gives no runtime error.

class TestThread: public QThread {
  private:
      QReadWriteLock mutex;

  public:
    bool mStop;

    TestThread(): mutex(QReadWriteLock::NonRecursive),mStop(false) {}
    void run() {
      while(!mStop) {
        mutex.lockForRead();        
        qDebug() << "Tread running";
        msleep(100);        
      }
    }
};

The lock is locked by the same thread several times and nothing happens. According to the manual http://doc.qt.io/archives/qt-4.7/qreadwritelock.html

the lock should only be lockable once by the same thread. Is this some serious bug or am I misunderstanding the manual ?

In Reply to Chris: The lock has to be unlocked several times in NonRecursive as well, the following code never prints "Writing" if one unlock is commented out.

class TestThread: public QThread {
  private:
    QReadWriteLock mutex;

  public:
    TestThread(): mutex(QReadWriteLock::NonRecursive){}
    void run() {
        mutex.lockForRead();
        mutex.lockForRead();
        qDebug() << "Tread running";
        //mutex.unlock();
        mutex.unlock();
        mutex.lockForWrite();
        qDebug() << "Writing";
        mutex.unlock();
        msleep(50);
    }
};


int main(int argc, char *argv[]) {
  TestThread myThread;

  myThread.start();
  usleep(500000);
  myThread.terminate();
}
Christophe Weis
  • 2,518
  • 4
  • 28
  • 32
Martin
  • 4,738
  • 4
  • 28
  • 57
  • Yes you're right, the behavior is somewhat confusing. I'll have to do some more digging to figure out what's going on there. – Chris Dec 07 '11 at 15:33

2 Answers2

2

I finally found the main difference. When a QReadWritelock is declared as Recursive a Readlock from one thread does only count as one lock. Hence a consecutive lock for read in the same thread my not be blocked by a waiting write lock. When the lock is declared non-recursive this may happen and lead to very bad deadlocks.

Martin
  • 4,738
  • 4
  • 28
  • 57
0

I guess the QReadWriteLock::NonRecursive mode only affects write locks.

Try obtaining a write lock in non-recursive mode two times from the same thread and I think you will get the behaviour you expected.

Jonny Dee
  • 837
  • 4
  • 12
  • A write lock should always only be obtained once. If not you are in serious trouble – Martin Feb 04 '12 at 20:39
  • 1
    I know, I just wanted to mention that the reason why obtaining read locks doesn't block in 'NonRecursive' mode might be that "QReadWriteLock::NonRecursive mode only affects obtaining write locks". Obtaining a write lock recursively (i.e. several times within the same thread) really does make sense. Suppose you have a function which calls a second one and both want a write lock. – Jonny Dee Feb 10 '12 at 11:44
  • Good point. There is nothing definite in the manpages but at least this would make sense ;-) – Martin Feb 10 '12 at 13:25