- When running in multi-threaded message loop mode wait for the UI thread to exit before returning from CefContext::Shutdown() (issue #263).

- Fix crash in IME handling when closing the application while content is still loading.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@258 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2011-06-14 17:10:15 +00:00
parent 5c2824a422
commit 0d893166d3
3 changed files with 46 additions and 14 deletions

View File

@ -129,6 +129,21 @@ void IOT_VisitUrlCookies(const GURL& url, bool includeHttpOnly,
IOT_VisitCookies(cookie_monster, list, visitor); IOT_VisitCookies(cookie_monster, list, visitor);
} }
// Used in multi-threaded message loop mode to observe shutdown of the UI
// thread.
class DestructionObserver : public MessageLoop::DestructionObserver
{
public:
DestructionObserver(base::WaitableEvent *event) : event_(event) {}
virtual void WillDestroyCurrentMessageLoop() {
MessageLoop::current()->RemoveDestructionObserver(this);
event_->Signal();
delete this;
}
private:
base::WaitableEvent *event_;
};
} // anonymous } // anonymous
bool CefInitialize(const CefSettings& settings) bool CefInitialize(const CefSettings& settings)
@ -475,23 +490,31 @@ void CefContext::Shutdown()
shutting_down_ = true; shutting_down_ = true;
if(settings_.multi_threaded_message_loop) { if(settings_.multi_threaded_message_loop) {
// Event that will be used to signal when shutdown is complete. Start in // Events that will be used to signal when shutdown is complete. Start in
// non-signaled mode so that the event will block. // non-signaled mode so that the event will block.
base::WaitableEvent event(false, false); base::WaitableEvent browser_shutdown_event(false, false);
base::WaitableEvent uithread_shutdown_event(false, false);
// Finish shutdown on the UI thread. // Finish shutdown on the UI thread.
CefThread::PostTask(CefThread::UI, FROM_HERE, CefThread::PostTask(CefThread::UI, FROM_HERE,
NewRunnableMethod(this, &CefContext::UIT_FinishShutdown, &event)); NewRunnableMethod(this, &CefContext::UIT_FinishShutdown,
&browser_shutdown_event, &uithread_shutdown_event));
// Block until shutdown is complete. // Block until browser shutdown is complete.
event.Wait(); browser_shutdown_event.Wait();
} else {
// Finish shutdown on the current thread, which should be the UI thread.
UIT_FinishShutdown(NULL);
}
// Delete the process to destroy the child threads. // Delete the process to destroy the child threads.
process_ = NULL; process_ = NULL;
// Block until UI thread shutdown is complete.
uithread_shutdown_event.Wait();
} else {
// Finish shutdown on the current thread, which should be the UI thread.
UIT_FinishShutdown(NULL, NULL);
// Delete the process to destroy the child threads.
process_ = NULL;
}
} }
bool CefContext::AddBrowser(CefRefPtr<CefBrowserImpl> browser) bool CefContext::AddBrowser(CefRefPtr<CefBrowserImpl> browser)
@ -562,7 +585,8 @@ CefRefPtr<CefBrowserImpl> CefContext::GetBrowserByID(int id)
return NULL; return NULL;
} }
void CefContext::UIT_FinishShutdown(base::WaitableEvent* event) void CefContext::UIT_FinishShutdown(base::WaitableEvent* browser_shutdown_event,
base::WaitableEvent* uithread_shutdown_event)
{ {
DCHECK(CefThread::CurrentlyOn(CefThread::UI)); DCHECK(CefThread::CurrentlyOn(CefThread::UI));
@ -583,6 +607,13 @@ void CefContext::UIT_FinishShutdown(base::WaitableEvent* event)
(*it)->UIT_DestroyBrowser(); (*it)->UIT_DestroyBrowser();
} }
if(event) if (uithread_shutdown_event) {
event->Signal(); // The destruction observer will signal the UI thread shutdown event when
// the UI thread has been destroyed.
MessageLoop::current()->AddDestructionObserver(
new DestructionObserver(uithread_shutdown_event));
// Signal the browser shutdown event now.
browser_shutdown_event->Signal();
}
} }

View File

@ -75,7 +75,8 @@ public:
private: private:
// Performs shutdown actions that need to occur on the UI thread before any // Performs shutdown actions that need to occur on the UI thread before any
// threads are destroyed. // threads are destroyed.
void UIT_FinishShutdown(base::WaitableEvent* event); void UIT_FinishShutdown(base::WaitableEvent* browser_shutdown_event,
base::WaitableEvent* uithread_shutdown_event);
// Track context state. // Track context state.
bool initialized_; bool initialized_;

View File

@ -1040,7 +1040,7 @@ void WebWidgetHost::UpdateInputMethod(HWND view)
WebWidgetHost* host = FromWindow(view); WebWidgetHost* host = FromWindow(view);
if (!host->input_method_is_active_) if (!host || !host->input_method_is_active_)
return; return;
if (!host->webwidget_ || !CefThread::CurrentlyOn(CefThread::UI)) if (!host->webwidget_ || !CefThread::CurrentlyOn(CefThread::UI))