History

Attempt to resolve Tablet scripting interface deadlocks

Bradley Austin Davis committed 9 years ago

Commit 30c86ff1 parent 0ccd0d31 file · +27 −19Browse files

Showing the changes to libraries/script-engine/src/TabletScriptingInterface.cpp (1 of 1 file). Show all

Unified · Split

libraries/script-engine/src/TabletScriptingInterface.cpp+27−19
@@ -540,7 +540,7 @@ void TabletProxy::gotoWebScreen(const QString& url, const QString& injectedJavaS · 539 unmodified lines
540540
541541 QObject* TabletProxy::addButton(const QVariant& properties) {
542542 auto tabletButtonProxy = QSharedPointer<TabletButtonProxy>(new TabletButtonProxy(properties.toMap()));
543− std::lock_guard<std::mutex> guard(_tabletMutex);
543+ std::unique_lock<std::mutex> guard(_tabletMutex);
544544 _tabletButtonProxies.push_back(tabletButtonProxy);
545545 if (!_toolbarMode && _qmlTabletRoot) {
546546 auto tablet = getQmlTablet();
@@ -550,7 +550,6 @@ QObject* TabletProxy::addButton(const QVariant& properties) { · 3 unmodified lines
550550 qCCritical(scriptengine) << "Could not find tablet in TabletRoot.qml";
551551 }
552552 } else if (_toolbarMode) {
553−
554553 auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
555554 QObject* toolbarProxy = tabletScriptingInterface->getSystemToolbarProxy();
556555
@@ -559,6 +558,8 @@ QObject* TabletProxy::addButton(const QVariant& properties) { · 2 unmodified lines
559558 connectionType = Qt::BlockingQueuedConnection;
560559 }
561560
561+ guard.unlock();
562+
562563 // copy properties from tablet button proxy to toolbar button proxy.
563564 QObject* toolbarButtonProxy = nullptr;
564565 bool hasResult = QMetaObject::invokeMethod(toolbarProxy, "addButton", connectionType, Q_RETURN_ARG(QObject*, toolbarButtonProxy), Q_ARG(QVariant, tabletButtonProxy->getProperties()));
@@ -576,31 +577,38 @@ bool TabletProxy::onHomeScreen() { · 11 unmodified lines
576577 }
577578
578579 void TabletProxy::removeButton(QObject* tabletButtonProxy) {
579− std::lock_guard<std::mutex> guard(_tabletMutex);
580+ std::unique_lock<std::mutex> guard(_tabletMutex);
580581
581582 auto tablet = getQmlTablet();
582583 if (!tablet) {
583584 qCCritical(scriptengine) << "Could not find tablet in TabletRoot.qml";
584585 }
585586
586− auto iter = std::find(_tabletButtonProxies.begin(), _tabletButtonProxies.end(), tabletButtonProxy);
587− if (iter != _tabletButtonProxies.end()) {
588− if (!_toolbarMode && _qmlTabletRoot) {
589− (*iter)->setQmlButton(nullptr);
590− if (tablet) {
591− QMetaObject::invokeMethod(tablet, "removeButtonProxy", Qt::AutoConnection, Q_ARG(QVariant, (*iter)->getProperties()));
592− }
593− } else if (_toolbarMode) {
594− auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
595− QObject* toolbarProxy = tabletScriptingInterface->getSystemToolbarProxy();
596−
597− // remove button from toolbarProxy
598− QMetaObject::invokeMethod(toolbarProxy, "removeButton", Qt::AutoConnection, Q_ARG(QVariant, (*iter)->getUuid().toString()));
599− (*iter)->setToolbarButtonProxy(nullptr);
587+ QSharedPointer<TabletButtonProxy> buttonProxy;
588+ {
589+ auto iter = std::find(_tabletButtonProxies.begin(), _tabletButtonProxies.end(), tabletButtonProxy);
590+ if (iter == _tabletButtonProxies.end()) {
591+ qCWarning(scriptengine) << "TabletProxy::removeButton() could not find button " << tabletButtonProxy;
592+ return;
600593 }
594+ buttonProxy = *iter;
601595 _tabletButtonProxies.erase(iter);
602− } else {
603− qCWarning(scriptengine) << "TabletProxy::removeButton() could not find button " << tabletButtonProxy;
596+ }
597+
598+ if (!_toolbarMode && _qmlTabletRoot) {
599+ buttonProxy->setQmlButton(nullptr);
600+ if (tablet) {
601+ guard.unlock();
602+ QMetaObject::invokeMethod(tablet, "removeButtonProxy", Qt::AutoConnection, Q_ARG(QVariant, buttonProxy->getProperties()));
603+ }
604+ } else if (_toolbarMode) {
605+ auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
606+ QObject* toolbarProxy = tabletScriptingInterface->getSystemToolbarProxy();
607+
608+ // remove button from toolbarProxy
609+ guard.unlock();
610+ QMetaObject::invokeMethod(toolbarProxy, "removeButton", Qt::AutoConnection, Q_ARG(QVariant, buttonProxy->getUuid().toString()));
611+ buttonProxy->setToolbarButtonProxy(nullptr);
604612 }
605613 }
606614