summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/scoped_nsautorelease_pool.h6
-rw-r--r--base/scoped_nsautorelease_pool.mm11
-rw-r--r--chrome/app/chrome_dll_main.cc12
-rw-r--r--chrome/browser/app_controller_mac.mm21
-rw-r--r--chrome/browser/browser_main.cc7
-rw-r--r--chrome/browser/browser_window_cocoa.mm1
-rw-r--r--chrome/common/main_function_params.h10
-rw-r--r--chrome/renderer/renderer_main.cc3
-rw-r--r--chrome/renderer/renderer_main_unittest.cc3
-rw-r--r--chrome/test/in_process_browser_test.cc2
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);