mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 18:16:45 +02:00
Merge pull request #311 from odysseus654/pr/webpage-restrict-from-polling
[shutdown-deadlock] Restructure ContextAwareProfile from polling to notifications
This commit is contained in:
commit
e6f3ba4458
2 changed files with 66 additions and 17 deletions
|
@ -12,7 +12,9 @@
|
||||||
#include "ContextAwareProfile.h"
|
#include "ContextAwareProfile.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#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>
|
||||||
|
@ -20,20 +22,63 @@
|
||||||
|
|
||||||
static const QString RESTRICTED_FLAG_PROPERTY = "RestrictFileAccess";
|
static const QString RESTRICTED_FLAG_PROPERTY = "RestrictFileAccess";
|
||||||
|
|
||||||
ContextAwareProfile::ContextAwareProfile(QQmlContext* context) :
|
QReadWriteLock ContextAwareProfile::_contextMapProtect;
|
||||||
ContextAwareProfileParent(context), _context(context) {
|
ContextAwareProfile::ContextMap ContextAwareProfile::_contextMap;
|
||||||
|
|
||||||
|
ContextAwareProfile::ContextAwareProfile(QQmlContext* context) : ContextAwareProfileParent(context), _context(context) {
|
||||||
assert(context);
|
assert(context);
|
||||||
|
|
||||||
|
{ // register our object for future updates
|
||||||
|
QWriteLocker guard(&_contextMapProtect);
|
||||||
|
ContextMap::iterator setLookup = _contextMap.find(_context);
|
||||||
|
if (setLookup == _contextMap.end()) {
|
||||||
|
setLookup = _contextMap.insert(_context, ContextAwareProfileSet());
|
||||||
|
}
|
||||||
|
assert(setLookup != _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(&_contextMapProtect);
|
||||||
|
ContextMap::iterator setLookup = _contextMap.find(_context);
|
||||||
|
assert(setLookup != _contextMap.end());
|
||||||
|
if (setLookup != _contextMap.end()) {
|
||||||
|
ContextAwareProfileSet& profileSet = setLookup.value();
|
||||||
|
assert(profileSet.find(this) != profileSet.end());
|
||||||
|
profileSet.remove(this);
|
||||||
|
if (profileSet.isEmpty()) {
|
||||||
|
_contextMap.erase(setLookup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ContextAwareProfile::restrictContext(QQmlContext* context, bool restrict) {
|
void ContextAwareProfile::restrictContext(QQmlContext* context, bool restrict) {
|
||||||
|
|
||||||
|
// set the QML property
|
||||||
context->setContextProperty(RESTRICTED_FLAG_PROPERTY, restrict);
|
context->setContextProperty(RESTRICTED_FLAG_PROPERTY, restrict);
|
||||||
|
|
||||||
|
// broadcast the new value to any registered ContextAwareProfile objects
|
||||||
|
QReadLocker guard(&_contextMapProtect);
|
||||||
|
ContextMap::const_iterator setLookup = _contextMap.find(context);
|
||||||
|
if (setLookup != _contextMap.end()) {
|
||||||
|
const ContextAwareProfileSet& profileSet = setLookup.value();
|
||||||
|
for (ContextAwareProfileSet::const_iterator profileIterator = profileSet.begin();
|
||||||
|
profileIterator != profileSet.end(); profileIterator++) {
|
||||||
|
(*profileIterator)->_isRestricted.store(restrict);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContextAwareProfile::isRestrictedInternal() {
|
bool ContextAwareProfile::isRestrictedGetProperty() {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
bool restrictedResult = false;
|
bool restrictedResult = false;
|
||||||
BLOCKING_INVOKE_METHOD(this, "isRestrictedInternal", Q_RETURN_ARG(bool, restrictedResult));
|
BLOCKING_INVOKE_METHOD(this, "isRestrictedGetProperty", Q_RETURN_ARG(bool, restrictedResult));
|
||||||
return restrictedResult;
|
return restrictedResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,10 +93,5 @@ bool ContextAwareProfile::isRestrictedInternal() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContextAwareProfile::isRestricted() {
|
bool ContextAwareProfile::isRestricted() {
|
||||||
auto now = usecTimestampNow();
|
return _isRestricted.load();
|
||||||
if (now > _cacheExpiry) {
|
|
||||||
_cachedValue = isRestrictedInternal();
|
|
||||||
_cacheExpiry = now + MAX_CACHE_AGE;
|
|
||||||
}
|
|
||||||
return _cachedValue;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,11 @@
|
||||||
#ifndef hifi_ContextAwareProfile_h
|
#ifndef hifi_ContextAwareProfile_h
|
||||||
#define hifi_ContextAwareProfile_h
|
#define hifi_ContextAwareProfile_h
|
||||||
|
|
||||||
#include <QtCore/QtGlobal>
|
#include <atomic>
|
||||||
|
#include <QtCore/QHash>
|
||||||
|
#include <QtCore/QReadWriteLock>
|
||||||
|
#include <QtCore/QSet>
|
||||||
|
#include <QtCore/QSharedPointer>
|
||||||
|
|
||||||
#if !defined(Q_OS_ANDROID)
|
#if !defined(Q_OS_ANDROID)
|
||||||
#include <QtWebEngine/QQuickWebEngineProfile>
|
#include <QtWebEngine/QQuickWebEngineProfile>
|
||||||
|
@ -26,8 +30,6 @@ using ContextAwareProfileParent = QObject;
|
||||||
using RequestInterceptorParent = QObject;
|
using RequestInterceptorParent = QObject;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <NumericalConstants.h>
|
|
||||||
|
|
||||||
class QQmlContext;
|
class QQmlContext;
|
||||||
|
|
||||||
class ContextAwareProfile : public ContextAwareProfileParent {
|
class ContextAwareProfile : public ContextAwareProfileParent {
|
||||||
|
@ -35,7 +37,7 @@ class ContextAwareProfile : public ContextAwareProfileParent {
|
||||||
public:
|
public:
|
||||||
static void restrictContext(QQmlContext* context, bool restrict = true);
|
static void restrictContext(QQmlContext* context, bool restrict = true);
|
||||||
bool isRestricted();
|
bool isRestricted();
|
||||||
Q_INVOKABLE bool isRestrictedInternal();
|
Q_INVOKABLE bool isRestrictedGetProperty();
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
class RequestInterceptor : public RequestInterceptorParent {
|
class RequestInterceptor : public RequestInterceptorParent {
|
||||||
|
@ -47,10 +49,17 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
ContextAwareProfile(QQmlContext* parent);
|
ContextAwareProfile(QQmlContext* parent);
|
||||||
|
~ContextAwareProfile();
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef QSet<ContextAwareProfile*> ContextAwareProfileSet;
|
||||||
|
typedef QHash<QQmlContext*, ContextAwareProfileSet> ContextMap;
|
||||||
|
|
||||||
QQmlContext* _context{ nullptr };
|
QQmlContext* _context{ nullptr };
|
||||||
bool _cachedValue{ false };
|
std::atomic<bool> _isRestricted{ false };
|
||||||
quint64 _cacheExpiry{ 0 };
|
|
||||||
constexpr static quint64 MAX_CACHE_AGE = MSECS_PER_SECOND;
|
static QReadWriteLock _contextMapProtect;
|
||||||
|
static ContextMap _contextMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_FileTypeProfile_h
|
#endif // hifi_FileTypeProfile_h
|
||||||
|
|
Loading…
Reference in a new issue