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
540 540
541QObject* TabletProxy::addButton(const QVariant& properties) {541QObject* TabletProxy::addButton(const QVariant& properties) {
542 auto tabletButtonProxy = QSharedPointer<TabletButtonProxy>(new TabletButtonProxy(properties.toMap()));542 auto tabletButtonProxy = QSharedPointer<TabletButtonProxy>(new TabletButtonProxy(properties.toMap()));
543 std::lock_guard<std::mutex> guard(_tabletMutex);543 std::unique_lock<std::mutex> guard(_tabletMutex);
544 _tabletButtonProxies.push_back(tabletButtonProxy);544 _tabletButtonProxies.push_back(tabletButtonProxy);
545 if (!_toolbarMode && _qmlTabletRoot) {545 if (!_toolbarMode && _qmlTabletRoot) {
546 auto tablet = getQmlTablet();546 auto tablet = getQmlTablet();
@@ -550,7 +550,6 @@ QObject* TabletProxy::addButton(const QVariant& properties) { · 3 unmodified lines
550 qCCritical(scriptengine) << "Could not find tablet in TabletRoot.qml";550 qCCritical(scriptengine) << "Could not find tablet in TabletRoot.qml";
551 }551 }
552 } else if (_toolbarMode) {552 } else if (_toolbarMode) {
553
554 auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();553 auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
555 QObject* toolbarProxy = tabletScriptingInterface->getSystemToolbarProxy();554 QObject* toolbarProxy = tabletScriptingInterface->getSystemToolbarProxy();
556 555
@@ -559,6 +558,8 @@ QObject* TabletProxy::addButton(const QVariant& properties) { · 2 unmodified lines
559 connectionType = Qt::BlockingQueuedConnection;558 connectionType = Qt::BlockingQueuedConnection;
560 }559 }
561 560
561 guard.unlock();
562
562 // copy properties from tablet button proxy to toolbar button proxy.563 // copy properties from tablet button proxy to toolbar button proxy.
563 QObject* toolbarButtonProxy = nullptr;564 QObject* toolbarButtonProxy = nullptr;
564 bool hasResult = QMetaObject::invokeMethod(toolbarProxy, "addButton", connectionType, Q_RETURN_ARG(QObject*, toolbarButtonProxy), Q_ARG(QVariant, tabletButtonProxy->getProperties()));565 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
576}577}
577 578
578void TabletProxy::removeButton(QObject* tabletButtonProxy) {579void TabletProxy::removeButton(QObject* tabletButtonProxy) {
579 std::lock_guard<std::mutex> guard(_tabletMutex);580 std::unique_lock<std::mutex> guard(_tabletMutex);
580 581
581 auto tablet = getQmlTablet();582 auto tablet = getQmlTablet();
582 if (!tablet) {583 if (!tablet) {
583 qCCritical(scriptengine) << "Could not find tablet in TabletRoot.qml";584 qCCritical(scriptengine) << "Could not find tablet in TabletRoot.qml";
584 }585 }
585 586
586 auto iter = std::find(_tabletButtonProxies.begin(), _tabletButtonProxies.end(), tabletButtonProxy);587 QSharedPointer<TabletButtonProxy> buttonProxy;
587 if (iter != _tabletButtonProxies.end()) {588 {
588 if (!_toolbarMode && _qmlTabletRoot) {589 auto iter = std::find(_tabletButtonProxies.begin(), _tabletButtonProxies.end(), tabletButtonProxy);
589 (*iter)->setQmlButton(nullptr);590 if (iter == _tabletButtonProxies.end()) {
590 if (tablet) {591 qCWarning(scriptengine) << "TabletProxy::removeButton() could not find button " << tabletButtonProxy;
591 QMetaObject::invokeMethod(tablet, "removeButtonProxy", Qt::AutoConnection, Q_ARG(QVariant, (*iter)->getProperties()));592 return;
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);
600 }593 }
594 buttonProxy = *iter;
601 _tabletButtonProxies.erase(iter);595 _tabletButtonProxies.erase(iter);
602 } else {596 }
603 qCWarning(scriptengine) << "TabletProxy::removeButton() could not find button " << tabletButtonProxy;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);
604 }612 }
605}613}
606 614