mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-08 19:23:28 +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";
|
||||
|
||||
ContextAwareProfile::ContextAwareProfile(QQmlContext* context) :
|
||||
ContextAwareProfileParent(context), _context(context) {
|
||||
assert(context);
|
||||
QMutex RestrictedContextMonitor::gl_monitorMapProtect;
|
||||
RestrictedContextMonitor::TMonitorMap RestrictedContextMonitor::gl_monitorMap;
|
||||
|
||||
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) {
|
||||
RestrictedContextMonitor::TSharedPtr monitor = RestrictedContextMonitor::getMonitor(context, false);
|
||||
|
||||
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()) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -47,11 +89,10 @@ bool ContextAwareProfile::isRestrictedInternal() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ContextAwareProfile::isRestricted() {
|
||||
auto now = usecTimestampNow();
|
||||
if (now > _cacheExpiry) {
|
||||
_cachedValue = isRestrictedInternal();
|
||||
_cacheExpiry = now + MAX_CACHE_AGE;
|
||||
}
|
||||
return _cachedValue;
|
||||
void ContextAwareProfile::onIsRestrictedChanged(bool newValue) {
|
||||
_isRestricted.store(newValue ? 1 : 0);
|
||||
}
|
||||
|
||||
bool ContextAwareProfile::isRestricted() {
|
||||
return _isRestricted.load() != 0;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define hifi_ContextAwareProfile_h
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
#include <QtCore/QMutex>
|
||||
|
||||
#if !defined(Q_OS_ANDROID)
|
||||
#include <QtWebEngine/QQuickWebEngineProfile>
|
||||
|
@ -30,12 +31,39 @@ using RequestInterceptorParent = QObject;
|
|||
|
||||
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 {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static void restrictContext(QQmlContext* context, bool restrict = true);
|
||||
bool isRestricted();
|
||||
Q_INVOKABLE bool isRestrictedInternal();
|
||||
Q_INVOKABLE bool isRestrictedGetProperty();
|
||||
protected:
|
||||
|
||||
class RequestInterceptor : public RequestInterceptorParent {
|
||||
|
@ -48,9 +76,13 @@ protected:
|
|||
|
||||
ContextAwareProfile(QQmlContext* parent);
|
||||
QQmlContext* _context{ nullptr };
|
||||
bool _cachedValue{ false };
|
||||
quint64 _cacheExpiry{ 0 };
|
||||
constexpr static quint64 MAX_CACHE_AGE = MSECS_PER_SECOND;
|
||||
QAtomicInt _isRestricted{ 0 };
|
||||
|
||||
private slots:
|
||||
void onIsRestrictedChanged(bool newValue);
|
||||
|
||||
private:
|
||||
RestrictedContextMonitor::TSharedPtr _monitor;
|
||||
};
|
||||
|
||||
#endif // hifi_FileTypeProfile_h
|
||||
|
|
Loading…
Reference in a new issue