diff options
-rw-r--r-- | base/scoped_nsautorelease_pool.h | 6 | ||||
-rw-r--r-- | base/scoped_nsautorelease_pool.mm | 11 | ||||
-rw-r--r-- | chrome/app/chrome_dll_main.cc | 12 | ||||
-rw-r--r-- | chrome/browser/app_controller_mac.mm | 21 | ||||
-rw-r--r-- | chrome/browser/browser_main.cc | 7 | ||||
-rw-r--r-- | chrome/browser/browser_window_cocoa.mm | 1 | ||||
-rw-r--r-- | chrome/common/main_function_params.h | 10 | ||||
-rw-r--r-- | chrome/renderer/renderer_main.cc | 3 | ||||
-rw-r--r-- | chrome/renderer/renderer_main_unittest.cc | 3 | ||||
-rw-r--r-- | chrome/test/in_process_browser_test.cc | 2 |
10 files changed, 57 insertions, 19 deletions
diff --git a/base/scoped_nsautorelease_pool.h b/base/scoped_nsautorelease_pool.h index 0e779af..64bf9e7 100644 --- a/base/scoped_nsautorelease_pool.h +++ b/base/scoped_nsautorelease_pool.h @@ -29,10 +29,16 @@ class ScopedNSAutoreleasePool { public: #if !defined(OS_MACOSX) ScopedNSAutoreleasePool() {} + void Recycle() { } #else // OS_MACOSX ScopedNSAutoreleasePool(); ~ScopedNSAutoreleasePool(); + // Clear out the pool in case its position on the stack causes it to be + // alive for long periods of time (such as the entire length of the app). + // Only use then when you're certain the items currently in the pool are + // no longer needed. + void Recycle(); private: NSAutoreleasePool* autorelease_pool_; #endif // OS_MACOSX diff --git a/base/scoped_nsautorelease_pool.mm b/base/scoped_nsautorelease_pool.mm index c4ae517..174fb82 100644 --- a/base/scoped_nsautorelease_pool.mm +++ b/base/scoped_nsautorelease_pool.mm @@ -6,14 +6,25 @@ #import <Foundation/Foundation.h> +#include "base/logging.h" + namespace base { ScopedNSAutoreleasePool::ScopedNSAutoreleasePool() : autorelease_pool_([[NSAutoreleasePool alloc] init]) { + DCHECK(autorelease_pool_); } ScopedNSAutoreleasePool::~ScopedNSAutoreleasePool() { [autorelease_pool_ drain]; } +// Cycle the internal pool, allowing everything there to get cleaned up and +// start anew. +void ScopedNSAutoreleasePool::Recycle() { + [autorelease_pool_ drain]; + autorelease_pool_ = [[NSAutoreleasePool alloc] init]; + DCHECK(autorelease_pool_); +} + } // namespace base diff --git a/chrome/app/chrome_dll_main.cc b/chrome/app/chrome_dll_main.cc index ebde279..f14b886 100644 --- a/chrome/app/chrome_dll_main.cc +++ b/chrome/app/chrome_dll_main.cc @@ -200,11 +200,10 @@ int ChromeMain(int argc, const char** argv) { // The exit manager is in charge of calling the dtors of singleton objects. base::AtExitManager exit_manager; - // TODO(pinkerton): We need this pool here for all the objects created - // before we get to the UI event loop, but we don't want to leave them - // hanging around until the app quits. We should add a "flush" to the class - // which just cycles the pool under the covers and then call that just - // before we invoke the main UI loop near the bottom of this function. + // We need this pool for all the objects created before we get to the + // event loop, but we don't want to leave them hanging around until the + // app quits. Each "main" needs to flush this pool right before it goes into + // its main event loop to get rid of the cruft. base::ScopedNSAutoreleasePool autorelease_pool; #if defined(OS_LINUX) @@ -307,7 +306,8 @@ int ChromeMain(int argc, const char** argv) { startup_timer.Stop(); // End of Startup Time Measurement. - MainFunctionParams main_params(parsed_command_line, sandbox_wrapper); + MainFunctionParams main_params(parsed_command_line, sandbox_wrapper, + &autorelease_pool); // TODO(port): turn on these main() functions as they've been de-winified. int rv = -1; diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm index 3895ece..5a9609a 100644 --- a/chrome/browser/app_controller_mac.mm +++ b/chrome/browser/app_controller_mac.mm @@ -19,10 +19,18 @@ @implementation AppController - (void)awakeFromNib { - // set up the command updater for when there are no windows open + // Set up the command updater for when there are no windows open [self initMenuState]; } +- (void)applicationDidFinishLaunching:(NSNotification*)notify { + // Hold an extra ref to the BrowserProcess singleton so it doesn't go away + // when all the browser windows get closed. We'll release it on quit which + // will be the signal to exit. + DCHECK(g_browser_process); + g_browser_process->AddRefModule(); +} + - (void)dealloc { delete menuState_; [super dealloc]; @@ -41,14 +49,11 @@ // go back to normal. // Close all the windows. - // TODO(pinkerton): the close code assumes that teardown happens - // synchronously, however with autorelease pools and ref-counting, we can't - // guarantee the window controller hits 0 inside this call, and thus the - // number of Browsers still alive will certainly be non-zero. Not sure yet - // how to handle this case. - // BrowserList::CloseAllBrowsers(false); + BrowserList::CloseAllBrowsers(true); - MessageLoopForUI::current()->Quit(); + // Release the reference to the browser process. Once all the browsers get + // dealloc'd, it will stop the RunLoop and fall back into main(). + g_browser_process->ReleaseModule(); } // Called to validate menu items when there are no key windows. All the diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index 23a8078..654da338 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -11,6 +11,7 @@ #include "base/file_util.h" #include "base/histogram.h" #include "base/lazy_instance.h" +#include "base/scoped_nsautorelease_pool.h" #include "base/path_service.h" #include "base/process_util.h" #include "base/string_piece.h" @@ -190,6 +191,7 @@ void RunUIMessageLoop(BrowserProcess* browser_process) { // Main routine for running as the Browser process. int BrowserMain(const MainFunctionParams& parameters) { const CommandLine& parsed_command_line = parameters.command_line_; + base::ScopedNSAutoreleasePool* pool = parameters.autorelease_pool_; // WARNING: If we get a WM_ENDSESSION objects created on the stack here // are NOT deleted. If you need something to run during WM_ENDSESSION add it @@ -554,13 +556,18 @@ int BrowserMain(const MainFunctionParams& parameters) { // This should happen before ProcessCommandLine. profile->InitExtensions(); + // Call Recycle() here as late as possible, just before going into the main + // loop. We can't do it any earlier, as ProcessCommandLine() will add things + // to it in the act of creating the initial browser window. int result_code = ResultCodes::NORMAL_EXIT; if (parameters.ui_task) { + if (pool) pool->Recycle(); MessageLoopForUI::current()->PostTask(FROM_HERE, parameters.ui_task); RunUIMessageLoop(browser_process.get()); } else if (BrowserInit::ProcessCommandLine(parsed_command_line, std::wstring(), local_state, true, profile, &result_code)) { + if (pool) pool->Recycle(); RunUIMessageLoop(browser_process.get()); } diff --git a/chrome/browser/browser_window_cocoa.mm b/chrome/browser/browser_window_cocoa.mm index b78b913..c541985 100644 --- a/chrome/browser/browser_window_cocoa.mm +++ b/chrome/browser/browser_window_cocoa.mm @@ -33,6 +33,7 @@ void BrowserWindowCocoa::SetBounds(const gfx::Rect& bounds) { void BrowserWindowCocoa::Close() { [window_ orderOut:controller_]; + [window_ performClose:controller_]; } void BrowserWindowCocoa::Activate() { diff --git a/chrome/common/main_function_params.h b/chrome/common/main_function_params.h index 5537879..1a240c5 100644 --- a/chrome/common/main_function_params.h +++ b/chrome/common/main_function_params.h @@ -12,13 +12,19 @@ #include "base/command_line.h" #include "chrome/common/sandbox_init_wrapper.h" +namespace base { +class ScopedNSAutoreleasePool; +}; class Task; struct MainFunctionParams { - MainFunctionParams(const CommandLine& cl, const SandboxInitWrapper& sb) - : command_line_(cl), sandbox_info_(sb), ui_task(NULL) { } + MainFunctionParams(const CommandLine& cl, const SandboxInitWrapper& sb, + base::ScopedNSAutoreleasePool* pool) + : command_line_(cl), sandbox_info_(sb), autorelease_pool_(pool), + ui_task(NULL) { } const CommandLine& command_line_; const SandboxInitWrapper& sandbox_info_; + base::ScopedNSAutoreleasePool* autorelease_pool_; // Used by InProcessBrowserTest. If non-null BrowserMain schedules this // task to run on the MessageLoop and BrowserInit is not invoked. Task* ui_task; diff --git a/chrome/renderer/renderer_main.cc b/chrome/renderer/renderer_main.cc index ff13fdb..561a9ef 100644 --- a/chrome/renderer/renderer_main.cc +++ b/chrome/renderer/renderer_main.cc @@ -6,6 +6,7 @@ #include "base/message_loop.h" #include "base/path_service.h" #include "base/platform_thread.h" +#include "base/scoped_nsautorelease_pool.h" #include "base/string_util.h" #include "base/system_monitor.h" #include "chrome/common/chrome_constants.h" @@ -56,6 +57,7 @@ static void HandleRendererErrorTestParameters(const CommandLine& command_line) { // mainline routine for running as the Rendererer process int RendererMain(const MainFunctionParams& parameters) { const CommandLine& parsed_command_line = parameters.command_line_; + base::ScopedNSAutoreleasePool* pool = parameters.autorelease_pool_; RendererMainPlatformDelegate platform(parameters); StatsScope<StatsCounterTimer> @@ -91,6 +93,7 @@ int RendererMain(const MainFunctionParams& parameters) { if (run_loop) { // Load the accelerator table from the browser executable and tell the // message loop to use it when translating messages. + if (pool) pool->Recycle(); MessageLoop::current()->Run(); } diff --git a/chrome/renderer/renderer_main_unittest.cc b/chrome/renderer/renderer_main_unittest.cc index f94c844..c938f5b 100644 --- a/chrome/renderer/renderer_main_unittest.cc +++ b/chrome/renderer/renderer_main_unittest.cc @@ -82,8 +82,7 @@ MULTIPROCESS_TEST_MAIN(SimpleRenderer) { cl.AppendSwitchWithValue(switches::kProcessChannelID, kRendererTestChannelName); - MainFunctionParams dummy_params(cl, - dummy_sandbox_init); + MainFunctionParams dummy_params(cl, dummy_sandbox_init, NULL); return RendererMain(dummy_params); } diff --git a/chrome/test/in_process_browser_test.cc b/chrome/test/in_process_browser_test.cc index 6d6cc96..dd1f919 100644 --- a/chrome/test/in_process_browser_test.cc +++ b/chrome/test/in_process_browser_test.cc @@ -88,7 +88,7 @@ void InProcessBrowserTest::SetUp() { sandbox::SandboxInterfaceInfo sandbox_info = {0}; SandboxInitWrapper sandbox_wrapper; - MainFunctionParams params(*command_line, sandbox_wrapper); + MainFunctionParams params(*command_line, sandbox_wrapper, NULL); params.ui_task = NewRunnableMethod(this, &InProcessBrowserTest::RunTestOnMainThreadLoop); BrowserMain(params); |