99#include " browser-render-handler.hpp"
1010#include " browser-load-handler.hpp"
1111#include " browser-obs-bridge-base.hpp"
12+ #include < chrono>
13+ #include < thread>
1214
1315BrowserManager::BrowserManager ()
1416: pimpl(new BrowserManager::Impl())
@@ -104,25 +106,31 @@ void BrowserManager::DispatchJSEvent(const char *eventName, const char *jsonStri
104106 pimpl->DispatchJSEvent (eventName, jsonString);
105107}
106108
107- BrowserManager::Impl::Impl ()
109+ std::string getBootstrap ()
108110{
109- os_event_init (&dispatchEvent, OS_EVENT_TYPE_AUTO);
110- pthread_mutex_init (&dispatchLock, nullptr );
111+ std::string modulePath (BrowserManager::Instance ()->GetModulePath ());
112+ std::string parentPath (modulePath.substr (0 ,
113+ modulePath.find_last_of (' /' ) + 1 ));
114+ #ifdef _WIN32
115+ return parentPath + " /cef-bootstrap.exe" ;
116+ #else
117+ return parentPath + " /cef-bootstrap" ;
118+ #endif
111119}
112120
113- BrowserManager::Impl::~Impl ()
114- {
115- os_event_destroy (dispatchEvent);
116- pthread_mutex_destroy (&dispatchLock);
117- }
121+ // ////////////////////////////////////////////////////////////////////////
122+ // BrowserManager::Impl
123+ BrowserManager::Impl::Impl () {}
124+
125+ BrowserManager::Impl::~Impl () { }
118126
119127int BrowserManager::Impl::CreateBrowser (
120128 const BrowserSettings &browserSettings,
121129 const std::shared_ptr<BrowserListener> &browserListener)
122130{
123131 int browserIdentifier = 0 ;
124- os_event_t *createdEvent ;
125- os_event_init (&createdEvent, OS_EVENT_TYPE_AUTO) ;
132+ std::mutex createMutex ;
133+ std::condition_variable createEvent ;
126134
127135 BrowserOBSBridge *browserOBSBridge = new BrowserOBSBridgeBase ();
128136
@@ -157,11 +165,11 @@ int BrowserManager::Impl::CreateBrowser(
157165 browserIdentifier = browser->GetIdentifier ();
158166 browserMap[browserIdentifier] = browser;
159167 }
160- os_event_signal (createdEvent );
168+ createEvent. notify_all ( );
161169 }));
162170
163- os_event_wait (createdEvent );
164- os_event_destroy (createdEvent );
171+ std::unique_lock<std::mutex> createLock (createMutex );
172+ createEvent. wait (createLock );
165173 return browserIdentifier;
166174}
167175
@@ -170,15 +178,14 @@ BrowserManager::Impl::DestroyBrowser(int browserIdentifier)
170178{
171179 if (browserMap.count (browserIdentifier) > 0 ) {
172180 CefRefPtr<CefBrowser> browser = browserMap[browserIdentifier];
173- os_event_t *closeEvent ;
174- os_event_init (&closeEvent, OS_EVENT_TYPE_AUTO) ;
175- CefPostTask (TID_UI, BrowserTask::newTask ([&, browser]
181+ std::mutex closeMutex ;
182+ std::condition_variable closeEvent ;
183+ CefPostTask (TID_UI, BrowserTask::newTask ([&, browser]
176184 {
177185 browser->GetHost ()->CloseBrowser (true );
178- os_event_signal ( closeEvent);
186+ closeEvent. notify_all ( );
179187 }));
180- os_event_wait (closeEvent);
181- os_event_destroy (closeEvent);
188+ closeEvent.wait (std::unique_lock<std::mutex>(closeMutex));
182189 browserMap.erase (browserIdentifier);
183190 }
184191}
@@ -198,14 +205,13 @@ void BrowserManager::Impl::ExecuteOnBrowser(int browserIdentifier,
198205 f (browser);
199206 }));
200207 } else {
201- os_event_t *finishedEvent ;
202- os_event_init (&finishedEvent, OS_EVENT_TYPE_AUTO) ;
208+ std::mutex finishedMutex ;
209+ std::condition_variable finishedEvent ;
203210 CefPostTask (TID_UI, BrowserTask::newTask ([&] {
204211 f (browser);
205- os_event_signal ( finishedEvent);
212+ finishedEvent. notify_all ( );
206213 }));
207- os_event_wait (finishedEvent);
208- os_event_destroy (finishedEvent);
214+ finishedEvent.wait (std::unique_lock<std::mutex>(finishedMutex));
209215 }
210216 }
211217}
@@ -221,14 +227,13 @@ void BrowserManager::Impl::ExecuteOnAllBrowsers(
221227 f (browser);
222228 }));
223229 } else {
224- os_event_t *finishedEvent ;
225- os_event_init (&finishedEvent, OS_EVENT_TYPE_AUTO) ;
230+ std::mutex finishedMutex ;
231+ std::condition_variable finishedEvent ;
226232 CefPostTask (TID_UI, BrowserTask::newTask ([&] {
227233 f (browser);
228- os_event_signal ( finishedEvent);
234+ finishedEvent. notify_all ( );
229235 }));
230- os_event_wait (finishedEvent);
231- os_event_destroy (finishedEvent);
236+ finishedEvent.wait (std::unique_lock<std::mutex>(finishedMutex));
232237 }
233238 }
234239}
@@ -363,112 +368,69 @@ void BrowserManager::Impl::DispatchJSEvent(const char *eventName, const char *js
363368 });
364369}
365370
366- void
367- BrowserManager::Impl::Startup ()
371+ void BrowserManager::Impl::Startup ()
368372{
369- pthread_mutex_lock (&dispatchLock);
370- int ret = pthread_create (&managerThread, nullptr ,
371- browserManagerEntry, this );
372-
373- if (ret != 0 ) {
374- blog (LOG_ERROR,
375- " BrowserManager: failed to create browser "
376- " manager thread." );
377- threadAlive = false ;
378- }
379- else {
380- threadAlive = true ;
381- }
382- pthread_mutex_unlock (&dispatchLock);
383-
384- return ;
385- }
373+ // Initialize CEF
374+ CefMainArgs mainArgs;
375+ CefSettings settings;
376+ settings.log_severity = LOGSEVERITY_VERBOSE;
377+ settings.windowless_rendering_enabled = true ;
378+ settings.no_sandbox = false ;
379+ settings.multi_threaded_message_loop = true ;
380+ CefString (&settings.cache_path ).FromASCII (obs_module_config_path (" " ));
381+ CefString (&settings.browser_subprocess_path ) = getBootstrap ();
382+ CefRefPtr<BrowserApp> app (new BrowserApp ());
383+ CefExecuteProcess (mainArgs, app, nullptr );
384+ CefInitialize (mainArgs, settings, app, nullptr );
385+ CefRegisterSchemeHandlerFactory (" http" , " absolute" , new BrowserSchemeHandlerFactory ());
386386
387- void BrowserManager::Impl::Shutdown ()
388- {
389- os_event_t *shutdown_event;
390- os_event_init (&shutdown_event, OS_EVENT_TYPE_AUTO);
391-
392- // post the task
393- CefPostTask (TID_UI, BrowserTask::newTask ([] {
394- CefQuitMessageLoop ();
395- }));
387+ // Initialize event queue.
388+ {
389+ std::lock_guard<std::mutex> lock (events.mutex );
390+ events.bQuit = false ;
391+ events.thread = std::thread (QueueThreadMain, this );
392+ }
396393
397- // this event will then get processed and shut down the dispatcher loop
398- PushEvent ([this , shutdown_event] {
399- threadAlive = false ;
400- os_event_signal (shutdown_event);
401- });
402394
403- os_event_wait (shutdown_event);
404- os_event_destroy (shutdown_event);
405395 return ;
406396}
407397
408- void * BrowserManager::Impl::browserManagerEntry ( void * threadArgument )
398+ void BrowserManager::Impl::Shutdown ( )
409399{
410- BrowserManager::Impl *browserManager =
411- static_cast <BrowserManager::Impl *>(threadArgument);
412- browserManager->BrowserManagerEntry ();
413- return nullptr ;
400+ // Quit Event Thread
401+ events.bQuit = true ;
402+ events.condvar .notify_all ();
403+ events.thread .join ();
404+
405+ // Shut down CEF
406+ CefShutdown ();
407+ return ;
414408}
415409
416410void BrowserManager::Impl::PushEvent (std::function<void ()> event)
417411{
418- pthread_mutex_lock (&dispatchLock);
419- queue.push_back (event);
420- pthread_mutex_unlock (&dispatchLock);
421- os_event_signal (dispatchEvent);
412+ std::lock_guard<std::mutex> lock (events.mutex );
413+ events.queue .push (event);
414+ events.condvar .notify_one ();
422415}
423416
424- std::string getBootstrap ( )
417+ void BrowserManager::Impl::QueueThreadMain ( void * data )
425418{
426- std::string modulePath (BrowserManager::Instance ()->GetModulePath ());
427- std::string parentPath (modulePath.substr (0 ,
428- modulePath.find_last_of (' /' ) + 1 ));
429- #ifdef _WIN32
430- return parentPath + " /cef-bootstrap.exe" ;
431- #else
432- return parentPath + " /cef-bootstrap" ;
433- #endif
419+ auto obj = static_cast <BrowserManager::Impl*>(data);
420+ obj->QueueThreadLocalMain ();
434421}
435422
436- void BrowserManager::Impl::BrowserManagerEntry ()
437- {
438- std::string bootstrapPath = getBootstrap ();
439- bool thread_exit = false ;
440- PushEvent ([] {
441- CefMainArgs mainArgs;
442- CefSettings settings;
443- settings.log_severity = LOGSEVERITY_VERBOSE;
444- settings.windowless_rendering_enabled = true ;
445- settings.no_sandbox = true ;
446- CefString (&settings.cache_path ).FromASCII (obs_module_config_path (" " ));
447- CefString (&settings.browser_subprocess_path ) = getBootstrap ();
448- CefRefPtr<BrowserApp> app (new BrowserApp ());
449- CefExecuteProcess (mainArgs, app, nullptr );
450- CefInitialize (mainArgs, settings, app, nullptr );
451- CefRegisterSchemeHandlerFactory (" http" , " absolute" , new BrowserSchemeHandlerFactory ());
452- CefRunMessageLoop ();
453- CefShutdown ();
454- });
455-
456- while (true ) {
457-
458- if (os_event_timedwait (dispatchEvent, 10 ) != ETIMEDOUT) {
459- pthread_mutex_lock (&dispatchLock);
460- while (!queue.empty ()) {
461- auto event = queue[0 ];
462- event ();
463- queue.erase (queue.begin ());
464- }
465- thread_exit = !threadAlive;
466- pthread_mutex_unlock (&dispatchLock);
467- if (thread_exit) {
468- return ;
469- }
423+ void BrowserManager::Impl::QueueThreadLocalMain ()
424+ {
425+ std::unique_lock<std::mutex> ulock (events.mutex );
426+ do {
427+ events.condvar .wait (ulock);
428+ while (events.queue .size () > 0 ) {
429+ auto v = events.queue .front ();
430+ v ();
431+ events.queue .pop ();
470432 }
471- }
433+ } while (events. bQuit == false );
472434}
473435
474436static BrowserManager *instance;
0 commit comments