Introduction

The Qt library can now be compiled with MT support. The only differences (currently) between libqt and libqt-mt are that some new classes are introduced (QThread, QMutex etc.) and that a QMutex is used to protect QApplication’s event loop.

For Qt to be a thread-safe library (not just multithread-capable), all classes and functions must be protected for access by more than one thread.

Achieving thread-safety for Qt is more complex than it may seem. Qt makes extensive use of copy-on-write semantics, providing both explicit- and implicit-shared classes.

Fine-grained locking

To gain thread-safety, surely we can just wrap all access to member data in a mutex ? Well, yes, we can, but the amount of CPU overhead would be more than acceptable. I have used this ‘solution’ in my program s.q.u.e.l.c.h to mediate access to a QQueue. The CPU overhead is not noticeable in this (isolated and carefully planned) case as (un)locking of the mutex is only performed a couple of times a second.

Coarse-grained locking

Instead of locking member data from within the class, how about adding public lock() and unlock() methods to class interfaces ? This would allow the user to have control over locking.

Coarse-grained locking is no solution at all. Not only does it require careful programming by the user, but it also does not work for shared classes ! A user cannot safely lock an object of a shared class because she cannot know how the object is being shared.

A compromise

Instead of introducing a mutex around each data member, how about using a mechanism similar to reference counting, whereby access is guarded by an integer counter ? Testing and setting an integer is orders of magnitude faster than unlocking and locking a mutex.

This method eliminates the horror of requiring sane users, but it requires more work by the library implementors. Avoiding mutexes means that testing and setting the integer counter would have to be atomic. Such atomic operations will have to be coded in assembly language for each target platform.

Example code

This code (for x86 Linux) shows how to make a copy-on-write string class which is MT-safe, using an atomic counter. There is a memory leak in the copy ctor, which I need to fix. Apart from that, it works.

qt_mt.tar.gz

I would love to fix the remaining bug in this code, then apply the general principle to the Qt library. I could do with some assistance, though. Anyone want to help ?