Qt 4.8
Public Types | Public Functions | Properties | Friends | List of all members
QReadWriteLock Class Reference

The QReadWriteLock class provides read-write locking. More...

#include <qreadwritelock.h>

Public Types

enum  RecursionMode { NonRecursive, Recursive }
 QReadWriteLock multiple times and the mutex won't be unlocked until a corresponding number of unlock() calls have been made. More...
 

Public Functions

void lockForRead ()
 Locks the lock for reading. More...
 
void lockForWrite ()
 Locks the lock for writing. More...
 
 QReadWriteLock ()
 Constructs a QReadWriteLock object in NonRecursive mode. More...
 
 QReadWriteLock (RecursionMode recursionMode)
 Constructs a QReadWriteLock object in the given recursionMode. More...
 
bool tryLockForRead ()
 Attempts to lock for reading. More...
 
bool tryLockForRead (int timeout)
 Attempts to lock for reading. More...
 
bool tryLockForWrite ()
 Attempts to lock for writing. More...
 
bool tryLockForWrite (int timeout)
 Attempts to lock for writing. More...
 
void unlock ()
 Unlocks the lock. More...
 
 ~QReadWriteLock ()
 Destroys the QReadWriteLock object. More...
 

Properties

QReadWriteLockPrivated
 

Friends

class QWaitCondition
 

Detailed Description

The QReadWriteLock class provides read-write locking.

Note
This class or function is threadsafe.

A read-write lock is a synchronization tool for protecting resources that can be accessed for reading and writing. This type of lock is useful if you want to allow multiple threads to have simultaneous read-only access, but as soon as one thread wants to write to the resource, all other threads must be blocked until the writing is complete.

In many cases, QReadWriteLock is a direct competitor to QMutex. QReadWriteLock is a good choice if there are many concurrent reads and writing occurs infrequently.

Example:

{
...
lock.lockForRead();
read_file();
lock.unlock();
...
}
{
...
lock.lockForWrite();
write_file();
lock.unlock();
...
}

To ensure that writers aren't blocked forever by readers, readers attempting to obtain a lock will not succeed if there is a blocked writer waiting for access, even if the lock is currently only accessed by other readers. Also, if the lock is accessed by a writer and another writer comes in, that writer will have priority over any readers that might also be waiting.

Like QMutex, a QReadWriteLock can be recursively locked by the same thread when constructed in QReadWriteLock::RecursionMode. In such cases, unlock() must be called the same number of times lockForWrite() or lockForRead() was called. Note that the lock type cannot be changed when trying to lock recursively, i.e. it is not possible to lock for reading in a thread that already has locked for writing (and vice versa).

See also
QReadLocker, QWriteLocker, QMutex, QSemaphore

Definition at line 58 of file qreadwritelock.h.

Enumerations

◆ RecursionMode

QReadWriteLock multiple times and the mutex won't be unlocked until a corresponding number of unlock() calls have been made.

Since
4.4
  • Recursive In this mode, a thread can lock the same
  • NonRecursive In this mode, a thread may only lock a QReadWriteLock once.
See also
QReadWriteLock()
Enumerator
NonRecursive 
Recursive 

Definition at line 61 of file qreadwritelock.h.

Constructors and Destructors

◆ QReadWriteLock() [1/2]

QReadWriteLock::QReadWriteLock ( )

Constructs a QReadWriteLock object in NonRecursive mode.

See also
lockForRead(), lockForWrite()

Definition at line 120 of file qreadwritelock.cpp.

◆ QReadWriteLock() [2/2]

QReadWriteLock::QReadWriteLock ( RecursionMode  recursionMode)

Constructs a QReadWriteLock object in the given recursionMode.

Since
4.4
See also
lockForRead(), lockForWrite(), RecursionMode

Definition at line 134 of file qreadwritelock.cpp.

135  : d(new QReadWriteLockPrivate(recursionMode))
136 { }
QReadWriteLockPrivate * d

◆ ~QReadWriteLock()

QReadWriteLock::~QReadWriteLock ( )

Destroys the QReadWriteLock object.

Warning
Destroying a read-write lock that is in use may result in undefined behavior.

Definition at line 144 of file qreadwritelock.cpp.

145 {
146  delete d;
147 }
QReadWriteLockPrivate * d

Functions

◆ lockForRead()

void QReadWriteLock::lockForRead ( )

Locks the lock for reading.

This function will block the current thread if any thread (including the current) has locked for writing.

See also
unlock() lockForWrite() tryLockForRead()

Definition at line 156 of file qreadwritelock.cpp.

Referenced by QSqlDatabasePrivate::database(), QWaitConditionPrivate::post(), QReadLocker::relock(), and QWaitCondition::wait().

157 {
159 
160  Qt::HANDLE self = 0;
161  if (d->recursive) {
162  self = QThread::currentThreadId();
163 
165  if (it != d->currentReaders.end()) {
166  ++it.value();
167  ++d->accessCount;
168  Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::lockForRead()",
169  "Overflow in lock counter");
170  return;
171  }
172  }
173 
174  while (d->accessCount < 0 || d->waitingWriters) {
175  ++d->waitingReaders;
176  d->readerWait.wait(&d->mutex);
177  --d->waitingReaders;
178  }
179  if (d->recursive)
180  d->currentReaders.insert(self, 1);
181 
182  ++d->accessCount;
183  Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::lockForRead()", "Overflow in lock counter");
184 }
QWaitCondition readerWait
#define it(className, varName)
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
QReadWriteLockPrivate * d
void * HANDLE
Definition: qnamespace.h:1671
bool wait(QMutex *mutex, unsigned long time=ULONG_MAX)
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:467
static QReadWriteLock lock
Definition: proxyconf.cpp:399
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
Definition: qhash.h:865
QHash< Qt::HANDLE, int > currentReaders
static Qt::HANDLE currentThreadId()
Returns the thread handle of the currently executing thread.

◆ lockForWrite()

void QReadWriteLock::lockForWrite ( )

Locks the lock for writing.

This function will block the current thread if another thread has locked for reading or writing.

See also
unlock() lockForRead() tryLockForWrite()

Definition at line 287 of file qreadwritelock.cpp.

Referenced by QWaitConditionPrivate::post(), QWriteLocker::relock(), and QWaitCondition::wait().

288 {
290 
291  Qt::HANDLE self = 0;
292  if (d->recursive) {
293  self = QThread::currentThreadId();
294 
295  if (d->currentWriter == self) {
296  --d->accessCount;
297  Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::lockForWrite()",
298  "Overflow in lock counter");
299  return;
300  }
301  }
302 
303  while (d->accessCount != 0) {
304  ++d->waitingWriters;
305  d->writerWait.wait(&d->mutex);
306  --d->waitingWriters;
307  }
308  if (d->recursive)
309  d->currentWriter = self;
310 
311  --d->accessCount;
312  Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::lockForWrite()", "Overflow in lock counter");
313 }
QWaitCondition writerWait
QReadWriteLockPrivate * d
void * HANDLE
Definition: qnamespace.h:1671
bool wait(QMutex *mutex, unsigned long time=ULONG_MAX)
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
static QReadWriteLock lock
Definition: proxyconf.cpp:399
static Qt::HANDLE currentThreadId()
Returns the thread handle of the currently executing thread.

◆ tryLockForRead() [1/2]

bool QReadWriteLock::tryLockForRead ( )

Attempts to lock for reading.

If the lock was obtained, this function returns true, otherwise it returns false instead of waiting for the lock to become available, i.e. it does not block.

The lock attempt will fail if another thread has locked for writing.

If the lock was obtained, the lock must be unlocked with unlock() before another thread can successfully lock it.

See also
unlock() lockForRead()

Definition at line 199 of file qreadwritelock.cpp.

200 {
202 
203  Qt::HANDLE self = 0;
204  if (d->recursive) {
205  self = QThread::currentThreadId();
206 
208  if (it != d->currentReaders.end()) {
209  ++it.value();
210  ++d->accessCount;
211  Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()",
212  "Overflow in lock counter");
213  return true;
214  }
215  }
216 
217  if (d->accessCount < 0)
218  return false;
219  if (d->recursive)
220  d->currentReaders.insert(self, 1);
221 
222  ++d->accessCount;
223  Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()", "Overflow in lock counter");
224 
225  return true;
226 }
#define it(className, varName)
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
QReadWriteLockPrivate * d
void * HANDLE
Definition: qnamespace.h:1671
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:467
static QReadWriteLock lock
Definition: proxyconf.cpp:399
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
Definition: qhash.h:865
QHash< Qt::HANDLE, int > currentReaders
static Qt::HANDLE currentThreadId()
Returns the thread handle of the currently executing thread.

◆ tryLockForRead() [2/2]

bool QReadWriteLock::tryLockForRead ( int  timeout)

Attempts to lock for reading.

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

This function returns true if the lock was obtained; otherwise it returns false. If another thread has locked for writing, this function will wait for at most timeout milliseconds for the lock to become available.

Note: Passing a negative number as the timeout is equivalent to calling lockForRead(), i.e. this function will wait forever until lock can be locked for reading when timeout is negative.

If the lock was obtained, the lock must be unlocked with unlock() before another thread can successfully lock it.

See also
unlock() lockForRead()

Definition at line 247 of file qreadwritelock.cpp.

248 {
250 
251  Qt::HANDLE self = 0;
252  if (d->recursive) {
253  self = QThread::currentThreadId();
254 
256  if (it != d->currentReaders.end()) {
257  ++it.value();
258  ++d->accessCount;
259  Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()",
260  "Overflow in lock counter");
261  return true;
262  }
263  }
264 
265  while (d->accessCount < 0 || d->waitingWriters) {
266  ++d->waitingReaders;
267  bool success = d->readerWait.wait(&d->mutex, timeout < 0 ? ULONG_MAX : ulong(timeout));
268  --d->waitingReaders;
269  if (!success)
270  return false;
271  }
272  if (d->recursive)
273  d->currentReaders.insert(self, 1);
274 
275  ++d->accessCount;
276  Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()", "Overflow in lock counter");
277 
278  return true;
279 }
QWaitCondition readerWait
#define it(className, varName)
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
QReadWriteLockPrivate * d
void * HANDLE
Definition: qnamespace.h:1671
unsigned long ulong
Definition: qglobal.h:997
bool wait(QMutex *mutex, unsigned long time=ULONG_MAX)
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:467
static QReadWriteLock lock
Definition: proxyconf.cpp:399
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
Definition: qhash.h:865
QHash< Qt::HANDLE, int > currentReaders
static Qt::HANDLE currentThreadId()
Returns the thread handle of the currently executing thread.

◆ tryLockForWrite() [1/2]

bool QReadWriteLock::tryLockForWrite ( )

Attempts to lock for writing.

If the lock was obtained, this function returns true; otherwise, it returns false immediately.

The lock attempt will fail if another thread has locked for reading or writing.

If the lock was obtained, the lock must be unlocked with unlock() before another thread can successfully lock it.

See also
unlock() lockForWrite()

Definition at line 327 of file qreadwritelock.cpp.

328 {
330 
331  Qt::HANDLE self = 0;
332  if (d->recursive) {
333  self = QThread::currentThreadId();
334 
335  if (d->currentWriter == self) {
336  --d->accessCount;
337  Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::lockForWrite()",
338  "Overflow in lock counter");
339  return true;
340  }
341  }
342 
343  if (d->accessCount != 0)
344  return false;
345  if (d->recursive)
346  d->currentWriter = self;
347 
348  --d->accessCount;
349  Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::tryLockForWrite()",
350  "Overflow in lock counter");
351 
352  return true;
353 }
QReadWriteLockPrivate * d
void * HANDLE
Definition: qnamespace.h:1671
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
static QReadWriteLock lock
Definition: proxyconf.cpp:399
static Qt::HANDLE currentThreadId()
Returns the thread handle of the currently executing thread.

◆ tryLockForWrite() [2/2]

bool QReadWriteLock::tryLockForWrite ( int  timeout)

Attempts to lock for writing.

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

This function returns true if the lock was obtained; otherwise it returns false. If another thread has locked for reading or writing, this function will wait for at most timeout milliseconds for the lock to become available.

Note: Passing a negative number as the timeout is equivalent to calling lockForWrite(), i.e. this function will wait forever until lock can be locked for writing when timeout is negative.

If the lock was obtained, the lock must be unlocked with unlock() before another thread can successfully lock it.

See also
unlock() lockForWrite()

Definition at line 374 of file qreadwritelock.cpp.

375 {
377 
378  Qt::HANDLE self = 0;
379  if (d->recursive) {
380  self = QThread::currentThreadId();
381 
382  if (d->currentWriter == self) {
383  --d->accessCount;
384  Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::lockForWrite()",
385  "Overflow in lock counter");
386  return true;
387  }
388  }
389 
390  while (d->accessCount != 0) {
391  ++d->waitingWriters;
392  bool success = d->writerWait.wait(&d->mutex, timeout < 0 ? ULONG_MAX : ulong(timeout));
393  --d->waitingWriters;
394 
395  if (!success)
396  return false;
397  }
398  if (d->recursive)
399  d->currentWriter = self;
400 
401  --d->accessCount;
402  Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::tryLockForWrite()",
403  "Overflow in lock counter");
404 
405  return true;
406 }
QWaitCondition writerWait
QReadWriteLockPrivate * d
void * HANDLE
Definition: qnamespace.h:1671
unsigned long ulong
Definition: qglobal.h:997
bool wait(QMutex *mutex, unsigned long time=ULONG_MAX)
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
static QReadWriteLock lock
Definition: proxyconf.cpp:399
static Qt::HANDLE currentThreadId()
Returns the thread handle of the currently executing thread.

◆ unlock()

void QReadWriteLock::unlock ( )

Unlocks the lock.

Attempting to unlock a lock that is not locked is an error, and will result in program termination.

See also
lockForRead() lockForWrite() tryLockForRead() tryLockForWrite()

Definition at line 416 of file qreadwritelock.cpp.

Referenced by QSqlDatabasePrivate::database(), QWaitConditionPrivate::post(), QWSDisplay::ungrab(), QReadLocker::unlock(), QWriteLocker::unlock(), and QWaitCondition::wait().

417 {
419 
420  Q_ASSERT_X(d->accessCount != 0, "QReadWriteLock::unlock()", "Cannot unlock an unlocked lock");
421 
422  bool unlocked = false;
423  if (d->accessCount > 0) {
424  // releasing a read lock
425  if (d->recursive) {
428  if (it != d->currentReaders.end()) {
429  if (--it.value() <= 0)
430  d->currentReaders.erase(it);
431  }
432  }
433 
434  unlocked = --d->accessCount == 0;
435  } else if (d->accessCount < 0 && ++d->accessCount == 0) {
436  // released a write lock
437  unlocked = true;
438  d->currentWriter = 0;
439  }
440 
441  if (unlocked) {
442  if (d->waitingWriters) {
443  d->writerWait.wakeOne();
444  } else if (d->waitingReaders) {
445  d->readerWait.wakeAll();
446  }
447  }
448 }
QWaitCondition readerWait
#define it(className, varName)
QWaitCondition writerWait
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
QReadWriteLockPrivate * d
void * HANDLE
Definition: qnamespace.h:1671
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:467
static QReadWriteLock lock
Definition: proxyconf.cpp:399
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
Definition: qhash.h:865
QHash< Qt::HANDLE, int > currentReaders
iterator erase(iterator it)
Removes the (key, value) pair associated with the iterator pos from the hash, and returns an iterator...
Definition: qhash.h:827
static Qt::HANDLE currentThreadId()
Returns the thread handle of the currently executing thread.

Friends and Related Functions

◆ QWaitCondition

friend class QWaitCondition
friend

Definition at line 81 of file qreadwritelock.h.

Properties

◆ d

QReadWriteLockPrivate* QReadWriteLock::d
private

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