From 1a2a0afee53b43049d9b6c78065c6211eb7ab39b Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Tue, 3 Sep 2013 18:06:25 +0000 Subject: [PATCH] Make CefContext non-reference-counted to clarify ownership semantics. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1425 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- libcef/browser/browser_context_impl.cc | 2 +- libcef/browser/chrome_scheme_handler.cc | 4 +- libcef/browser/context.cc | 51 ++++++++++++++------ libcef/browser/context.h | 16 +++--- libcef/browser/trace_impl.cc | 6 +-- libcef/browser/url_request_context_getter.cc | 6 +-- libcef/common/main_delegate.cc | 4 +- libcef/renderer/content_renderer_client.cc | 2 +- 8 files changed, 54 insertions(+), 37 deletions(-) diff --git a/libcef/browser/browser_context_impl.cc b/libcef/browser/browser_context_impl.cc index 3a7aedb50..d31d04092 100644 --- a/libcef/browser/browser_context_impl.cc +++ b/libcef/browser/browser_context_impl.cc @@ -205,7 +205,7 @@ CefBrowserContextImpl::~CefBrowserContextImpl() { } base::FilePath CefBrowserContextImpl::GetPath() const { - return _Context->cache_path(); + return CefContext::Get()->cache_path(); } bool CefBrowserContextImpl::IsOffTheRecord() const { diff --git a/libcef/browser/chrome_scheme_handler.cc b/libcef/browser/chrome_scheme_handler.cc index 8647cb40f..88c0a0224 100644 --- a/libcef/browser/chrome_scheme_handler.cc +++ b/libcef/browser/chrome_scheme_handler.cc @@ -297,7 +297,7 @@ class Delegate : public InternalHandlerDelegate { parser.Add("USERAGENT", content::GetUserAgent(GURL())); parser.Add("COMMANDLINE", GetCommandLine()); parser.Add("MODULEPATH", GetModulePath()); - parser.Add("CACHEPATH", CefString(_Context->cache_path().value())); + parser.Add("CACHEPATH", CefString(CefContext::Get()->cache_path().value())); std::string tmpl = piece.as_string(); parser.Parse(&tmpl); @@ -632,7 +632,7 @@ void OnChromeTracingProcessMessage(CefRefPtr browser, CefString(), std::vector(), new Callback(frame, contents.Pass())); } else if (action == "getKnownCategories") { - _Context->GetTraceSubscriber()->GetKnownCategoriesAsync( + CefContext::Get()->GetTraceSubscriber()->GetKnownCategoriesAsync( base::Bind(OnKnownCategoriesCollected, frame)); } else { NOTREACHED() << "Unknown trace action: " << action.c_str(); diff --git a/libcef/browser/context.cc b/libcef/browser/context.cc index 1c13dda2f..0ab1474f2 100644 --- a/libcef/browser/context.cc +++ b/libcef/browser/context.cc @@ -36,9 +36,24 @@ #include "sandbox/win/src/sandbox_types.h" #endif -// Global CefContext pointer -CefRefPtr _Context; +namespace { +CefContext* g_context = NULL; + +// Force shutdown when the process terminates if a context currently exists and +// CefShutdown() has not been explicitly called. +class CefForceShutdown { + public: + ~CefForceShutdown() { + if (g_context) { + g_context->Shutdown(); + delete g_context; + g_context = NULL; + } + } +} g_force_shutdown; + +} // namespace int CefExecuteProcess(const CefMainArgs& args, CefRefPtr application) { @@ -79,7 +94,7 @@ bool CefInitialize(const CefMainArgs& args, const CefSettings& settings, CefRefPtr application) { // Return true if the global context already exists. - if (_Context.get()) + if (g_context) return true; if (settings.size != sizeof(cef_settings_t)) { @@ -88,10 +103,10 @@ bool CefInitialize(const CefMainArgs& args, } // Create the new global context object. - _Context = new CefContext(); + g_context = new CefContext(); // Initialize the global context. - return _Context->Initialize(args, settings, application); + return g_context->Initialize(args, settings, application); } void CefShutdown() { @@ -102,16 +117,17 @@ void CefShutdown() { } // Must always be called on the same thread as Initialize. - if (!_Context->OnInitThread()) { + if (!g_context->OnInitThread()) { NOTREACHED() << "called on invalid thread"; return; } // Shut down the global context. This will block until shutdown is complete. - _Context->Shutdown(); + g_context->Shutdown(); // Delete the global context object. - _Context = NULL; + delete g_context; + g_context = NULL; } void CefDoMessageLoopWork() { @@ -122,7 +138,7 @@ void CefDoMessageLoopWork() { } // Must always be called on the same thread as Initialize. - if (!_Context->OnInitThread()) { + if (!g_context->OnInitThread()) { NOTREACHED() << "called on invalid thread"; return; } @@ -138,7 +154,7 @@ void CefRunMessageLoop() { } // Must always be called on the same thread as Initialize. - if (!_Context->OnInitThread()) { + if (!g_context->OnInitThread()) { NOTREACHED() << "called on invalid thread"; return; } @@ -154,7 +170,7 @@ void CefQuitMessageLoop() { } // Must always be called on the same thread as Initialize. - if (!_Context->OnInitThread()) { + if (!g_context->OnInitThread()) { NOTREACHED() << "called on invalid thread"; return; } @@ -187,8 +203,11 @@ CefContext::CefContext() } CefContext::~CefContext() { - if (!shutting_down_) - Shutdown(); +} + +// static +CefContext* CefContext::Get() { + return g_context; } bool CefContext::Initialize(const CefMainArgs& args, @@ -249,7 +268,8 @@ bool CefContext::Initialize(const CefMainArgs& args, initialized_ = true; // Continue initialization on the UI thread. - CEF_POST_TASK(CEF_UIT, base::Bind(&CefContext::OnContextInitialized, this)); + CEF_POST_TASK(CEF_UIT, + base::Bind(&CefContext::OnContextInitialized, base::Unretained(this))); return true; } @@ -267,7 +287,8 @@ void CefContext::Shutdown() { // Finish shutdown on the UI thread. CEF_POST_TASK(CEF_UIT, - base::Bind(&CefContext::FinishShutdownOnUIThread, this, + base::Bind(&CefContext::FinishShutdownOnUIThread, + base::Unretained(this), &uithread_shutdown_event)); /// Block until UI thread shutdown is complete. diff --git a/libcef/browser/context.h b/libcef/browser/context.h index a003fa06b..fd4498ab1 100644 --- a/libcef/browser/context.h +++ b/libcef/browser/context.h @@ -11,7 +11,6 @@ #include #include "include/cef_app.h" -#include "include/cef_base.h" #include "base/files/file_path.h" #include "base/files/scoped_temp_dir.h" @@ -32,14 +31,16 @@ class CefBrowserHostImpl; class CefMainDelegate; class CefTraceSubscriber; -class CefContext : public CefBase, - public content::NotificationObserver { +class CefContext : public content::NotificationObserver { public: typedef std::list > BrowserList; CefContext(); ~CefContext(); + // Returns the singleton CefContext instance. + static CefContext* Get(); + // These methods will be called on the main application thread. bool Initialize(const CefMainArgs& args, const CefSettings& settings, @@ -94,16 +95,11 @@ class CefContext : public CefBase, // Only accessed on the UI Thread. scoped_ptr registrar_; - - IMPLEMENT_REFCOUNTING(CefContext); - IMPLEMENT_LOCKING(CefContext); }; -// Global context object pointer. -extern CefRefPtr _Context; - // Helper macro that returns true if the global context is in a valid state. #define CONTEXT_STATE_VALID() \ - (_Context.get() && _Context->initialized() && !_Context->shutting_down()) + (CefContext::Get() && CefContext::Get()->initialized() && \ + !CefContext::Get()->shutting_down()) #endif // CEF_LIBCEF_BROWSER_CONTEXT_H_ diff --git a/libcef/browser/trace_impl.cc b/libcef/browser/trace_impl.cc index 606ae1dd1..45ac975e3 100644 --- a/libcef/browser/trace_impl.cc +++ b/libcef/browser/trace_impl.cc @@ -23,7 +23,7 @@ bool CefBeginTracing(CefRefPtr client, return false; } - CefTraceSubscriber* subscriber = _Context->GetTraceSubscriber(); + CefTraceSubscriber* subscriber = CefContext::Get()->GetTraceSubscriber(); if (!subscriber) return false; @@ -41,7 +41,7 @@ bool CefGetTraceBufferPercentFullAsync() { return false; } - CefTraceSubscriber* subscriber = _Context->GetTraceSubscriber(); + CefTraceSubscriber* subscriber = CefContext::Get()->GetTraceSubscriber(); if (!subscriber) return false; @@ -59,7 +59,7 @@ bool CefEndTracingAsync() { return false; } - CefTraceSubscriber* subscriber = _Context->GetTraceSubscriber(); + CefTraceSubscriber* subscriber = CefContext::Get()->GetTraceSubscriber(); if (!subscriber) return false; diff --git a/libcef/browser/url_request_context_getter.cc b/libcef/browser/url_request_context_getter.cc index 6b4930f6b..ef927e5e8 100644 --- a/libcef/browser/url_request_context_getter.cc +++ b/libcef/browser/url_request_context_getter.cc @@ -77,9 +77,9 @@ net::URLRequestContext* CefURLRequestContextGetter::GetURLRequestContext() { CEF_REQUIRE_IOT(); if (!url_request_context_.get()) { - const base::FilePath& cache_path = _Context->cache_path(); + const base::FilePath& cache_path = CefContext::Get()->cache_path(); const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - const CefSettings& settings = _Context->settings(); + const CefSettings& settings = CefContext::Get()->settings(); url_request_context_.reset(new net::URLRequestContext()); storage_.reset( @@ -290,7 +290,7 @@ void CefURLRequestContextGetter::ReleaseURLRequestContextProxy( // Don't do anything if we're currently shutting down. The proxy objects will // be deleted when this object is destroyed. - if (_Context->shutting_down()) + if (CefContext::Get()->shutting_down()) return; if (proxy->url_requests()->size() == 0) { diff --git a/libcef/common/main_delegate.cc b/libcef/common/main_delegate.cc index 87b23616a..54ea2dff9 100644 --- a/libcef/common/main_delegate.cc +++ b/libcef/common/main_delegate.cc @@ -151,7 +151,7 @@ bool CefMainDelegate::BasicStartupComplete(int* exit_code) { if (process_type.empty()) { // In the browser process. Populate the global command-line object. - const CefSettings& settings = _Context->settings(); + const CefSettings& settings = CefContext::Get()->settings(); if (settings.command_line_args_disabled) { // Remove any existing command-line arguments. @@ -355,7 +355,7 @@ int CefMainDelegate::RunProcess( const std::string& process_type, const content::MainFunctionParams& main_function_params) { if (process_type.empty()) { - const CefSettings& settings = _Context->settings(); + const CefSettings& settings = CefContext::Get()->settings(); if (!settings.multi_threaded_message_loop) { // Use our own browser process runner. browser_runner_.reset(content::BrowserMainRunner::Create()); diff --git a/libcef/renderer/content_renderer_client.cc b/libcef/renderer/content_renderer_client.cc index d7ee949d4..17a23442d 100644 --- a/libcef/renderer/content_renderer_client.cc +++ b/libcef/renderer/content_renderer_client.cc @@ -678,6 +678,6 @@ void CefContentRendererClient::RunSingleProcessCleanupOnUIThread() { // this task will only execute when running in multi-threaded message loop // mode (because otherwise the UI message loop has already stopped). Therefore // we need to explicitly delete the object when not running in this mode. - if (!_Context->settings().multi_threaded_message_loop) + if (!CefContext::Get()->settings().multi_threaded_message_loop) delete host; }