fix deadlock when rapidly switching scenes

This commit is contained in:
WarmUpTill 2020-04-12 21:26:45 +02:00
parent 5e92a7bcdf
commit 115a90196c
3 changed files with 15 additions and 12 deletions

View File

@ -997,7 +997,7 @@ void SwitcherData::Thread()
{
break;
}
setDefaultSceneTransitions(lock);
setDefaultSceneTransitions();
if (autoStopEnable)
{
autoStopStreamAndRecording();
@ -1056,14 +1056,14 @@ void SwitcherData::Thread()
}
if (match)
{
switchScene(scene, transition);
switchScene(scene, transition, lock);
}
}
endLoop:
;
}
void switchScene(OBSWeakSource& scene, OBSWeakSource& transition)
void switchScene(OBSWeakSource& scene, OBSWeakSource& transition, unique_lock<mutex>& lock)
{
obs_source_t* source = obs_weak_source_get_source(scene);
obs_source_t* currentSource = obs_frontend_get_current_scene();
@ -1077,22 +1077,26 @@ void switchScene(OBSWeakSource& scene, OBSWeakSource& transition)
if (nextTransitionWs)
{
obs_source_t* nextTransition = obs_weak_source_get_source(nextTransitionWs);
//lock.unlock();
//transitionCv.wait(transitionLock, transitionActiveCheck);
//lock.lock();
lock.unlock();
obs_frontend_set_current_transition(nextTransition);
lock.lock();
obs_source_release(nextTransition);
}
else if (transition)
{
obs_source_t* nextTransition = obs_weak_source_get_source(transition);
//lock.unlock();
//transitionCv.wait(transitionLock, transitionActiveCheck);
//lock.lock();
lock.unlock();
obs_frontend_set_current_transition(nextTransition);
lock.lock();
obs_source_release(nextTransition);
}
// this call might block when OBS_FRONTEND_EVENT_SCENE_CHANGED is active and mutex is held
// thus unlock mutex to avoid deadlock
lock.unlock();
obs_frontend_set_current_scene(source);
lock.lock();
obs_weak_source_release(nextTransitionWs);
}
obs_source_release(currentSource);
@ -1155,7 +1159,6 @@ static void OBSEvent(enum obs_frontend_event event, void* switcher)
{
SwitcherData* s = (SwitcherData*)switcher;
lock_guard<mutex> lock(s->m);
//stop waiting if scene was manually changed
if (s->sceneChangedDuringWait())
s->cv.notify_one();

View File

@ -275,7 +275,7 @@ struct SwitcherData
bool sceneChangedDuringWait();
bool prioFuncsValid();
void writeSceneInfoToFile();
void setDefaultSceneTransitions(unique_lock<mutex>& lock);
void setDefaultSceneTransitions();
void autoStopStreamAndRecording();
bool checkPause();
void checkSceneRoundTrip(bool& match, OBSWeakSource& scene, OBSWeakSource& transition, unique_lock<mutex>& lock);

View File

@ -153,7 +153,7 @@ void SceneSwitcher::on_defaultTransitionsRemove_clicked()
delete item;
}
void SwitcherData::setDefaultSceneTransitions(unique_lock<mutex>& lock)
void SwitcherData::setDefaultSceneTransitions()
{
obs_source_t* currentSource = obs_frontend_get_current_scene();
obs_weak_source_t* ws = obs_source_get_weak_source(currentSource);