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 <cassert>
#include <QtCore/QMutexLocker>
#include <QtCore/QReadLocker>
#include <QtCore/QThread>
#include <QtCore/QWriteLocker>
#include <QtQml/QQmlContext>
#include <shared/QtHelpers.h>
@ -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();
}

View file

@ -11,9 +11,10 @@
#ifndef hifi_ContextAwareProfile_h
#define hifi_ContextAwareProfile_h
#include <QtCore/QtGlobal>
#include <atomic>
#include <QtCore/QMap>
#include <QtCore/QMutex>
#include <QtCore/QReadWriteLock>
#include <QtCore/QSet>
#include <QtCore/QSharedPointer>
#if !defined(Q_OS_ANDROID)
@ -29,37 +30,8 @@ using ContextAwareProfileParent = QObject;
using RequestInterceptorParent = QObject;
#endif
#include <NumericalConstants.h>
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 {
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<bool> _isRestricted{ false };
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