Skip to content

Commit

Permalink
Add RAII class QgsReadWriteLocker
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Sep 6, 2018
1 parent cdc7d39 commit ba5cfc3
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 0 deletions.
68 changes: 68 additions & 0 deletions python/core/auto_generated/qgsreadwritelocker.sip.in
@@ -0,0 +1,68 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsreadwritelocker.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsReadWriteLocker
{
%Docstring
The QgsReadWriteLocker class is a convenience class that simplifies locking and unlocking QReadWriteLocks.

Locking and unlocking a QReadWriteLocks in complex functions and statements or in exception handling code
is error-prone and difficult to debug.
QgsReadWriteLocker can be used in such situations to ensure that the state of the lock is always well-defined.

QgsReadWriteLocker should be created within a function where a QReadWriteLock needs to be locked.
The lock may be locked when QgsReadWriteLocker is created or when changeMode is called.
You can unlock and relock the lock with unlock() and changeMode().
If locked, the mutex will be unlocked when the QgsReadWriteLocker is destroyed.

.. versionadded:: 3.4
%End

%TypeHeaderCode
#include "qgsreadwritelocker.h"
%End
public:
enum Mode
{
Read,
Write,
Unlocked
};

QgsReadWriteLocker( QReadWriteLock &lock, Mode mode );
%Docstring
Create a new QgsReadWriteLocker for ``lock`` and initialize in ``mode``.
%End

void changeMode( Mode mode );
%Docstring
Change the mode of the lock to ``mode``.
The lock will be unlocked and relocked as required.
%End

void unlock();
%Docstring
Unlocks the lock.
Equivalent to doing ``changeMode( QgsReadWriteLocker.Unlock );``
%End

~QgsReadWriteLocker();

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsreadwritelocker.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -106,6 +106,7 @@
%Include auto_generated/qgspythonrunner.sip
%Include auto_generated/qgsrange.sip
%Include auto_generated/qgsreadwritecontext.sip
%Include auto_generated/qgsreadwritelocker.sip
%Include auto_generated/qgsrenderchecker.sip
%Include auto_generated/qgsrendercontext.sip
%Include auto_generated/qgsrulebasedlabeling.sip
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -280,6 +280,7 @@ SET(QGIS_CORE_SRCS
qgsproxyprogresstask.cpp
qgspythonrunner.cpp
qgsreadwritecontext.cpp
qgsreadwritelocker.cpp
qgsrelation.cpp
qgsrelationmanager.cpp
qgsrenderchecker.cpp
Expand Down Expand Up @@ -919,6 +920,7 @@ SET(QGIS_CORE_HDRS
qgspythonrunner.h
qgsrange.h
qgsreadwritecontext.h
qgsreadwritelocker.h
qgsrenderchecker.h
qgsrendercontext.h
qgsrulebasedlabeling.h
Expand Down
54 changes: 54 additions & 0 deletions src/core/qgsreadwritelocker.cpp
@@ -0,0 +1,54 @@
/***************************************************************************
qgsreadwritelocker.cpp
-------------------------
begin : September 2018
copyright : (C) 2018 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsreadwritelocker.h"

QgsReadWriteLocker::QgsReadWriteLocker( QReadWriteLock &lock, QgsReadWriteLocker::Mode mode )
: mLock( lock )
, mMode( mode )
{
if ( mode == Read )
mLock.lockForRead();
else if ( mode == Write )
mLock.lockForWrite();
}

void QgsReadWriteLocker::changeMode( QgsReadWriteLocker::Mode mode )
{
if ( mode == mMode )
return;

unlock();

if ( mMode == Read )
mLock.lockForRead();
else if ( mMode == Write )
mLock.lockForWrite();
}

void QgsReadWriteLocker::unlock()
{
if ( mMode != Unlocked )
mLock.unlock();

mMode = Unlocked;
}

QgsReadWriteLocker::~QgsReadWriteLocker()
{
unlock();
}
74 changes: 74 additions & 0 deletions src/core/qgsreadwritelocker.h
@@ -0,0 +1,74 @@
/***************************************************************************
qgsreadwritelocker.cpp
-------------------------
begin : September 2018
copyright : (C) 2018 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSREADWRITELOCKER_H
#define QGSREADWRITELOCKER_H

#include "qgis_core.h"

#include <QReadWriteLock>

/**
* \ingroup core
* The QgsReadWriteLocker class is a convenience class that simplifies locking and unlocking QReadWriteLocks.
*
* Locking and unlocking a QReadWriteLocks in complex functions and statements or in exception handling code
* is error-prone and difficult to debug.
* QgsReadWriteLocker can be used in such situations to ensure that the state of the lock is always well-defined.
*
* QgsReadWriteLocker should be created within a function where a QReadWriteLock needs to be locked.
* The lock may be locked when QgsReadWriteLocker is created or when changeMode is called.
* You can unlock and relock the lock with unlock() and changeMode().
* If locked, the mutex will be unlocked when the QgsReadWriteLocker is destroyed.
*
* \since QGIS 3.4
*/
class CORE_EXPORT QgsReadWriteLocker
{
public:
enum Mode
{
Read, //!< Lock for read
Write, //!< Lock for write
Unlocked //!< Unlocked
};

/**
* Create a new QgsReadWriteLocker for \a lock and initialize in \a mode.
*/
QgsReadWriteLocker( QReadWriteLock &lock, Mode mode );

/**
* Change the mode of the lock to \a mode.
* The lock will be unlocked and relocked as required.
*/
void changeMode( Mode mode );

/**
* Unlocks the lock.
* Equivalent to doing ``changeMode( QgsReadWriteLocker::Unlock );``
*/
void unlock();

~QgsReadWriteLocker();

private:
QReadWriteLock &mLock;
Mode mMode = Unlocked;
};

#endif // QGSREADWRITELOCKER_H

0 comments on commit ba5cfc3

Please sign in to comment.