UI: Make workaround for Logitech plugin hard lock
In commit d17ee20863, we attempted to fix a race condition crash in the Logitech plugin by deferring the "stream/recording/replay buffer active" calls to the UI thread. However, the Logitech plugin loop_function funciton can call obs_frontend_streaming_active/etc functions while the UI thread waits for the loop_function thread for many OBS events, causing a hard lock in the Logitech plugin. This fixes that by making the obs_frontend_streaming_active/etc functions completely atomic instead. It's a bit of a hack but it's better than accessing objects.
This commit is contained in:
parent
484c3847fc
commit
1c4a6ca6c6
@ -20,6 +20,10 @@ static T GetOBSRef(QListWidgetItem *item)
|
|||||||
void EnumProfiles(function<bool (const char *, const char *)> &&cb);
|
void EnumProfiles(function<bool (const char *, const char *)> &&cb);
|
||||||
void EnumSceneCollections(function<bool (const char *, const char *)> &&cb);
|
void EnumSceneCollections(function<bool (const char *, const char *)> &&cb);
|
||||||
|
|
||||||
|
extern volatile bool streaming_active;
|
||||||
|
extern volatile bool recording_active;
|
||||||
|
extern volatile bool replaybuf_active;
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
template<typename T> struct OBSStudioCallback {
|
template<typename T> struct OBSStudioCallback {
|
||||||
@ -232,12 +236,7 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
|||||||
|
|
||||||
bool obs_frontend_streaming_active(void) override
|
bool obs_frontend_streaming_active(void) override
|
||||||
{
|
{
|
||||||
bool active;
|
return os_atomic_load_bool(&streaming_active);
|
||||||
QMetaObject::invokeMethod(main,
|
|
||||||
"StreamingActive",
|
|
||||||
WaitConnection(),
|
|
||||||
Q_RETURN_ARG(bool, active));
|
|
||||||
return active;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void obs_frontend_recording_start(void) override
|
void obs_frontend_recording_start(void) override
|
||||||
@ -252,12 +251,7 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
|||||||
|
|
||||||
bool obs_frontend_recording_active(void) override
|
bool obs_frontend_recording_active(void) override
|
||||||
{
|
{
|
||||||
bool active;
|
return os_atomic_load_bool(&recording_active);
|
||||||
QMetaObject::invokeMethod(main,
|
|
||||||
"RecordingActive",
|
|
||||||
WaitConnection(),
|
|
||||||
Q_RETURN_ARG(bool, active));
|
|
||||||
return active;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void obs_frontend_replay_buffer_start(void) override
|
void obs_frontend_replay_buffer_start(void) override
|
||||||
@ -277,12 +271,7 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
|||||||
|
|
||||||
bool obs_frontend_replay_buffer_active(void) override
|
bool obs_frontend_replay_buffer_active(void) override
|
||||||
{
|
{
|
||||||
bool active;
|
return os_atomic_load_bool(&replaybuf_active);
|
||||||
QMetaObject::invokeMethod(main,
|
|
||||||
"ReplayBufferActive",
|
|
||||||
WaitConnection(),
|
|
||||||
Q_RETURN_ARG(bool, active));
|
|
||||||
return active;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *obs_frontend_add_tools_menu_qaction(const char *name) override
|
void *obs_frontend_add_tools_menu_qaction(const char *name) override
|
||||||
|
@ -10,6 +10,10 @@ using namespace std;
|
|||||||
|
|
||||||
extern bool EncoderAvailable(const char *encoder);
|
extern bool EncoderAvailable(const char *encoder);
|
||||||
|
|
||||||
|
volatile bool streaming_active = false;
|
||||||
|
volatile bool recording_active = false;
|
||||||
|
volatile bool replaybuf_active = false;
|
||||||
|
|
||||||
static void OBSStreamStarting(void *data, calldata_t *params)
|
static void OBSStreamStarting(void *data, calldata_t *params)
|
||||||
{
|
{
|
||||||
BasicOutputHandler *output = static_cast<BasicOutputHandler*>(data);
|
BasicOutputHandler *output = static_cast<BasicOutputHandler*>(data);
|
||||||
@ -41,6 +45,7 @@ static void OBSStartStreaming(void *data, calldata_t *params)
|
|||||||
{
|
{
|
||||||
BasicOutputHandler *output = static_cast<BasicOutputHandler*>(data);
|
BasicOutputHandler *output = static_cast<BasicOutputHandler*>(data);
|
||||||
output->streamingActive = true;
|
output->streamingActive = true;
|
||||||
|
os_atomic_set_bool(&streaming_active, true);
|
||||||
QMetaObject::invokeMethod(output->main, "StreamingStart");
|
QMetaObject::invokeMethod(output->main, "StreamingStart");
|
||||||
|
|
||||||
UNUSED_PARAMETER(params);
|
UNUSED_PARAMETER(params);
|
||||||
@ -56,6 +61,7 @@ static void OBSStopStreaming(void *data, calldata_t *params)
|
|||||||
|
|
||||||
output->streamingActive = false;
|
output->streamingActive = false;
|
||||||
output->delayActive = false;
|
output->delayActive = false;
|
||||||
|
os_atomic_set_bool(&streaming_active, false);
|
||||||
QMetaObject::invokeMethod(output->main,
|
QMetaObject::invokeMethod(output->main,
|
||||||
"StreamingStop", Q_ARG(int, code), Q_ARG(QString, arg_last_error));
|
"StreamingStop", Q_ARG(int, code), Q_ARG(QString, arg_last_error));
|
||||||
}
|
}
|
||||||
@ -65,6 +71,7 @@ static void OBSStartRecording(void *data, calldata_t *params)
|
|||||||
BasicOutputHandler *output = static_cast<BasicOutputHandler*>(data);
|
BasicOutputHandler *output = static_cast<BasicOutputHandler*>(data);
|
||||||
|
|
||||||
output->recordingActive = true;
|
output->recordingActive = true;
|
||||||
|
os_atomic_set_bool(&recording_active, true);
|
||||||
QMetaObject::invokeMethod(output->main, "RecordingStart");
|
QMetaObject::invokeMethod(output->main, "RecordingStart");
|
||||||
|
|
||||||
UNUSED_PARAMETER(params);
|
UNUSED_PARAMETER(params);
|
||||||
@ -76,6 +83,7 @@ static void OBSStopRecording(void *data, calldata_t *params)
|
|||||||
int code = (int)calldata_int(params, "code");
|
int code = (int)calldata_int(params, "code");
|
||||||
|
|
||||||
output->recordingActive = false;
|
output->recordingActive = false;
|
||||||
|
os_atomic_set_bool(&recording_active, false);
|
||||||
QMetaObject::invokeMethod(output->main,
|
QMetaObject::invokeMethod(output->main,
|
||||||
"RecordingStop", Q_ARG(int, code));
|
"RecordingStop", Q_ARG(int, code));
|
||||||
|
|
||||||
@ -95,6 +103,7 @@ static void OBSStartReplayBuffer(void *data, calldata_t *params)
|
|||||||
BasicOutputHandler *output = static_cast<BasicOutputHandler*>(data);
|
BasicOutputHandler *output = static_cast<BasicOutputHandler*>(data);
|
||||||
|
|
||||||
output->replayBufferActive = true;
|
output->replayBufferActive = true;
|
||||||
|
os_atomic_set_bool(&replaybuf_active, true);
|
||||||
QMetaObject::invokeMethod(output->main, "ReplayBufferStart");
|
QMetaObject::invokeMethod(output->main, "ReplayBufferStart");
|
||||||
|
|
||||||
UNUSED_PARAMETER(params);
|
UNUSED_PARAMETER(params);
|
||||||
@ -106,6 +115,7 @@ static void OBSStopReplayBuffer(void *data, calldata_t *params)
|
|||||||
int code = (int)calldata_int(params, "code");
|
int code = (int)calldata_int(params, "code");
|
||||||
|
|
||||||
output->replayBufferActive = false;
|
output->replayBufferActive = false;
|
||||||
|
os_atomic_set_bool(&replaybuf_active, false);
|
||||||
QMetaObject::invokeMethod(output->main,
|
QMetaObject::invokeMethod(output->main,
|
||||||
"ReplayBufferStop", Q_ARG(int, code));
|
"ReplayBufferStop", Q_ARG(int, code));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user