mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-03-29 10:20:11 +01:00
Don't use NotificationStateLock for GetMainFrame (see issue #2421)
This causes a race related to |notification_state_lock_| assignment when GetMainFrame is called from multiple threads. GetMainFrame doesn't trigger any notifications so it shouldn't need that lock. Instead, only use NotificationStateLock on the UI thread.
This commit is contained in:
parent
db807e804a
commit
84117f2d1b
@ -234,7 +234,7 @@ void CefBrowserInfo::RemoveFrame(content::RenderFrameHost* host) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CefRefPtr<CefFrameHostImpl> CefBrowserInfo::GetMainFrame() {
|
CefRefPtr<CefFrameHostImpl> CefBrowserInfo::GetMainFrame() {
|
||||||
NotificationStateLock lock_scope(this);
|
base::AutoLock lock_scope(lock_);
|
||||||
// Early exit if called post-destruction.
|
// Early exit if called post-destruction.
|
||||||
if (!browser_ || is_closing_)
|
if (!browser_ || is_closing_)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -504,6 +504,8 @@ void CefBrowserInfo::RemoveAllFrames(
|
|||||||
CefBrowserInfo::NotificationStateLock::NotificationStateLock(
|
CefBrowserInfo::NotificationStateLock::NotificationStateLock(
|
||||||
CefBrowserInfo* browser_info)
|
CefBrowserInfo* browser_info)
|
||||||
: browser_info_(browser_info) {
|
: browser_info_(browser_info) {
|
||||||
|
CEF_REQUIRE_UIT();
|
||||||
|
|
||||||
// Take the navigation state lock.
|
// Take the navigation state lock.
|
||||||
{
|
{
|
||||||
base::AutoLock lock_scope_(browser_info_->notification_lock_);
|
base::AutoLock lock_scope_(browser_info_->notification_lock_);
|
||||||
@ -518,6 +520,8 @@ CefBrowserInfo::NotificationStateLock::NotificationStateLock(
|
|||||||
}
|
}
|
||||||
|
|
||||||
CefBrowserInfo::NotificationStateLock::~NotificationStateLock() {
|
CefBrowserInfo::NotificationStateLock::~NotificationStateLock() {
|
||||||
|
CEF_REQUIRE_UIT();
|
||||||
|
|
||||||
// Unlock in reverse order.
|
// Unlock in reverse order.
|
||||||
browser_info_lock_scope_.reset();
|
browser_info_lock_scope_.reset();
|
||||||
|
|
||||||
@ -530,11 +534,8 @@ CefBrowserInfo::NotificationStateLock::~NotificationStateLock() {
|
|||||||
if (!queue_.empty()) {
|
if (!queue_.empty()) {
|
||||||
DCHECK(frame_handler_);
|
DCHECK(frame_handler_);
|
||||||
|
|
||||||
scoped_refptr<NavigationLock> nav_lock;
|
// Don't navigate while inside callbacks.
|
||||||
if (CEF_CURRENTLY_ON_UIT()) {
|
auto nav_lock = browser_info_->CreateNavigationLock();
|
||||||
// Don't navigate while inside callbacks.
|
|
||||||
nav_lock = browser_info_->CreateNavigationLock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Empty the queue of pending actions. Any of these actions might result in
|
// Empty the queue of pending actions. Any of these actions might result in
|
||||||
// the acquisition of a new NotificationStateLock.
|
// the acquisition of a new NotificationStateLock.
|
||||||
|
@ -204,7 +204,7 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
|
|||||||
// Used instead of |base::AutoLock(lock_)| in situations that might generate
|
// Used instead of |base::AutoLock(lock_)| in situations that might generate
|
||||||
// CefFrameHandler notifications. Any notifications passed to
|
// CefFrameHandler notifications. Any notifications passed to
|
||||||
// MaybeExecuteFrameNotification() will be queued until the lock is released,
|
// MaybeExecuteFrameNotification() will be queued until the lock is released,
|
||||||
// and then executed in order.
|
// and then executed in order. Only accessed on the UI thread.
|
||||||
class NotificationStateLock final {
|
class NotificationStateLock final {
|
||||||
public:
|
public:
|
||||||
explicit NotificationStateLock(CefBrowserInfo* browser_info);
|
explicit NotificationStateLock(CefBrowserInfo* browser_info);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user