restructured the code to using a set of ContextAwareProfile objects rather than subscribing to an intermediate object

changed _isRestricted from QAtomicInt to std::atomic<bool>
This commit is contained in:
Heather Anderson 2020-07-30 22:49:54 -07:00
parent 47c96fcff5
commit 4f5f46a623
2 changed files with 59 additions and 76 deletions

View file

@ -12,8 +12,9 @@
#include "ContextAwareProfile.h" #include "ContextAwareProfile.h"
#include <cassert> #include <cassert>
#include <QtCore/QMutexLocker> #include <QtCore/QReadLocker>
#include <QtCore/QThread> #include <QtCore/QThread>
#include <QtCore/QWriteLocker>
#include <QtQml/QQmlContext> #include <QtQml/QQmlContext>
#include <shared/QtHelpers.h> #include <shared/QtHelpers.h>
@ -21,53 +22,59 @@
static const QString RESTRICTED_FLAG_PROPERTY = "RestrictFileAccess"; static const QString RESTRICTED_FLAG_PROPERTY = "RestrictFileAccess";
QMutex RestrictedContextMonitor::gl_monitorMapProtect; QReadWriteLock ContextAwareProfile::gl_contextMapProtect;
RestrictedContextMonitor::TMonitorMap RestrictedContextMonitor::gl_monitorMap; ContextAwareProfile::ContextMap ContextAwareProfile::gl_contextMap;
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;
}
ContextAwareProfile::ContextAwareProfile(QQmlContext* context) : ContextAwareProfileParent(context), _context(context) { ContextAwareProfile::ContextAwareProfile(QQmlContext* context) : ContextAwareProfileParent(context), _context(context) {
assert(context); assert(context);
_monitor = RestrictedContextMonitor::getMonitor(context, true); { // register our object for future updates
assert(_monitor); QWriteLocker guard(&gl_contextMapProtect);
connect(_monitor.get(), &RestrictedContextMonitor::onIsRestrictedChanged, this, &ContextAwareProfile::onIsRestrictedChanged); ContextMap::iterator setLookup = gl_contextMap.find(_context);
if (_monitor->_isUninitialized) { if (setLookup == gl_contextMap.end()) {
_monitor->_isRestricted = isRestrictedGetProperty(); setLookup = gl_contextMap.insert(_context, ContextAwareProfileSet());
_monitor->_isUninitialized = false; }
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) { void ContextAwareProfile::restrictContext(QQmlContext* context, bool restrict) {
RestrictedContextMonitor::TSharedPointer monitor = RestrictedContextMonitor::getMonitor(context, false);
// set the QML property
context->setContextProperty(RESTRICTED_FLAG_PROPERTY, restrict); context->setContextProperty(RESTRICTED_FLAG_PROPERTY, restrict);
if (monitor && monitor->_isRestricted != restrict) {
monitor->_isRestricted = restrict; // broadcast the new value to any registered ContextAwareProfile objects
monitor->onIsRestrictedChanged(restrict); { // 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) { void ContextAwareProfile::onIsRestrictedChanged(bool newValue) {
_isRestricted.store(newValue ? 1 : 0); _isRestricted.store(newValue);
} }
bool ContextAwareProfile::isRestricted() { bool ContextAwareProfile::isRestricted() {
return _isRestricted.load() != 0; return _isRestricted.load();
} }

View file

@ -11,9 +11,10 @@
#ifndef hifi_ContextAwareProfile_h #ifndef hifi_ContextAwareProfile_h
#define hifi_ContextAwareProfile_h #define hifi_ContextAwareProfile_h
#include <QtCore/QtGlobal> #include <atomic>
#include <QtCore/QMap> #include <QtCore/QMap>
#include <QtCore/QMutex> #include <QtCore/QReadWriteLock>
#include <QtCore/QSet>
#include <QtCore/QSharedPointer> #include <QtCore/QSharedPointer>
#if !defined(Q_OS_ANDROID) #if !defined(Q_OS_ANDROID)
@ -29,37 +30,8 @@ using ContextAwareProfileParent = QObject;
using RequestInterceptorParent = QObject; using RequestInterceptorParent = QObject;
#endif #endif
#include <NumericalConstants.h>
class QQmlContext; class QQmlContext;
class RestrictedContextMonitor : public QObject {
Q_OBJECT
public:
typedef QSharedPointer<RestrictedContextMonitor> TSharedPointer;
typedef QWeakPointer<RestrictedContextMonitor> 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<QQmlContext*, TWeakPointer> TMonitorMap;
static QMutex gl_monitorMapProtect;
static TMonitorMap gl_monitorMap;
};
class ContextAwareProfile : public ContextAwareProfileParent { class ContextAwareProfile : public ContextAwareProfileParent {
Q_OBJECT Q_OBJECT
public: public:
@ -77,14 +49,18 @@ protected:
}; };
ContextAwareProfile(QQmlContext* parent); ContextAwareProfile(QQmlContext* parent);
QQmlContext* _context{ nullptr }; ~ContextAwareProfile();
QAtomicInt _isRestricted{ 0 };
private slots:
void onIsRestrictedChanged(bool newValue); void onIsRestrictedChanged(bool newValue);
QQmlContext* _context{ nullptr };
std::atomic<bool> _isRestricted{ false };
private: private:
RestrictedContextMonitor::TSharedPointer _monitor; typedef QSet<ContextAwareProfile*> ContextAwareProfileSet;
typedef QMap<QQmlContext*, ContextAwareProfileSet> ContextMap;
static QReadWriteLock gl_contextMapProtect;
static ContextMap gl_contextMap;
}; };
#endif // hifi_FileTypeProfile_h #endif // hifi_FileTypeProfile_h