Skip to content

Fix deadlock in multithreaded excerpt serialisation - #34733

Draft
ajuncosa wants to merge 1 commit into
musescore:mainfrom
ajuncosa:write-deadlock
Draft

Fix deadlock in multithreaded excerpt serialisation#34733
ajuncosa wants to merge 1 commit into
musescore:mainfrom
ajuncosa:write-deadlock

Conversation

@ajuncosa

Copy link
Copy Markdown
Contributor

The goal is to avoid side effects on the score during write/serialisation, so excerpt serialisation can safely run in separate threads.

There was a deadlock when saving scores that contained multi measure rests and some hidden parts. The save called layout in that case, which frees Systems/Pages, and the EngravingItem destructor calls Score::onElementDestruction which ends with score->elementDestroyed().send(e). This send was cross-thread, and that channel has a main-thread receiver for every score, so the send must register a port on the main thread's slot (QueuePool::regPort), and this locks the same mutex that the main thread is holding while it's processing queued callbacks (in QueuePool::processMessages), and the save is one of the queued commands.

Apart from the freezing doLayout() call, the write was also modifying the score in other ways (start/endCmd(), undoChangeProperty(VISIBLE, true)), and all this routes to the master score's single shared TransactionManager, whose endTransaction calls m_masterScore->update(), relaying out the master from a worker thread.

I have moved the unhide and relayout out of the writer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant