Skip to content

Commit 3c94aab

Browse files
committed
update mac-obs-browser to not block main thread (CefRunMessageLoop)
* call CefDoMessageLoopWork instead of CefRunMessageLoop which is a blocking call * QoL change for dev: update ExecuteTask/ExecuteSyncTask to check if invoked on main thread. When debugging slobs, we're on main thread. But when this code is invoked from SLD, we're running from an async thread. so this code enables the task to be executed with no thought or care where its been run from.
1 parent c404f38 commit 3c94aab

File tree

3 files changed

+50
-14
lines changed

3 files changed

+50
-14
lines changed

browser-mac.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ bool ExecuteNextBrowserTask();
4444
void ExecuteTask(MessageTask task);
4545
void ExecuteSyncTask(MessageTask task);
4646
void DoCefMessageLoop(int ms);
47+
void DoCefMessageLoopTimer(float ms);
48+
void StopCefMessageLoopTimer();
4749
void Process();
4850
#if 0 // REMOVE_DUPLICATE
4951
void QueueBrowserTask(CefRefPtr<CefBrowser> browser, BrowserFunc func);

browser-mac.mm

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,26 @@ bool ExecuteNextBrowserTask()
4545

4646
void ExecuteTask(MessageTask task)
4747
{
48-
dispatch_async(dispatch_get_main_queue(), ^{
48+
// Protect against exception if already on main thread
49+
if ([NSThread isMainThread]) {
4950
task();
50-
});
51+
} else {
52+
dispatch_async(dispatch_get_main_queue(), ^{
53+
task();
54+
});
55+
}
5156
}
5257

5358
void ExecuteSyncTask(MessageTask task)
5459
{
55-
dispatch_sync(dispatch_get_main_queue(), ^{
60+
// Protect against exception if already on main thread
61+
if ([NSThread isMainThread]) {
5662
task();
57-
});
63+
} else {
64+
dispatch_sync(dispatch_get_main_queue(), ^{
65+
task();
66+
});
67+
}
5868
}
5969

6070
void DoCefMessageLoop(int)
@@ -64,6 +74,24 @@ void DoCefMessageLoop(int)
6474
});
6575
}
6676

77+
static NSTimer *cefTimer = nil;
78+
79+
void DoCefMessageLoopTimer(float ms)
80+
{
81+
cefTimer = [NSTimer
82+
scheduledTimerWithTimeInterval:ms
83+
repeats:YES
84+
block:^(NSTimer *) {
85+
CefDoMessageLoopWork();
86+
}];
87+
}
88+
89+
void StopCefMessageLoopTimer()
90+
{
91+
[cefTimer invalidate];
92+
cefTimer = nil;
93+
}
94+
6795
void Process()
6896
{
6997
dispatch_async(dispatch_get_main_queue(), ^{

obs-browser-plugin.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,8 @@ static obs_data_array_t *browser_source_get_messages(void *data)
333333
messages = obs_data_array_create();
334334
for (const auto &message : bs->messagesToApp) {
335335
obs_data_t *msg_data = obs_data_create();
336-
obs_data_set_string(msg_data, "message", message.c_str());
336+
obs_data_set_string(msg_data, "message",
337+
message.c_str());
337338
obs_data_array_push_back(messages, msg_data);
338339
obs_data_release(msg_data);
339340
}
@@ -529,15 +530,9 @@ static void BrowserShutdown(void)
529530
#ifndef ENABLE_BROWSER_QT_LOOP
530531
static void BrowserManagerThread(obs_data_t *settings)
531532
{
532-
#ifdef __APPLE__
533-
ExecuteSyncTask([&settings]() {
534-
#endif
535-
BrowserInit(settings);
536-
CefRunMessageLoop();
537-
BrowserShutdown();
538-
#ifdef __APPLE__
539-
});
540-
#endif
533+
BrowserInit(settings);
534+
CefRunMessageLoop();
535+
BrowserShutdown();
541536
}
542537
#endif
543538

@@ -546,6 +541,12 @@ extern "C" EXPORT void obs_browser_initialize(obs_data_t *settings)
546541
if (!os_atomic_set_bool(&manager_initialized, true)) {
547542
#ifdef ENABLE_BROWSER_QT_LOOP
548543
BrowserInit(settings);
544+
#elif __APPLE__
545+
546+
ExecuteTask([&settings]() {
547+
BrowserInit(settings);
548+
DoCefMessageLoopTimer(0.01f); // Do not block the main queue so we avoid calling CefRunMessageLoop()
549+
});
549550
#else
550551
auto binded_fn = bind(BrowserManagerThread, settings);
551552
manager_thread = thread(binded_fn);
@@ -956,6 +957,11 @@ void obs_module_unload(void)
956957
{
957958
#ifdef USE_UI_LOOP
958959
BrowserShutdown();
960+
#elif __APPLE__
961+
ExecuteSyncTask([]() {
962+
StopCefMessageLoopTimer();
963+
BrowserShutdown();
964+
});
959965
#else
960966
if (manager_thread.joinable()) {
961967
while (!QueueCEFTask([]() { CefQuitMessageLoop(); }))

0 commit comments

Comments
 (0)