Skip to content

Commit f2089f2

Browse files
committed
fix: ensure CefViewBrowserClient::CloseAllBrowsers logic is always executed in CEF UI thread
1 parent afedf01 commit f2089f2

File tree

4 files changed

+67
-19
lines changed

4 files changed

+67
-19
lines changed

include/CefViewCoreGlobal.h

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
#pragma region cef_headers
1818
#include <include/cef_app.h>
1919
#include <include/cef_client.h>
20-
#include <include/cef_version.h>
2120
#include <include/cef_parser.h>
21+
#include <include/cef_task.h>
22+
#include <include/cef_version.h>
2223
#include <include/wrapper/cef_helpers.h>
2324
#include <include/wrapper/cef_message_router.h>
2425
#include <include/wrapper/cef_resource_manager.h>
@@ -41,4 +42,36 @@ struct std::hash<CefFrameId>
4142
};
4243
#endif // CEF_VERSION_MAJOR < 122
4344

45+
/// <summary>
46+
/// Task for rendering operations.
47+
/// </summary>
48+
class CefLambdaTask : public CefTask
49+
{
50+
IMPLEMENT_REFCOUNTING(CefLambdaTask);
51+
52+
/// <summary>
53+
/// Function that contains the lambda work to be executed.
54+
/// </summary>
55+
std::function<void()> work;
56+
57+
public:
58+
/// <summary>
59+
/// Constructor for the task.
60+
/// </summary>
61+
CefLambdaTask(std::function<void()>&& t)
62+
: work(std::move(t))
63+
{
64+
}
65+
66+
/// <summary>
67+
/// Executes the task.
68+
/// </summary>
69+
void Execute() override
70+
{
71+
if (work) {
72+
work();
73+
}
74+
}
75+
};
76+
4477
#endif // CefViewCoreGlobal_h

src/CefView/CefBrowserApp/CefViewBrowserClient.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,26 @@ CefViewBrowserClient::~CefViewBrowserClient()
5050
void
5151
CefViewBrowserClient::CloseAllBrowsers()
5252
{
53-
close_by_native_ = true;
54-
auto browsers = browser_map_;
55-
for (auto& kv : browsers) {
56-
kv.second->StopLoad();
57-
kv.second->GetHost()->CloseBrowser(true);
53+
CefRefPtr<CefViewBrowserClient> self = this;
54+
auto closeTask = [self]() {
55+
// set flags
56+
self->is_closing_ = true;
57+
self->close_by_native_ = true;
58+
59+
// close all browser in current client instance
60+
auto browserMap = self->browser_map_;
61+
for (auto& kv : browserMap) {
62+
if (kv.second) {
63+
kv.second->StopLoad();
64+
kv.second->GetHost()->CloseBrowser(true);
65+
}
66+
}
67+
};
68+
69+
if (CefCurrentlyOn(TID_UI)) {
70+
closeTask();
71+
} else {
72+
CefPostTask(TID_UI, new CefLambdaTask(std::move(closeTask)));
5873
}
5974
}
6075

src/CefView/CefBrowserApp/CefViewBrowserClient_LifeSpanHandler.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ CefViewBrowserClient::OnBeforePopup(CefRefPtr<CefBrowser> browser,
4141

4242
bool result = false;
4343

44-
auto delegate = client_delegate_.lock();
45-
if (delegate) {
44+
if (auto delegate = client_delegate_.lock()) {
4645
bool disableJSAccess = no_javascript_access ? *no_javascript_access : false;
4746
result = delegate->onBeforePopup(browser,
4847
frame,
@@ -78,9 +77,9 @@ CefViewBrowserClient::OnAfterCreated(CefRefPtr<CefBrowser> browser)
7877
message_router_->AddHandler(message_router_handler_.get(), false);
7978
}
8079

81-
auto delegate = client_delegate_.lock();
82-
if (delegate)
80+
if (auto delegate = client_delegate_.lock()) {
8381
delegate->onAfterCreate(browser);
82+
}
8483

8584
browser_map_[browser->GetIdentifier()] = browser;
8685
}
@@ -90,14 +89,14 @@ CefViewBrowserClient::DoClose(CefRefPtr<CefBrowser> browser)
9089
{
9190
CEF_REQUIRE_UI_THREAD();
9291

93-
bool ignoreClose = false;
94-
9592
if (browser->IsPopup()) {
96-
return ignoreClose;
93+
// return false for pop-up browser
94+
return false;
9795
}
9896

99-
auto delegate = client_delegate_.lock();
100-
if (delegate) {
97+
bool ignoreClose = false;
98+
99+
if (auto delegate = client_delegate_.lock()) {
101100
if (close_by_native_) {
102101
// close by native
103102
ignoreClose = delegate->doClose(browser);
@@ -119,9 +118,9 @@ CefViewBrowserClient::OnBeforeClose(CefRefPtr<CefBrowser> browser)
119118
{
120119
CEF_REQUIRE_UI_THREAD();
121120

122-
auto delegate = client_delegate_.lock();
123-
if (delegate)
121+
if (auto delegate = client_delegate_.lock()) {
124122
delegate->onBeforeClose(browser);
123+
}
125124

126125
message_router_->OnBeforeClose(browser);
127126

src/CefView/CefBrowserApp/CefViewBrowserClient_LoadHandler.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,10 @@ CefViewBrowserClient::OnLoadError(CefRefPtr<CefBrowser> browser,
7373
if (errorCode == ERR_ABORTED)
7474
return;
7575

76-
// If the browser is closing, block the popup
77-
if (is_closing_)
76+
// If the browser is closing, block the pop-up
77+
if (is_closing_) {
7878
return;
79+
}
7980

8081
auto msg = errorText.ToString();
8182
auto url = failedUrl.ToString();

0 commit comments

Comments
 (0)