#include <QThread.h>
One of these functions quite similarly to a QMutex, except that when you lock() it you can specify if you want write access in addition to read access. If you do request write access, only one thread (you) is permitted to use the data. If you want merely read access, anyone else requesting only read access will be permitted to read without blocking.
QRWMutex is useful when you have many threads mostly reading the same data because it can in some cases vastly improve performance. It does however arrive with a greater cost than a QMutex which is in the order of fractions of a microsecond - a QRWMutex will take possibly up to four to five times longer.
This implementation fully supports recursion of both read and write locks and furthermore supports you obtaining a read lock first and then a subsequent write lock on top of it, or obtaining a write lock and then subsequent read lock. It uses an intelligent algorithm to stall any new readers or writers except those already with a read or write lock who get preference. Write requests get preference over read requests - a future version may be configurable to be the opposite.
One inescapable caveat in fully recursive read write mutexes is what happens when two threads with existing read locks both claim the write lock at the same time. Most implementations lock up or define it as an impossible state you should not permit - our implementation instead serialises each thread through the write locked section. Obviously, this means across the claiming of the write lock when a read lock is already held, <u>the data may change</u> - and if you do not take care, pointers held from the read lock period may become dangling or otherwise pre-write lock references become invalid. lock() returns true when this happens (and the FX::QMtxHold::lockLost() method returns true) so you can detect when you need to reestablish your data state.
Because this creates hard to detect bugs, let me emphasise here from my own bitter experience - always assume when requesting write access when already holding a read lock that you have effectively unlocked completely ie; retest entries have not been since added to a list, or assume pointers or references remain valid etc.
Public Types | |
enum | LockedState { Unlocked, ReadOnly, ReadWrite } |
Public Member Functions | |
FXuint | spinCount () const |
void | setSpinCount (FXuint c) |
bool | lock (bool write=true) |
void | unlock (bool write=true) |
LockedState | isLocked () const |
bool | trylock (bool write) |
FXuint FX::QRWMutex::spinCount | ( | ) | const |
Returns the spin count of the underlying QMutex.
void FX::QRWMutex::setSpinCount | ( | FXuint | c | ) |
Sets the spin count of the underlying QMutex. It would be rare you'd want to set this as the default is about right.
bool FX::QRWMutex::lock | ( | bool | write = true |
) |
write | True if you wish to write as well as read |
void FX::QRWMutex::unlock | ( | bool | write = true |
) |
LockedState FX::QRWMutex::isLocked | ( | ) | const [inline] |
Returns the current state of the read/write mutex.
bool FX::QRWMutex::trylock | ( | bool | write | ) |
Claims the mutex if free and returns true. If already taken, immediately returns false without waiting