Make CefContext non-reference-counted to clarify ownership semantics.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1425 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2013-09-03 18:06:25 +00:00
parent 385be456c3
commit 1a2a0afee5
8 changed files with 54 additions and 37 deletions

View File

@ -205,7 +205,7 @@ CefBrowserContextImpl::~CefBrowserContextImpl() {
} }
base::FilePath CefBrowserContextImpl::GetPath() const { base::FilePath CefBrowserContextImpl::GetPath() const {
return _Context->cache_path(); return CefContext::Get()->cache_path();
} }
bool CefBrowserContextImpl::IsOffTheRecord() const { bool CefBrowserContextImpl::IsOffTheRecord() const {

View File

@ -297,7 +297,7 @@ class Delegate : public InternalHandlerDelegate {
parser.Add("USERAGENT", content::GetUserAgent(GURL())); parser.Add("USERAGENT", content::GetUserAgent(GURL()));
parser.Add("COMMANDLINE", GetCommandLine()); parser.Add("COMMANDLINE", GetCommandLine());
parser.Add("MODULEPATH", GetModulePath()); 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(); std::string tmpl = piece.as_string();
parser.Parse(&tmpl); parser.Parse(&tmpl);
@ -632,7 +632,7 @@ void OnChromeTracingProcessMessage(CefRefPtr<CefBrowser> browser,
CefString(), std::vector<CefString>(), CefString(), std::vector<CefString>(),
new Callback(frame, contents.Pass())); new Callback(frame, contents.Pass()));
} else if (action == "getKnownCategories") { } else if (action == "getKnownCategories") {
_Context->GetTraceSubscriber()->GetKnownCategoriesAsync( CefContext::Get()->GetTraceSubscriber()->GetKnownCategoriesAsync(
base::Bind(OnKnownCategoriesCollected, frame)); base::Bind(OnKnownCategoriesCollected, frame));
} else { } else {
NOTREACHED() << "Unknown trace action: " << action.c_str(); NOTREACHED() << "Unknown trace action: " << action.c_str();

View File

@ -36,9 +36,24 @@
#include "sandbox/win/src/sandbox_types.h" #include "sandbox/win/src/sandbox_types.h"
#endif #endif
// Global CefContext pointer namespace {
CefRefPtr<CefContext> _Context;
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, int CefExecuteProcess(const CefMainArgs& args,
CefRefPtr<CefApp> application) { CefRefPtr<CefApp> application) {
@ -79,7 +94,7 @@ bool CefInitialize(const CefMainArgs& args,
const CefSettings& settings, const CefSettings& settings,
CefRefPtr<CefApp> application) { CefRefPtr<CefApp> application) {
// Return true if the global context already exists. // Return true if the global context already exists.
if (_Context.get()) if (g_context)
return true; return true;
if (settings.size != sizeof(cef_settings_t)) { if (settings.size != sizeof(cef_settings_t)) {
@ -88,10 +103,10 @@ bool CefInitialize(const CefMainArgs& args,
} }
// Create the new global context object. // Create the new global context object.
_Context = new CefContext(); g_context = new CefContext();
// Initialize the global context. // Initialize the global context.
return _Context->Initialize(args, settings, application); return g_context->Initialize(args, settings, application);
} }
void CefShutdown() { void CefShutdown() {
@ -102,16 +117,17 @@ void CefShutdown() {
} }
// Must always be called on the same thread as Initialize. // Must always be called on the same thread as Initialize.
if (!_Context->OnInitThread()) { if (!g_context->OnInitThread()) {
NOTREACHED() << "called on invalid thread"; NOTREACHED() << "called on invalid thread";
return; return;
} }
// Shut down the global context. This will block until shutdown is complete. // Shut down the global context. This will block until shutdown is complete.
_Context->Shutdown(); g_context->Shutdown();
// Delete the global context object. // Delete the global context object.
_Context = NULL; delete g_context;
g_context = NULL;
} }
void CefDoMessageLoopWork() { void CefDoMessageLoopWork() {
@ -122,7 +138,7 @@ void CefDoMessageLoopWork() {
} }
// Must always be called on the same thread as Initialize. // Must always be called on the same thread as Initialize.
if (!_Context->OnInitThread()) { if (!g_context->OnInitThread()) {
NOTREACHED() << "called on invalid thread"; NOTREACHED() << "called on invalid thread";
return; return;
} }
@ -138,7 +154,7 @@ void CefRunMessageLoop() {
} }
// Must always be called on the same thread as Initialize. // Must always be called on the same thread as Initialize.
if (!_Context->OnInitThread()) { if (!g_context->OnInitThread()) {
NOTREACHED() << "called on invalid thread"; NOTREACHED() << "called on invalid thread";
return; return;
} }
@ -154,7 +170,7 @@ void CefQuitMessageLoop() {
} }
// Must always be called on the same thread as Initialize. // Must always be called on the same thread as Initialize.
if (!_Context->OnInitThread()) { if (!g_context->OnInitThread()) {
NOTREACHED() << "called on invalid thread"; NOTREACHED() << "called on invalid thread";
return; return;
} }
@ -187,8 +203,11 @@ CefContext::CefContext()
} }
CefContext::~CefContext() { CefContext::~CefContext() {
if (!shutting_down_) }
Shutdown();
// static
CefContext* CefContext::Get() {
return g_context;
} }
bool CefContext::Initialize(const CefMainArgs& args, bool CefContext::Initialize(const CefMainArgs& args,
@ -249,7 +268,8 @@ bool CefContext::Initialize(const CefMainArgs& args,
initialized_ = true; initialized_ = true;
// Continue initialization on the UI thread. // 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; return true;
} }
@ -267,7 +287,8 @@ void CefContext::Shutdown() {
// Finish shutdown on the UI thread. // Finish shutdown on the UI thread.
CEF_POST_TASK(CEF_UIT, CEF_POST_TASK(CEF_UIT,
base::Bind(&CefContext::FinishShutdownOnUIThread, this, base::Bind(&CefContext::FinishShutdownOnUIThread,
base::Unretained(this),
&uithread_shutdown_event)); &uithread_shutdown_event));
/// Block until UI thread shutdown is complete. /// Block until UI thread shutdown is complete.

View File

@ -11,7 +11,6 @@
#include <string> #include <string>
#include "include/cef_app.h" #include "include/cef_app.h"
#include "include/cef_base.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h" #include "base/files/scoped_temp_dir.h"
@ -32,14 +31,16 @@ class CefBrowserHostImpl;
class CefMainDelegate; class CefMainDelegate;
class CefTraceSubscriber; class CefTraceSubscriber;
class CefContext : public CefBase, class CefContext : public content::NotificationObserver {
public content::NotificationObserver {
public: public:
typedef std::list<CefRefPtr<CefBrowserHostImpl> > BrowserList; typedef std::list<CefRefPtr<CefBrowserHostImpl> > BrowserList;
CefContext(); CefContext();
~CefContext(); ~CefContext();
// Returns the singleton CefContext instance.
static CefContext* Get();
// These methods will be called on the main application thread. // These methods will be called on the main application thread.
bool Initialize(const CefMainArgs& args, bool Initialize(const CefMainArgs& args,
const CefSettings& settings, const CefSettings& settings,
@ -94,16 +95,11 @@ class CefContext : public CefBase,
// Only accessed on the UI Thread. // Only accessed on the UI Thread.
scoped_ptr<content::NotificationRegistrar> registrar_; scoped_ptr<content::NotificationRegistrar> registrar_;
IMPLEMENT_REFCOUNTING(CefContext);
IMPLEMENT_LOCKING(CefContext);
}; };
// Global context object pointer.
extern CefRefPtr<CefContext> _Context;
// Helper macro that returns true if the global context is in a valid state. // Helper macro that returns true if the global context is in a valid state.
#define CONTEXT_STATE_VALID() \ #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_ #endif // CEF_LIBCEF_BROWSER_CONTEXT_H_

View File

@ -23,7 +23,7 @@ bool CefBeginTracing(CefRefPtr<CefTraceClient> client,
return false; return false;
} }
CefTraceSubscriber* subscriber = _Context->GetTraceSubscriber(); CefTraceSubscriber* subscriber = CefContext::Get()->GetTraceSubscriber();
if (!subscriber) if (!subscriber)
return false; return false;
@ -41,7 +41,7 @@ bool CefGetTraceBufferPercentFullAsync() {
return false; return false;
} }
CefTraceSubscriber* subscriber = _Context->GetTraceSubscriber(); CefTraceSubscriber* subscriber = CefContext::Get()->GetTraceSubscriber();
if (!subscriber) if (!subscriber)
return false; return false;
@ -59,7 +59,7 @@ bool CefEndTracingAsync() {
return false; return false;
} }
CefTraceSubscriber* subscriber = _Context->GetTraceSubscriber(); CefTraceSubscriber* subscriber = CefContext::Get()->GetTraceSubscriber();
if (!subscriber) if (!subscriber)
return false; return false;

View File

@ -77,9 +77,9 @@ net::URLRequestContext* CefURLRequestContextGetter::GetURLRequestContext() {
CEF_REQUIRE_IOT(); CEF_REQUIRE_IOT();
if (!url_request_context_.get()) { 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 CommandLine& command_line = *CommandLine::ForCurrentProcess();
const CefSettings& settings = _Context->settings(); const CefSettings& settings = CefContext::Get()->settings();
url_request_context_.reset(new net::URLRequestContext()); url_request_context_.reset(new net::URLRequestContext());
storage_.reset( storage_.reset(
@ -290,7 +290,7 @@ void CefURLRequestContextGetter::ReleaseURLRequestContextProxy(
// Don't do anything if we're currently shutting down. The proxy objects will // Don't do anything if we're currently shutting down. The proxy objects will
// be deleted when this object is destroyed. // be deleted when this object is destroyed.
if (_Context->shutting_down()) if (CefContext::Get()->shutting_down())
return; return;
if (proxy->url_requests()->size() == 0) { if (proxy->url_requests()->size() == 0) {

View File

@ -151,7 +151,7 @@ bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
if (process_type.empty()) { if (process_type.empty()) {
// In the browser process. Populate the global command-line object. // 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) { if (settings.command_line_args_disabled) {
// Remove any existing command-line arguments. // Remove any existing command-line arguments.
@ -355,7 +355,7 @@ int CefMainDelegate::RunProcess(
const std::string& process_type, const std::string& process_type,
const content::MainFunctionParams& main_function_params) { const content::MainFunctionParams& main_function_params) {
if (process_type.empty()) { if (process_type.empty()) {
const CefSettings& settings = _Context->settings(); const CefSettings& settings = CefContext::Get()->settings();
if (!settings.multi_threaded_message_loop) { if (!settings.multi_threaded_message_loop) {
// Use our own browser process runner. // Use our own browser process runner.
browser_runner_.reset(content::BrowserMainRunner::Create()); browser_runner_.reset(content::BrowserMainRunner::Create());

View File

@ -678,6 +678,6 @@ void CefContentRendererClient::RunSingleProcessCleanupOnUIThread() {
// this task will only execute when running in multi-threaded message loop // this task will only execute when running in multi-threaded message loop
// mode (because otherwise the UI message loop has already stopped). Therefore // mode (because otherwise the UI message loop has already stopped). Therefore
// we need to explicitly delete the object when not running in this mode. // 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; delete host;
} }