Hacky CEF shutdown needed when using CefDoMessageLoopWork

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

Hacky CEF shutdown needed when using CefDoMessageLoopWork

Postby Biohazard » Mon Jun 22, 2020 3:53 pm

Hi,

I have a situation where I would like to update CEF (using 4103 / 83.0.4103.97) within an existing message pump so I'm using CefDoMessageLoopWork for this. However, I'm having trouble shutting down CEF properly.

I need to explicitely close the browser before calling CefShutdown, otherwise I'm getting an assertion and a crash when calling CefShutdown in:

Code: Select all
    libcef.dll!logging::LogMessage::~LogMessage() Line 953   C++
    libcef.dll!cef_log(const char * file, int line, int severity, const char * message) Line 335   C++
    [External Code]   
>   libcef.dll!CefAudioHandlerCToCpp::OnAudioStreamStopped(scoped_refptr<CefBrowser> browser) Line 113   C++
    libcef.dll!CefBrowserHostImpl::DestroyBrowser() Line 1535   C++
    libcef.dll!CefBrowserInfoManager::DestroyAllBrowsers() Line 352   C++
    libcef.dll!CefContext::FinishShutdownOnUIThread(base::WaitableEvent * uithread_shutdown_event) Line 680   C++
    libcef.dll!CefContext::Shutdown() Line 567   C++
    libcef.dll!CefShutdown() Line 351   C++


with the log message "[FATAL:shutdown_checker.cc(52)] Check failed: !IsCefShutdown(). Object reference incorrectly held at CefShutdown"

So I'm closing the browser like this:

Code: Select all
browser->GetHost()->CloseBrowser(true)


I also need to wait for this operation to complete or the assertion will still be false. Currently I'm waiting for the callback CefLifeSpanHandler::OnBeforeClose where I'm clearing my browser variable. However, I also need to keep updating CEF while doing so:

Code: Select all
WINASSERT(CefCurrentlyOn(TID_UI));
if (browser != nullptr)
{
   browser->GetHost()->CloseBrowser(true);
}

for (int attempts = 0; browser != nullptr && attempts < 1000; ++attempts)
{
   Sleep(1);
   CefDoMessageLoopWork();
}


Clearly this isn't a good solution, but this is the most responsive shutdown I could achieve so far.


Can anyone point me into a better direction? Can I avoid closing the browser without tripping that shutdown assertion or is there a better way to close it?

Thanks.
Biohazard
Newbie
 
Posts: 9
Joined: Mon Jun 15, 2020 10:01 am

Re: Hacky CEF shutdown needed when using CefDoMessageLoopWor

Postby magreenblatt » Mon Jun 22, 2020 4:51 pm

At what point are you terminating the app message loop which was previously calling CefDoMessageLoopWork? Have you considered using multi-threaded message loop instead?
magreenblatt
Site Admin
 
Posts: 10184
Joined: Fri May 29, 2009 6:57 pm

Re: Hacky CEF shutdown needed when using CefDoMessageLoopWor

Postby Biohazard » Mon Jun 22, 2020 5:59 pm

The message loop has been terminated at that point already but I think I see what I'm doing wrong now, I would simply have to keep my message loop running until OnBeforeClose is done to solve this, thanks!

I wanted to avoid a multi-threaded message loop so I wouldn't need to additionally worry about synchronization. Ideally I would just use CefRunMessageLoop like I'm doing elsewhere, but I would first need to make changes to Chromium that would allow me to control the scheduling/animation delay (I'm currently ignoring the requested delay for CefDoMessageLoopWork because my own desired delay is expected to be higher). But since Chromium is so complex I didn't want to even look into that yet so that's for another time.
Biohazard
Newbie
 
Posts: 9
Joined: Mon Jun 15, 2020 10:01 am

Re: Hacky CEF shutdown needed when using CefDoMessageLoopWor

Postby magreenblatt » Mon Jun 22, 2020 7:10 pm

Intentionally slowing down CefDoMessageLoopWork will impact many things beyond animation, and I would not recommend it.
magreenblatt
Site Admin
 
Posts: 10184
Joined: Fri May 29, 2009 6:57 pm

Re: Hacky CEF shutdown needed when using CefDoMessageLoopWor

Postby Biohazard » Tue Jun 23, 2020 4:47 am

Thanks for the heads-up! Yes, I know that it's far from ideal, but right now this is better for my use-case than not delaying anything. I haven't run into any show stoppers yet.

Ideally I would want to delay (or even pause) setTimeout, window.nextAnimationFrame and painting/layout/whatever else Chromium may do during a regular update to be limited to a given FPS which may also change at runtime. Delaying CefDoMessageLoopWork is not the right approach to this (i.e. window.nextAnimationFrame is completely unaffected and it may have a lot of side effects) but I believe if I want to do this the right way this will turn into a major task of modifying Chromium.
Biohazard
Newbie
 
Posts: 9
Joined: Mon Jun 15, 2020 10:01 am

Re: Hacky CEF shutdown needed when using CefDoMessageLoopWor

Postby amaitland » Tue Jun 23, 2020 5:08 am

Maybe _cef_window_info_t.external_begin_frame_enabled is worth checking out, you can call CefBrowserHost::SendExternalBeginFrame at the desired frame rate (long as your not using offscreen rendering)
Maintainer of the CefSharp project.
amaitland
Master
 
Posts: 745
Joined: Wed Jan 14, 2015 2:35 am

Re: Hacky CEF shutdown needed when using CefDoMessageLoopWor

Postby magreenblatt » Tue Jun 23, 2020 11:26 am

I see it's not clear from the docs, but external_begin_frame_enabled and SendExternalBeginFrame are only supported with off-screen rendering.
magreenblatt
Site Admin
 
Posts: 10184
Joined: Fri May 29, 2009 6:57 pm

Re: Hacky CEF shutdown needed when using CefDoMessageLoopWor

Postby Biohazard » Tue Jun 23, 2020 12:14 pm

amaitland wrote:Maybe _cef_window_info_t.external_begin_frame_enabled is worth checking out, you can call CefBrowserHost::SendExternalBeginFrame at the desired frame rate (long as your not using offscreen rendering)


Thanks for the tip! Like magreenblatt said it seems to be OSR specific and making a small modification to enable it without OSR anyway in CefBrowserPlatformDelegate::Create isn't enough to get the expected result. I'm just assuming but making this change is probably a lot more involved because I would need to bring a bunch of OSR specific code into the normal platform delegate or something.

But anyway, this might be a good point to start at in the future.
Biohazard
Newbie
 
Posts: 9
Joined: Mon Jun 15, 2020 10:01 am

Re: Hacky CEF shutdown needed when using CefDoMessageLoopWor

Postby magreenblatt » Tue Jun 23, 2020 1:18 pm

Biohazard wrote:Thanks for the tip! Like magreenblatt said it seems to be OSR specific and making a small modification to enable it without OSR anyway in CefBrowserPlatformDelegate::Create isn't enough to get the expected result. I'm just assuming but making this change is probably a lot more involved because I would need to bring a bunch of OSR specific code into the normal platform delegate or something.

But anyway, this might be a good point to start at in the future.

It's probably the right idea for a "proper" solution, but it will involve Chromium changes. Currently, begin-frame events are generated based on vsync timing.
magreenblatt
Site Admin
 
Posts: 10184
Joined: Fri May 29, 2009 6:57 pm

Re: Hacky CEF shutdown needed when using CefDoMessageLoopWor

Postby amaitland » Tue Jun 23, 2020 4:30 pm

amaitland wrote:Maybe _cef_window_info_t.external_begin_frame_enabled is worth checking out, you can call CefBrowserHost::SendExternalBeginFrame at the desired frame rate (long as your not using offscreen rendering)


My mistake, documentation should probably be updated.

I was going to use it with OSR until I saw https://bitbucket.org/chromiumembedded/ ... s-not-call so assumed it was only working with windowed rendering.
Maintainer of the CefSharp project.
amaitland
Master
 
Posts: 745
Joined: Wed Jan 14, 2015 2:35 am

Next

Return to Support Forum

Who is online

Users browsing this forum: No registered users and 35 guests