Skip to content

Commit fc6ce90

Browse files
authored
Merge pull request #15524 from daschuer/applyMappingFix
Fix deadlock with mappings for display controllers
2 parents f0fdd67 + 5c4a19d commit fc6ce90

1 file changed

Lines changed: 12 additions & 3 deletions

File tree

src/controllers/controllermanager.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ void ControllerManager::slotPollDevices() {
354354
// we are cooperative a skip the next cycle to free at least some
355355
// CPU time
356356
//
357-
// Some random test data form a i5-3317U CPU @ 1.70GHz Running
357+
// Some random test data from a i5-3317U CPU @ 1.70GHz Running
358358
// Ubuntu Trusty:
359359
// * Idle poll: ~5 µs.
360360
// * 5 messages burst (full midi bandwidth): ~872 µs.
@@ -412,6 +412,8 @@ void ControllerManager::closeController(Controller* pController) {
412412
ConfigKey("[Controller]", sanitizeDeviceName(pController->getName())), 0);
413413
}
414414

415+
// This needs to be called in a Qt::BlockingQueuedConnection so that the
416+
// signaling thread can't alter the LegacyControllerMapping during applying
415417
void ControllerManager::slotApplyMapping(Controller* pController,
416418
std::shared_ptr<LegacyControllerMapping> pMapping,
417419
bool bEnabled) {
@@ -434,19 +436,26 @@ void ControllerManager::slotApplyMapping(Controller* pController,
434436
qWarning() << "Mapping is dirty, changes might be lost on restart!";
435437
}
436438

437-
438439
// Save the file path/name in the config so it can be auto-loaded at
439440
// startup next time
440441
m_pConfig->set(key, pMapping->filePath());
441442

442443
pController->setMapping(std::move(pMapping));
443444

444445
if (bEnabled) {
445-
openController(pController);
446446
emit mappingApplied(pController->isMappable());
447447
} else {
448448
emit mappingApplied(false);
449+
return;
449450
}
451+
452+
// Note: openController() may call ControllerRenderingEngine::setup()
453+
// Which has a blocking invokeMethod() call for QOffscreenSurface::create()
454+
// That why we need to return from this blocking call first.
455+
QMetaObject::invokeMethod(
456+
this,
457+
[this, pController]() { openController(pController); },
458+
Qt::QueuedConnection);
450459
}
451460

452461
// static

0 commit comments

Comments
 (0)