From 3557eacbd05d9c3fe28f53e00e6d5ebf41102999 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 10 Nov 2015 18:18:29 -0800 Subject: [PATCH] Add QTryRead/WriteLocker classes --- libraries/shared/src/shared/QTryReadLocker.h | 92 +++++++++++++++++++ libraries/shared/src/shared/QTryWriteLocker.h | 92 +++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 libraries/shared/src/shared/QTryReadLocker.h create mode 100644 libraries/shared/src/shared/QTryWriteLocker.h diff --git a/libraries/shared/src/shared/QTryReadLocker.h b/libraries/shared/src/shared/QTryReadLocker.h new file mode 100644 index 0000000000..573eba61b8 --- /dev/null +++ b/libraries/shared/src/shared/QTryReadLocker.h @@ -0,0 +1,92 @@ +// +// QTryReadLocker.h +// shared/src/shared/QTryReadLocker.h +// +// Created by Clément Brisset on 10/29/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_QTryReadLocker_h +#define hifi_QTryReadLocker_h + +#include + +class QTryReadLocker { +public: + QTryReadLocker(QReadWriteLock* readWriteLock); + QTryReadLocker(QReadWriteLock* readWriteLock, int timeout); + ~QTryReadLocker(); + + bool isLocked() const; + + void unlock(); + bool tryRelock(); + bool tryRelock(int timeout); + + QReadWriteLock* readWriteLock() const; + +private: + Q_DISABLE_COPY(QTryReadLocker) + quintptr q_val; +}; + +// Implementation +inline QTryReadLocker::QTryReadLocker(QReadWriteLock *areadWriteLock) : + q_val(reinterpret_cast(areadWriteLock)) +{ + Q_ASSERT_X((q_val & quintptr(1u)) == quintptr(0), + "QTryReadLocker", "QTryReadLocker pointer is misaligned"); + tryRelock(); +} + +inline QTryReadLocker::QTryReadLocker(QReadWriteLock *areadWriteLock, int timeout) : + q_val(reinterpret_cast(areadWriteLock)) +{ + Q_ASSERT_X((q_val & quintptr(1u)) == quintptr(0), + "QTryReadLocker", "QTryReadLocker pointer is misaligned"); + tryRelock(timeout); +} + +inline QTryReadLocker::~QTryReadLocker() { + unlock(); +} + +inline bool QTryReadLocker::isLocked() const { + return (q_val & quintptr(1u)) == quintptr(1u); +} + +inline void QTryReadLocker::unlock() { + if (q_val && isLocked()) { + q_val &= ~quintptr(1u); + readWriteLock()->unlock(); + } +} + +inline bool QTryReadLocker::tryRelock() { + if (q_val && !isLocked()) { + if (readWriteLock()->tryLockForRead()) { + q_val |= quintptr(1u); + return true; + } + } + return false; +} + +inline bool QTryReadLocker::tryRelock(int timeout) { + if (q_val && !isLocked()) { + if (readWriteLock()->tryLockForRead(timeout)) { + q_val |= quintptr(1u); + return true; + } + } + return false; +} + +inline QReadWriteLock* QTryReadLocker::readWriteLock() const { + return reinterpret_cast(q_val & ~quintptr(1u)); +} + +#endif // hifi_QTryReadLocker_h \ No newline at end of file diff --git a/libraries/shared/src/shared/QTryWriteLocker.h b/libraries/shared/src/shared/QTryWriteLocker.h new file mode 100644 index 0000000000..319920f724 --- /dev/null +++ b/libraries/shared/src/shared/QTryWriteLocker.h @@ -0,0 +1,92 @@ +// +// QTryWriteLocker.h +// shared/src/shared/QTryWriteLocker.h +// +// Created by Clément Brisset on 10/29/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_QTryWriteLocker_h +#define hifi_QTryWriteLocker_h + +#include + +class QTryWriteLocker { +public: + QTryWriteLocker(QReadWriteLock* readWriteLock); + QTryWriteLocker(QReadWriteLock* readWriteLock, int timeout); + ~QTryWriteLocker(); + + bool isLocked() const; + + void unlock(); + bool tryRelock(); + bool tryRelock(int timeout); + + QReadWriteLock* readWriteLock() const; + +private: + Q_DISABLE_COPY(QTryWriteLocker) + quintptr q_val; +}; + +// Implementation +inline QTryWriteLocker::QTryWriteLocker(QReadWriteLock *readWriteLock) : + q_val(reinterpret_cast(readWriteLock)) +{ + Q_ASSERT_X((q_val & quintptr(1u)) == quintptr(0), + "QTryWriteLocker", "QTryWriteLocker pointer is misaligned"); + tryRelock(); +} + +inline QTryWriteLocker::QTryWriteLocker(QReadWriteLock *readWriteLock, int timeout) : + q_val(reinterpret_cast(readWriteLock)) +{ + Q_ASSERT_X((q_val & quintptr(1u)) == quintptr(0), + "QTryWriteLocker", "QTryWriteLocker pointer is misaligned"); + tryRelock(timeout); +} + +inline QTryWriteLocker::~QTryWriteLocker() { + unlock(); +} + +inline bool QTryWriteLocker::isLocked() const { + return (q_val & quintptr(1u)) == quintptr(1u); +} + +inline void QTryWriteLocker::unlock() { + if (q_val && isLocked()) { + q_val &= ~quintptr(1u); + readWriteLock()->unlock(); + } +} + +inline bool QTryWriteLocker::tryRelock() { + if (q_val && !isLocked()) { + if (readWriteLock()->tryLockForWrite()) { + q_val |= quintptr(1u); + return true; + } + } + return false; +} + +inline bool QTryWriteLocker::tryRelock(int timeout) { + if (q_val && !isLocked()) { + if (readWriteLock()->tryLockForWrite(timeout)) { + q_val |= quintptr(1u); + return true; + } + } + return false; +} + +inline QReadWriteLock* QTryWriteLocker::readWriteLock() const { + return reinterpret_cast(q_val & ~quintptr(1u)); +} + +#endif // hifi_QTryWriteLocker_h \ No newline at end of file