Fix crashes/assertions when CefBrowserImpl is destroyed on a non-UI thread (issue #694).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@736 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt
2012-08-13 16:24:53 +00:00
parent 26a2281486
commit 6ab23a802f
5 changed files with 30 additions and 19 deletions

View File

@@ -771,6 +771,9 @@ void CefBrowserImpl::UIT_DestroyBrowser() {
dev_tools_agent_.reset(); dev_tools_agent_.reset();
} }
if (frame_objects_.size() > 0)
frame_objects_.clear();
// Clean up anything associated with the WebViewHost widget. // Clean up anything associated with the WebViewHost widget.
if (webviewhost_.get()) { if (webviewhost_.get()) {
if (webviewhost_->webwidget()) if (webviewhost_->webwidget())
@@ -778,6 +781,13 @@ void CefBrowserImpl::UIT_DestroyBrowser() {
webviewhost_.reset(); webviewhost_.reset();
} }
delegate_.reset(NULL);
popup_delegate_.reset(NULL);
nav_controller_.reset(NULL);
if (paint_delegate_.get())
paint_delegate_.reset(NULL);
// Remove the reference to the window handle. // Remove the reference to the window handle.
UIT_ClearMainWndHandle(); UIT_ClearMainWndHandle();
@@ -789,11 +799,11 @@ void CefBrowserImpl::UIT_DestroyBrowser() {
request_context_proxy_.release()); request_context_proxy_.release());
} }
// Remove the reference added in UIT_CreateBrowser().
Release();
// Remove the browser from the list maintained by the context. // Remove the browser from the list maintained by the context.
_Context->RemoveBrowser(this); _Context->RemoveBrowser(this);
// Remove the reference added in UIT_CreateBrowser().
Release();
} }
void CefBrowserImpl::UIT_CloseBrowser() { void CefBrowserImpl::UIT_CloseBrowser() {

View File

@@ -111,7 +111,8 @@ BrowserNavigationEntry* BrowserNavigationController::GetLastCommittedEntry()
const { const {
if (last_committed_entry_index_ == -1) if (last_committed_entry_index_ == -1)
return NULL; return NULL;
return entries_[last_committed_entry_index_].get(); return const_cast<BrowserNavigationEntry*>(
entries_[last_committed_entry_index_]);
} }
BrowserNavigationEntry* BrowserNavigationController::GetActiveEntry() const { BrowserNavigationEntry* BrowserNavigationController::GetActiveEntry() const {
@@ -133,13 +134,14 @@ BrowserNavigationEntry* BrowserNavigationController::GetEntryAtIndex(
if (index < 0 || index >= GetEntryCount()) if (index < 0 || index >= GetEntryCount())
return NULL; return NULL;
return entries_[index].get(); return const_cast<BrowserNavigationEntry*>(entries_[index]);
} }
BrowserNavigationEntry* BrowserNavigationController::GetEntryWithPageID( BrowserNavigationEntry* BrowserNavigationController::GetEntryWithPageID(
int32 page_id) const { int32 page_id) const {
int index = GetEntryIndexWithPageID(page_id); int index = GetEntryIndexWithPageID(page_id);
return (index != -1) ? entries_[index].get() : NULL; return (index != -1) ?
const_cast<BrowserNavigationEntry*>(entries_[index]) : NULL;
} }
void BrowserNavigationController::DidNavigateToEntry( void BrowserNavigationController::DidNavigateToEntry(
@@ -158,7 +160,7 @@ void BrowserNavigationController::DidNavigateToEntry(
int existing_entry_index = GetEntryIndexWithPageID(entry->GetPageID()); int existing_entry_index = GetEntryIndexWithPageID(entry->GetPageID());
BrowserNavigationEntry* existing_entry = (existing_entry_index != -1) ? BrowserNavigationEntry* existing_entry = (existing_entry_index != -1) ?
entries_[existing_entry_index].get() : NULL; entries_[existing_entry_index] : NULL;
if (!existing_entry) { if (!existing_entry) {
// No existing entry, then simply ignore this navigation! // No existing entry, then simply ignore this navigation!
DLOG(WARNING) << "ignoring navigation for page: " << entry->GetPageID(); DLOG(WARNING) << "ignoring navigation for page: " << entry->GetPageID();
@@ -191,7 +193,7 @@ void BrowserNavigationController::DidNavigateToEntry(
} }
void BrowserNavigationController::DiscardPendingEntry() { void BrowserNavigationController::DiscardPendingEntry() {
if (pending_entry_index_ == -1) if (pending_entry_index_ == -1 && pending_entry_)
delete pending_entry_; delete pending_entry_;
pending_entry_ = NULL; pending_entry_ = NULL;
pending_entry_index_ = -1; pending_entry_index_ = -1;
@@ -210,13 +212,13 @@ void BrowserNavigationController::InsertEntry(BrowserNavigationEntry* entry) {
int current_size = static_cast<int>(entries_.size()); int current_size = static_cast<int>(entries_.size());
if (current_size > 0) { if (current_size > 0) {
while (last_committed_entry_index_ < (current_size - 1)) { while (last_committed_entry_index_ < (current_size - 1)) {
entries_.pop_back(); entries_.erase(entries_.end() - 1);
current_size--; current_size--;
} }
} }
} }
entries_.push_back(linked_ptr<BrowserNavigationEntry>(entry)); entries_.push_back(entry);
last_committed_entry_index_ = static_cast<int>(entries_.size()) - 1; last_committed_entry_index_ = static_cast<int>(entries_.size()) - 1;
UpdateMaxPageID(); UpdateMaxPageID();
} }
@@ -234,7 +236,7 @@ void BrowserNavigationController::NavigateToPendingEntry(bool reload,
// For session history navigations only the pending_entry_index_ is set. // For session history navigations only the pending_entry_index_ is set.
if (!pending_entry_) { if (!pending_entry_) {
DCHECK_NE(pending_entry_index_, -1); DCHECK_NE(pending_entry_index_, -1);
pending_entry_ = entries_[pending_entry_index_].get(); pending_entry_ = entries_[pending_entry_index_];
} }
if (browser_->UIT_Navigate(*pending_entry_, reload, ignoreCache)) { if (browser_->UIT_Navigate(*pending_entry_, reload, ignoreCache)) {

View File

@@ -11,8 +11,8 @@
#include <vector> #include <vector>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
#include "googleurl/src/gurl.h" #include "googleurl/src/gurl.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebHTTPBody.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebHTTPBody.h"
@@ -187,8 +187,7 @@ class BrowserNavigationController {
void UpdateMaxPageID(); void UpdateMaxPageID();
// List of NavigationEntry for this tab // List of NavigationEntry for this tab
typedef std::vector< linked_ptr<BrowserNavigationEntry> > NavigationEntryList; typedef ScopedVector<BrowserNavigationEntry> NavigationEntryList;
typedef NavigationEntryList::iterator NavigationEntryListIterator;
NavigationEntryList entries_; NavigationEntryList entries_;
// An entry we haven't gotten a response for yet. This will be discarded // An entry we haven't gotten a response for yet. This will be discarded
@@ -210,4 +209,3 @@ class BrowserNavigationController {
}; };
#endif // CEF_LIBCEF_BROWSER_NAVIGATION_CONTROLLER_H_ #endif // CEF_LIBCEF_BROWSER_NAVIGATION_CONTROLLER_H_

View File

@@ -1263,8 +1263,8 @@ void BrowserWebViewDelegate::UpdateSessionHistory(WebFrame* frame) {
if (page_id_ == -1) if (page_id_ == -1)
return; return;
BrowserNavigationEntry* entry = static_cast<BrowserNavigationEntry*>( BrowserNavigationEntry* entry =
browser_->UIT_GetNavigationController()->GetEntryWithPageID(page_id_)); browser_->UIT_GetNavigationController()->GetEntryWithPageID(page_id_);
if (!entry) if (!entry)
return; return;

View File

@@ -11,6 +11,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/string_util.h" #include "base/string_util.h"
#include "base/threading/non_thread_safe.h"
#include "base/utf_string_conversions.h" #include "base/utf_string_conversions.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMEvent.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMEvent.h"
@@ -38,7 +39,8 @@ namespace {
// Wrapper implementation for WebDOMEventListener. // Wrapper implementation for WebDOMEventListener.
class CefDOMEventListenerWrapper : public WebDOMEventListener, class CefDOMEventListenerWrapper : public WebDOMEventListener,
public CefTrackNode { public CefTrackNode,
public base::NonThreadSafe {
public: public:
CefDOMEventListenerWrapper(CefBrowserImpl* browser, WebFrame* frame, CefDOMEventListenerWrapper(CefBrowserImpl* browser, WebFrame* frame,
CefRefPtr<CefDOMEventListener> listener) CefRefPtr<CefDOMEventListener> listener)
@@ -49,7 +51,6 @@ class CefDOMEventListenerWrapper : public WebDOMEventListener,
browser->UIT_AddFrameObject(frame, this); browser->UIT_AddFrameObject(frame, this);
} }
virtual ~CefDOMEventListenerWrapper() { virtual ~CefDOMEventListenerWrapper() {
REQUIRE_UIT();
} }
virtual void handleEvent(const WebDOMEvent& event) { virtual void handleEvent(const WebDOMEvent& event) {