From 5548186fc0bde1c04497fb7b4e39ed9971e8d830 Mon Sep 17 00:00:00 2001 From: "grt@chromium.org" Date: Sat, 17 Dec 2011 03:37:55 +0000 Subject: Fix Chrome Frame crash when automation server dies. GCF was crashing if the automation server dies while there are outstanding sub-resource requests being serviced on the new bg thread. The reason was that AutomationServerDied posts a task to InitializeComplete(AUTOMATION_SERVER_CRASHED) and then a task to Uninitialize(). The former will call ReleaseAutomationServer() without first joining on the bg resource thread. The fix is to wait and release the server in Uninitialize. BUG=107811 TEST=Prior to fix, the following would usually trigger the crash: chrome_frame_tests.exe --gtest_repeat=20 --gtest_filter=CF/FullTabUITest.TabCrashReload/0 Review URL: http://codereview.chromium.org/8965031 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114906 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome_frame/chrome_frame_automation.cc | 6 +++--- chrome_frame/chrome_frame_automation.h | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'chrome_frame') diff --git a/chrome_frame/chrome_frame_automation.cc b/chrome_frame/chrome_frame_automation.cc index 81740e6..2aae122 100644 --- a/chrome_frame/chrome_frame_automation.cc +++ b/chrome_frame/chrome_frame_automation.cc @@ -623,7 +623,7 @@ void ChromeFrameAutomationClient::Uninitialize() { tab_ = NULL; // scoped_refptr::Release } - // Wait for the background thread to exit. + // Wait for the automation proxy's worker thread to exit. ReleaseAutomationServer(); // We must destroy the window, since if there are pending tasks @@ -846,7 +846,7 @@ AutomationLaunchResult ChromeFrameAutomationClient::CreateExternalTabComplete( return launch_result; } -// Invoked in launch background thread. +// Invoked in the automation proxy's worker thread. void ChromeFrameAutomationClient::LaunchComplete( ChromeFrameAutomationProxy* proxy, AutomationLaunchResult result) { @@ -889,6 +889,7 @@ void ChromeFrameAutomationClient::LaunchComplete( } } +// Invoked in the automation proxy's worker thread. void ChromeFrameAutomationClient::AutomationServerDied() { // Make sure we notify our delegate. PostTask( @@ -905,7 +906,6 @@ void ChromeFrameAutomationClient::InitializeComplete( DCHECK_EQ(base::PlatformThread::CurrentId(), ui_thread_id_); if (result != AUTOMATION_SUCCESS) { DLOG(WARNING) << "InitializeComplete: failure " << result; - ReleaseAutomationServer(); } else { init_state_ = INITIALIZED; diff --git a/chrome_frame/chrome_frame_automation.h b/chrome_frame/chrome_frame_automation.h index 83a3e0b..b1cef96 100644 --- a/chrome_frame/chrome_frame_automation.h +++ b/chrome_frame/chrome_frame_automation.h @@ -208,7 +208,8 @@ class ChromeFrameLaunchParams : // NOLINT }; // Callback when chrome process launch is complete and automation handshake -// (Hello message) is established. +// (Hello message) is established. All methods are invoked on the automation +// proxy's worker thread. struct DECLSPEC_NOVTABLE LaunchDelegate { // NOLINT virtual void LaunchComplete(ChromeFrameAutomationProxy* proxy, AutomationLaunchResult result) = 0; -- cgit v1.1