mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 05:37:17 +02:00
Restructure ContextAwareProfile from a (thread-blocking) polling to a threadsafe-notification
This commit is contained in:
parent
bfb4eaeb21
commit
61e6e8dfc9
2 changed files with 89 additions and 16 deletions
|
@ -20,20 +20,62 @@
|
||||||
|
|
||||||
static const QString RESTRICTED_FLAG_PROPERTY = "RestrictFileAccess";
|
static const QString RESTRICTED_FLAG_PROPERTY = "RestrictFileAccess";
|
||||||
|
|
||||||
ContextAwareProfile::ContextAwareProfile(QQmlContext* context) :
|
QMutex RestrictedContextMonitor::gl_monitorMapProtect;
|
||||||
ContextAwareProfileParent(context), _context(context) {
|
RestrictedContextMonitor::TMonitorMap RestrictedContextMonitor::gl_monitorMap;
|
||||||
assert(context);
|
|
||||||
|
RestrictedContextMonitor::~RestrictedContextMonitor() {
|
||||||
|
gl_monitorMapProtect.lock();
|
||||||
|
TMonitorMap::iterator lookup = gl_monitorMap.find(context);
|
||||||
|
if (lookup != gl_monitorMap.end()) {
|
||||||
|
gl_monitorMap.erase(lookup);
|
||||||
|
}
|
||||||
|
gl_monitorMapProtect.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RestrictedContextMonitor::TSharedPtr RestrictedContextMonitor::getMonitor(QQmlContext* context, bool createIfMissing) {
|
||||||
|
TSharedPtr monitor;
|
||||||
|
|
||||||
|
gl_monitorMapProtect.lock();
|
||||||
|
TMonitorMap::const_iterator lookup = gl_monitorMap.find(context);
|
||||||
|
if (lookup != gl_monitorMap.end()) {
|
||||||
|
monitor = lookup->second.lock();
|
||||||
|
assert(monitor);
|
||||||
|
} else if(createIfMissing) {
|
||||||
|
monitor = std::make_shared<RestrictedContextMonitor>(context);
|
||||||
|
monitor->selfPtr = monitor;
|
||||||
|
gl_monitorMap.insert(TMonitorMap::value_type(context, monitor));
|
||||||
|
}
|
||||||
|
gl_monitorMapProtect.unlock();
|
||||||
|
return monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
_isRestricted.store(_monitor->isRestricted ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
void ContextAwareProfile::restrictContext(QQmlContext* context, bool restrict) {
|
void ContextAwareProfile::restrictContext(QQmlContext* context, bool restrict) {
|
||||||
|
RestrictedContextMonitor::TSharedPtr monitor = RestrictedContextMonitor::getMonitor(context, false);
|
||||||
|
|
||||||
context->setContextProperty(RESTRICTED_FLAG_PROPERTY, restrict);
|
context->setContextProperty(RESTRICTED_FLAG_PROPERTY, restrict);
|
||||||
|
if (monitor && monitor->isRestricted != restrict) {
|
||||||
|
monitor->isRestricted = restrict;
|
||||||
|
monitor->onIsRestrictedChanged(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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,11 +89,10 @@ bool ContextAwareProfile::isRestrictedInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContextAwareProfile::isRestricted() {
|
void ContextAwareProfile::onIsRestrictedChanged(bool newValue) {
|
||||||
auto now = usecTimestampNow();
|
_isRestricted.store(newValue ? 1 : 0);
|
||||||
if (now > _cacheExpiry) {
|
}
|
||||||
_cachedValue = isRestrictedInternal();
|
|
||||||
_cacheExpiry = now + MAX_CACHE_AGE;
|
bool ContextAwareProfile::isRestricted() {
|
||||||
}
|
return _isRestricted.load() != 0;
|
||||||
return _cachedValue;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#define hifi_ContextAwareProfile_h
|
#define hifi_ContextAwareProfile_h
|
||||||
|
|
||||||
#include <QtCore/QtGlobal>
|
#include <QtCore/QtGlobal>
|
||||||
|
#include <QtCore/QMutex>
|
||||||
|
|
||||||
#if !defined(Q_OS_ANDROID)
|
#if !defined(Q_OS_ANDROID)
|
||||||
#include <QtWebEngine/QQuickWebEngineProfile>
|
#include <QtWebEngine/QQuickWebEngineProfile>
|
||||||
|
@ -30,12 +31,39 @@ using RequestInterceptorParent = QObject;
|
||||||
|
|
||||||
class QQmlContext;
|
class QQmlContext;
|
||||||
|
|
||||||
|
class RestrictedContextMonitor : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
typedef std::shared_ptr<RestrictedContextMonitor> TSharedPtr;
|
||||||
|
typedef std::weak_ptr<RestrictedContextMonitor> TWeakPtr;
|
||||||
|
|
||||||
|
inline RestrictedContextMonitor(QQmlContext* c) : context(c) {}
|
||||||
|
~RestrictedContextMonitor();
|
||||||
|
|
||||||
|
static TSharedPtr getMonitor(QQmlContext* context, bool createIfMissing);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void onIsRestrictedChanged(bool newValue);
|
||||||
|
|
||||||
|
public:
|
||||||
|
TWeakPtr selfPtr;
|
||||||
|
QQmlContext* context{ nullptr };
|
||||||
|
bool isRestricted{ true };
|
||||||
|
bool isUninitialized{ true };
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::map<QQmlContext*, TWeakPtr> TMonitorMap;
|
||||||
|
|
||||||
|
static QMutex gl_monitorMapProtect;
|
||||||
|
static TMonitorMap gl_monitorMap;
|
||||||
|
};
|
||||||
|
|
||||||
class ContextAwareProfile : public ContextAwareProfileParent {
|
class ContextAwareProfile : public ContextAwareProfileParent {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
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 {
|
||||||
|
@ -48,9 +76,13 @@ protected:
|
||||||
|
|
||||||
ContextAwareProfile(QQmlContext* parent);
|
ContextAwareProfile(QQmlContext* parent);
|
||||||
QQmlContext* _context{ nullptr };
|
QQmlContext* _context{ nullptr };
|
||||||
bool _cachedValue{ false };
|
QAtomicInt _isRestricted{ 0 };
|
||||||
quint64 _cacheExpiry{ 0 };
|
|
||||||
constexpr static quint64 MAX_CACHE_AGE = MSECS_PER_SECOND;
|
private slots:
|
||||||
|
void onIsRestrictedChanged(bool newValue);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RestrictedContextMonitor::TSharedPtr _monitor;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_FileTypeProfile_h
|
#endif // hifi_FileTypeProfile_h
|
||||||
|
|
Loading…
Reference in a new issue