From 4f5f46a6237a693e0c7eb81154b58f11f870e159 Mon Sep 17 00:00:00 2001 From: Heather Anderson Date: Thu, 30 Jul 2020 22:49:54 -0700 Subject: [PATCH] restructured the code to using a set of ContextAwareProfile objects rather than subscribing to an intermediate object changed _isRestricted from QAtomicInt to std::atomic --- .../ui/src/ui/types/ContextAwareProfile.cpp | 87 ++++++++++--------- .../ui/src/ui/types/ContextAwareProfile.h | 48 +++------- 2 files changed, 59 insertions(+), 76 deletions(-) diff --git a/libraries/ui/src/ui/types/ContextAwareProfile.cpp b/libraries/ui/src/ui/types/ContextAwareProfile.cpp index 2399471e29..5df2d34dfa 100644 --- a/libraries/ui/src/ui/types/ContextAwareProfile.cpp +++ b/libraries/ui/src/ui/types/ContextAwareProfile.cpp @@ -12,8 +12,9 @@ #include "ContextAwareProfile.h" #include -#include +#include #include +#include #include #include @@ -21,53 +22,59 @@ static const QString RESTRICTED_FLAG_PROPERTY = "RestrictFileAccess"; -QMutex RestrictedContextMonitor::gl_monitorMapProtect; -RestrictedContextMonitor::TMonitorMap RestrictedContextMonitor::gl_monitorMap; - -RestrictedContextMonitor::~RestrictedContextMonitor() { - QMutexLocker locker(&gl_monitorMapProtect); - TMonitorMap::iterator lookup = gl_monitorMap.find(_context); - if (lookup != gl_monitorMap.end()) { - gl_monitorMap.erase(lookup); - } -} - -RestrictedContextMonitor::TSharedPointer RestrictedContextMonitor::getMonitor(QQmlContext* context, bool createIfMissing) { - TSharedPointer monitor; - - QMutexLocker locker(&gl_monitorMapProtect); - TMonitorMap::const_iterator lookup = gl_monitorMap.find(context); - if (lookup != gl_monitorMap.end()) { - monitor = lookup.value().lock(); - assert(monitor); - } else if(createIfMissing) { - monitor = TSharedPointer::create(context); - monitor->_selfPointer = monitor; - gl_monitorMap.insert(context, monitor); - } - return monitor; -} +QReadWriteLock ContextAwareProfile::gl_contextMapProtect; +ContextAwareProfile::ContextMap ContextAwareProfile::gl_contextMap; ContextAwareProfile::ContextAwareProfile(QQmlContext* context) : ContextAwareProfileParent(context), _context(context) { assert(context); - _monitor = RestrictedContextMonitor::getMonitor(context, true); - assert(_monitor); - connect(_monitor.get(), &RestrictedContextMonitor::onIsRestrictedChanged, this, &ContextAwareProfile::onIsRestrictedChanged); - if (_monitor->_isUninitialized) { - _monitor->_isRestricted = isRestrictedGetProperty(); - _monitor->_isUninitialized = false; + { // register our object for future updates + QWriteLocker guard(&gl_contextMapProtect); + ContextMap::iterator setLookup = gl_contextMap.find(_context); + if (setLookup == gl_contextMap.end()) { + setLookup = gl_contextMap.insert(_context, ContextAwareProfileSet()); + } + assert(setLookup != gl_contextMap.end()); + ContextAwareProfileSet& profileSet = setLookup.value(); + assert(profileSet.find(this) == profileSet.end()); + profileSet.insert(this); + } + + _isRestricted.store(isRestrictedGetProperty()); +} + +ContextAwareProfile::~ContextAwareProfile() { + { // deregister our object + QWriteLocker guard(&gl_contextMapProtect); + ContextMap::iterator setLookup = gl_contextMap.find(_context); + assert(setLookup != gl_contextMap.end()); + if (setLookup != gl_contextMap.end()) { + ContextAwareProfileSet& profileSet = setLookup.value(); + assert(profileSet.find(this) != profileSet.end()); + profileSet.remove(this); + if (profileSet.isEmpty()) { + gl_contextMap.erase(setLookup); + } + } } - _isRestricted.store(_monitor->_isRestricted ? 1 : 0); } void ContextAwareProfile::restrictContext(QQmlContext* context, bool restrict) { - RestrictedContextMonitor::TSharedPointer monitor = RestrictedContextMonitor::getMonitor(context, false); + // set the QML property context->setContextProperty(RESTRICTED_FLAG_PROPERTY, restrict); - if (monitor && monitor->_isRestricted != restrict) { - monitor->_isRestricted = restrict; - monitor->onIsRestrictedChanged(restrict); + + // broadcast the new value to any registered ContextAwareProfile objects + { // deregister our object + QReadLocker guard(&gl_contextMapProtect); + ContextMap::const_iterator setLookup = gl_contextMap.find(context); + if (setLookup != gl_contextMap.end()) { + const ContextAwareProfileSet& profileSet = setLookup.value(); + for (ContextAwareProfileSet::const_iterator profileIterator = profileSet.begin(); + profileIterator != profileSet.end(); profileIterator++) { + (*profileIterator)->onIsRestrictedChanged(restrict); + } + } } } @@ -89,9 +96,9 @@ bool ContextAwareProfile::isRestrictedGetProperty() { } void ContextAwareProfile::onIsRestrictedChanged(bool newValue) { - _isRestricted.store(newValue ? 1 : 0); + _isRestricted.store(newValue); } bool ContextAwareProfile::isRestricted() { - return _isRestricted.load() != 0; + return _isRestricted.load(); } diff --git a/libraries/ui/src/ui/types/ContextAwareProfile.h b/libraries/ui/src/ui/types/ContextAwareProfile.h index 99fee8112d..d8ec762858 100644 --- a/libraries/ui/src/ui/types/ContextAwareProfile.h +++ b/libraries/ui/src/ui/types/ContextAwareProfile.h @@ -11,9 +11,10 @@ #ifndef hifi_ContextAwareProfile_h #define hifi_ContextAwareProfile_h -#include +#include #include -#include +#include +#include #include #if !defined(Q_OS_ANDROID) @@ -29,37 +30,8 @@ using ContextAwareProfileParent = QObject; using RequestInterceptorParent = QObject; #endif -#include - class QQmlContext; -class RestrictedContextMonitor : public QObject { - Q_OBJECT -public: - typedef QSharedPointer TSharedPointer; - typedef QWeakPointer TWeakPointer; - - inline RestrictedContextMonitor(QQmlContext* c) : _context(c) {} - ~RestrictedContextMonitor(); - - static TSharedPointer getMonitor(QQmlContext* context, bool createIfMissing); - -signals: - void onIsRestrictedChanged(bool newValue); - -public: - TWeakPointer _selfPointer; - QQmlContext* _context{ nullptr }; - bool _isRestricted{ true }; - bool _isUninitialized{ true }; - -private: - typedef QMap TMonitorMap; - - static QMutex gl_monitorMapProtect; - static TMonitorMap gl_monitorMap; -}; - class ContextAwareProfile : public ContextAwareProfileParent { Q_OBJECT public: @@ -77,14 +49,18 @@ protected: }; ContextAwareProfile(QQmlContext* parent); - QQmlContext* _context{ nullptr }; - QAtomicInt _isRestricted{ 0 }; - -private slots: + ~ContextAwareProfile(); void onIsRestrictedChanged(bool newValue); + QQmlContext* _context{ nullptr }; + std::atomic _isRestricted{ false }; + private: - RestrictedContextMonitor::TSharedPointer _monitor; + typedef QSet ContextAwareProfileSet; + typedef QMap ContextMap; + + static QReadWriteLock gl_contextMapProtect; + static ContextMap gl_contextMap; }; #endif // hifi_FileTypeProfile_h