FX::QRWMutex Class Reference

#include <QThread.h>

List of all members.


Detailed Description

A mutex object permitting multiple reads simultaneously.

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)


Member Function Documentation

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  ) 

Returns:
True if nested write lock request while read lock was held resulted in unlock for other thread (ie; reread all your pointers etc)
Parameters:
write True if you wish to write as well as read
Claims the read/write mutex for access. Requesting read access will always return immediately if only other claimants have requested read access. You may nest lock()'s, for example
    lock(false);
    ...
    lock(true);
    ...
    unlock(true);
    unlock(false);
This facility to lock for read, then if necessary a write is quite useful.
Warning:
Do not use this directly unless absolutely necessary. Use QMtxHold instead.

void FX::QRWMutex::unlock ( bool  write = true  ) 

Release the mutex from its previous lock(). You must use the same parameter as in the most recent lock().

Warning:
Do not use this directly unless absolutely necessary. Use QMtxHold instead.

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


The documentation for this class was generated from the following file:

(C) 2002-2008 Niall Douglas. Some parts (C) to assorted authors.
Generated on Fri Jun 13 22:28:54 2008 for TnFOX by doxygen v1.5.6