UI: Fix potential deadlocks when saving

SaveProject calls obs functions that locks certain mutexes, and because
I made it so that SaveProject was being called inside of certain signal
handlers (which could already be locked in other mutexes), it could
cause a mutual deadlock with other threads.

This fix puts the main project saving code in to SaveProjectDeferred,
then pushes it on to the Qt message queue to safely save outside of
those locks.  It's a function that's perfectly safe to put on the
message queue because it will automatically be disabled in certain
circumstances where it would be unsafe to call, such as on shutdown.

This code will also make it so that the project will not needlessly be
saved more than once if the SaveProjectDeferred call was pushed multiple
times on to the queue.
This commit is contained in:
jp9000 2015-07-06 09:02:13 -07:00
parent e30255fbee
commit 49501be2a3
2 changed files with 17 additions and 0 deletions

View file

@ -1103,6 +1103,21 @@ void OBSBasic::SaveProject()
if (disableSaving)
return;
projectChanged = true;
QMetaObject::invokeMethod(this, "SaveProjectDeferred",
Qt::QueuedConnection);
}
void OBSBasic::SaveProjectDeferred()
{
if (disableSaving)
return;
if (!projectChanged)
return;
projectChanged = false;
const char *sceneCollection = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollectionFile");
char savePath[512];

View file

@ -75,6 +75,7 @@ private:
bool loaded = false;
long disableSaving = 1;
bool projectChanged = false;
QPointer<QThread> updateCheckThread;
QPointer<QThread> logUploadThread;
@ -197,6 +198,7 @@ public slots:
void RecordingStart();
void RecordingStop(int code);
void SaveProjectDeferred();
void SaveProject();
private slots: