Cleanup destruction of URLRequestContextGetter (#12305)
- Add Leak detector - Indicate shutdown of request context from Browser Context - Change stored references to URLRequestContextGetter to use BrowserContext - Destroy session properties explicitly
This commit is contained in:
parent
fc00a2ba32
commit
171230e45d
14 changed files with 144 additions and 96 deletions
|
@ -238,11 +238,11 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||||
: browser_context_(browser_context),
|
: browser_context_(browser_context) {
|
||||||
request_context_getter_(browser_context->url_request_context_getter()) {
|
|
||||||
Init(isolate);
|
Init(isolate);
|
||||||
cookie_change_subscription_ = browser_context->RegisterCookieChangeCallback(
|
auto subscription = browser_context->RegisterCookieChangeCallback(
|
||||||
base::Bind(&Cookies::OnCookieChanged, base::Unretained(this)));
|
base::Bind(&Cookies::OnCookieChanged, base::Unretained(this)));
|
||||||
|
browser_context->set_cookie_change_subscription(std::move(subscription));
|
||||||
}
|
}
|
||||||
|
|
||||||
Cookies::~Cookies() {}
|
Cookies::~Cookies() {}
|
||||||
|
@ -250,34 +250,38 @@ Cookies::~Cookies() {}
|
||||||
void Cookies::Get(const base::DictionaryValue& filter,
|
void Cookies::Get(const base::DictionaryValue& filter,
|
||||||
const GetCallback& callback) {
|
const GetCallback& callback) {
|
||||||
std::unique_ptr<base::DictionaryValue> copied(filter.CreateDeepCopy());
|
std::unique_ptr<base::DictionaryValue> copied(filter.CreateDeepCopy());
|
||||||
auto getter = WrapRefCounted(request_context_getter_);
|
auto getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
BrowserThread::IO, FROM_HERE,
|
BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(GetCookiesOnIO, getter, Passed(&copied), callback));
|
base::BindOnce(GetCookiesOnIO, base::RetainedRef(getter), Passed(&copied),
|
||||||
|
callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cookies::Remove(const GURL& url, const std::string& name,
|
void Cookies::Remove(const GURL& url, const std::string& name,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
auto getter = WrapRefCounted(request_context_getter_);
|
auto getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
BrowserThread::IO, FROM_HERE,
|
BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(RemoveCookieOnIOThread, getter, url, name, callback));
|
base::BindOnce(RemoveCookieOnIOThread, base::RetainedRef(getter), url,
|
||||||
|
name, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cookies::Set(const base::DictionaryValue& details,
|
void Cookies::Set(const base::DictionaryValue& details,
|
||||||
const SetCallback& callback) {
|
const SetCallback& callback) {
|
||||||
std::unique_ptr<base::DictionaryValue> copied(details.CreateDeepCopy());
|
std::unique_ptr<base::DictionaryValue> copied(details.CreateDeepCopy());
|
||||||
auto getter = WrapRefCounted(request_context_getter_);
|
auto getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
BrowserThread::IO, FROM_HERE,
|
BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(SetCookieOnIO, getter, Passed(&copied), callback));
|
base::BindOnce(SetCookieOnIO, base::RetainedRef(getter), Passed(&copied),
|
||||||
|
callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cookies::FlushStore(const base::Closure& callback) {
|
void Cookies::FlushStore(const base::Closure& callback) {
|
||||||
auto getter = WrapRefCounted(request_context_getter_);
|
auto getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
BrowserThread::IO, FROM_HERE,
|
BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(FlushCookieStoreOnIOThread, getter, callback));
|
base::BindOnce(FlushCookieStoreOnIOThread, base::RetainedRef(getter),
|
||||||
|
callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cookies::OnCookieChanged(const CookieDetails* details) {
|
void Cookies::OnCookieChanged(const CookieDetails* details) {
|
||||||
|
|
|
@ -58,12 +58,7 @@ class Cookies : public mate::TrackableObject<Cookies> {
|
||||||
void OnCookieChanged(const CookieDetails*);
|
void OnCookieChanged(const CookieDetails*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Store a reference to ensure this class gets destroyed before the context.
|
|
||||||
scoped_refptr<AtomBrowserContext> browser_context_;
|
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||||
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
|
|
||||||
cookie_change_subscription_;
|
|
||||||
|
|
||||||
net::URLRequestContextGetter* request_context_getter_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Cookies);
|
DISALLOW_COPY_AND_ASSIGN(Cookies);
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,14 +33,6 @@ namespace {
|
||||||
// List of registered custom standard schemes.
|
// List of registered custom standard schemes.
|
||||||
std::vector<std::string> g_standard_schemes;
|
std::vector<std::string> g_standard_schemes;
|
||||||
|
|
||||||
// Clear protocol handlers in IO thread.
|
|
||||||
void ClearJobFactoryInIO(
|
|
||||||
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter) {
|
|
||||||
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
|
|
||||||
request_context_getter->job_factory());
|
|
||||||
job_factory->Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::vector<std::string> GetStandardSchemes() {
|
std::vector<std::string> GetStandardSchemes() {
|
||||||
|
@ -76,15 +68,11 @@ void RegisterStandardSchemes(const std::vector<std::string>& schemes,
|
||||||
}
|
}
|
||||||
|
|
||||||
Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||||
: request_context_getter_(browser_context->GetRequestContext()),
|
: browser_context_(browser_context), weak_factory_(this) {
|
||||||
weak_factory_(this) {
|
|
||||||
Init(isolate);
|
Init(isolate);
|
||||||
}
|
}
|
||||||
|
|
||||||
Protocol::~Protocol() {
|
Protocol::~Protocol() {
|
||||||
content::BrowserThread::PostTask(
|
|
||||||
content::BrowserThread::IO, FROM_HERE,
|
|
||||||
base::Bind(ClearJobFactoryInIO, request_context_getter_));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Protocol::RegisterServiceWorkerSchemes(
|
void Protocol::RegisterServiceWorkerSchemes(
|
||||||
|
@ -96,12 +84,12 @@ void Protocol::UnregisterProtocol(
|
||||||
const std::string& scheme, mate::Arguments* args) {
|
const std::string& scheme, mate::Arguments* args) {
|
||||||
CompletionCallback callback;
|
CompletionCallback callback;
|
||||||
args->GetNext(&callback);
|
args->GetNext(&callback);
|
||||||
|
auto getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||||
content::BrowserThread::IO, FROM_HERE,
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(&Protocol::UnregisterProtocolInIO,
|
base::BindOnce(&Protocol::UnregisterProtocolInIO,
|
||||||
request_context_getter_, scheme),
|
base::RetainedRef(getter), scheme),
|
||||||
base::Bind(&Protocol::OnIOCompleted,
|
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||||
GetWeakPtr(), callback));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -118,10 +106,11 @@ Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
|
||||||
|
|
||||||
void Protocol::IsProtocolHandled(const std::string& scheme,
|
void Protocol::IsProtocolHandled(const std::string& scheme,
|
||||||
const BooleanCallback& callback) {
|
const BooleanCallback& callback) {
|
||||||
|
auto getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||||
content::BrowserThread::IO, FROM_HERE,
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(&Protocol::IsProtocolHandledInIO,
|
base::Bind(&Protocol::IsProtocolHandledInIO, base::RetainedRef(getter),
|
||||||
request_context_getter_, scheme),
|
scheme),
|
||||||
callback);
|
callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,12 +125,12 @@ void Protocol::UninterceptProtocol(
|
||||||
const std::string& scheme, mate::Arguments* args) {
|
const std::string& scheme, mate::Arguments* args) {
|
||||||
CompletionCallback callback;
|
CompletionCallback callback;
|
||||||
args->GetNext(&callback);
|
args->GetNext(&callback);
|
||||||
|
auto getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||||
content::BrowserThread::IO, FROM_HERE,
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(&Protocol::UninterceptProtocolInIO,
|
base::BindOnce(&Protocol::UninterceptProtocolInIO,
|
||||||
request_context_getter_, scheme),
|
base::RetainedRef(getter), scheme),
|
||||||
base::Bind(&Protocol::OnIOCompleted,
|
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||||
GetWeakPtr(), callback));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -181,13 +170,6 @@ std::string Protocol::ErrorCodeToString(ProtocolError error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AtomURLRequestJobFactory* Protocol::GetJobFactoryInIO() const {
|
|
||||||
request_context_getter_->GetURLRequestContext(); // Force init.
|
|
||||||
return static_cast<AtomURLRequestJobFactory*>(
|
|
||||||
static_cast<brightray::URLRequestContextGetter*>(
|
|
||||||
request_context_getter_.get())->job_factory());
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
mate::Handle<Protocol> Protocol::Create(
|
mate::Handle<Protocol> Protocol::Create(
|
||||||
v8::Isolate* isolate, AtomBrowserContext* browser_context) {
|
v8::Isolate* isolate, AtomBrowserContext* browser_context) {
|
||||||
|
|
|
@ -101,12 +101,12 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
||||||
mate::Arguments* args) {
|
mate::Arguments* args) {
|
||||||
CompletionCallback callback;
|
CompletionCallback callback;
|
||||||
args->GetNext(&callback);
|
args->GetNext(&callback);
|
||||||
|
auto getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||||
content::BrowserThread::IO, FROM_HERE,
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(&Protocol::RegisterProtocolInIO<RequestJob>,
|
base::BindOnce(&Protocol::RegisterProtocolInIO<RequestJob>,
|
||||||
request_context_getter_, isolate(), scheme, handler),
|
base::RetainedRef(getter), isolate(), scheme, handler),
|
||||||
base::Bind(&Protocol::OnIOCompleted,
|
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||||
GetWeakPtr(), callback));
|
|
||||||
}
|
}
|
||||||
template<typename RequestJob>
|
template<typename RequestJob>
|
||||||
static ProtocolError RegisterProtocolInIO(
|
static ProtocolError RegisterProtocolInIO(
|
||||||
|
@ -147,12 +147,12 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
||||||
mate::Arguments* args) {
|
mate::Arguments* args) {
|
||||||
CompletionCallback callback;
|
CompletionCallback callback;
|
||||||
args->GetNext(&callback);
|
args->GetNext(&callback);
|
||||||
|
auto getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||||
content::BrowserThread::IO, FROM_HERE,
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(&Protocol::InterceptProtocolInIO<RequestJob>,
|
base::BindOnce(&Protocol::InterceptProtocolInIO<RequestJob>,
|
||||||
request_context_getter_, isolate(), scheme, handler),
|
base::RetainedRef(getter), isolate(), scheme, handler),
|
||||||
base::Bind(&Protocol::OnIOCompleted,
|
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||||
GetWeakPtr(), callback));
|
|
||||||
}
|
}
|
||||||
template<typename RequestJob>
|
template<typename RequestJob>
|
||||||
static ProtocolError InterceptProtocolInIO(
|
static ProtocolError InterceptProtocolInIO(
|
||||||
|
@ -187,13 +187,11 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
||||||
// Convert error code to string.
|
// Convert error code to string.
|
||||||
std::string ErrorCodeToString(ProtocolError error);
|
std::string ErrorCodeToString(ProtocolError error);
|
||||||
|
|
||||||
AtomURLRequestJobFactory* GetJobFactoryInIO() const;
|
|
||||||
|
|
||||||
base::WeakPtr<Protocol> GetWeakPtr() {
|
base::WeakPtr<Protocol> GetWeakPtr() {
|
||||||
return weak_factory_.GetWeakPtr();
|
return weak_factory_.GetWeakPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter_;
|
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||||
base::WeakPtrFactory<Protocol> weak_factory_;
|
base::WeakPtrFactory<Protocol> weak_factory_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Protocol);
|
DISALLOW_COPY_AND_ASSIGN(Protocol);
|
||||||
|
|
|
@ -342,7 +342,7 @@ void DoCacheActionInIO(
|
||||||
on_get_backend.Run(net::OK);
|
on_get_backend.Run(net::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetProxyInIO(net::URLRequestContextGetter* getter,
|
void SetProxyInIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||||
const net::ProxyConfig& config,
|
const net::ProxyConfig& config,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
auto proxy_service = getter->GetURLRequestContext()->proxy_service();
|
auto proxy_service = getter->GetURLRequestContext()->proxy_service();
|
||||||
|
@ -452,6 +452,32 @@ void SetDevToolsNetworkEmulationClientIdInIO(
|
||||||
network_delegate->SetDevToolsNetworkEmulationClientId(client_id);
|
network_delegate->SetDevToolsNetworkEmulationClientId(client_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear protocol handlers in IO thread.
|
||||||
|
void ClearJobFactoryInIO(
|
||||||
|
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter) {
|
||||||
|
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
|
||||||
|
request_context_getter->job_factory());
|
||||||
|
if (job_factory)
|
||||||
|
job_factory->Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyGlobalHandle(v8::Isolate* isolate,
|
||||||
|
const v8::Global<v8::Value>& global_handle) {
|
||||||
|
v8::Locker locker(isolate);
|
||||||
|
v8::HandleScope handle_scope(isolate);
|
||||||
|
if (!global_handle.IsEmpty()) {
|
||||||
|
v8::Local<v8::Value> local_handle = global_handle.Get(isolate);
|
||||||
|
if (local_handle->IsObject()) {
|
||||||
|
v8::Local<v8::Object> object = local_handle->ToObject();
|
||||||
|
void* ptr = object->GetAlignedPointerFromInternalField(0);
|
||||||
|
if (!ptr)
|
||||||
|
return;
|
||||||
|
delete static_cast<mate::WrappableBase*>(ptr);
|
||||||
|
object->SetAlignedPointerInInternalField(0, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||||
|
@ -468,8 +494,15 @@ Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||||
}
|
}
|
||||||
|
|
||||||
Session::~Session() {
|
Session::~Session() {
|
||||||
|
auto getter = browser_context_->GetRequestContext();
|
||||||
|
content::BrowserThread::PostTask(
|
||||||
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
|
base::BindOnce(ClearJobFactoryInIO, base::RetainedRef(getter)));
|
||||||
content::BrowserContext::GetDownloadManager(browser_context())->
|
content::BrowserContext::GetDownloadManager(browser_context())->
|
||||||
RemoveObserver(this);
|
RemoveObserver(this);
|
||||||
|
DestroyGlobalHandle(isolate(), cookies_);
|
||||||
|
DestroyGlobalHandle(isolate(), web_request_);
|
||||||
|
DestroyGlobalHandle(isolate(), protocol_);
|
||||||
g_sessions.erase(weak_map_id());
|
g_sessions.erase(weak_map_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,8 +566,10 @@ void Session::FlushStorageData() {
|
||||||
void Session::SetProxy(const net::ProxyConfig& config,
|
void Session::SetProxy(const net::ProxyConfig& config,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
auto getter = browser_context_->GetRequestContext();
|
auto getter = browser_context_->GetRequestContext();
|
||||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
BrowserThread::PostTask(
|
||||||
base::Bind(&SetProxyInIO, base::Unretained(getter), config, callback));
|
BrowserThread::IO, FROM_HERE,
|
||||||
|
base::BindOnce(&SetProxyInIO, base::RetainedRef(getter), config,
|
||||||
|
callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::SetDownloadPath(const base::FilePath& path) {
|
void Session::SetDownloadPath(const base::FilePath& path) {
|
||||||
|
|
|
@ -31,15 +31,16 @@ class IDUserData : public base::SupportsUserData::Data {
|
||||||
|
|
||||||
TrackableObjectBase::TrackableObjectBase()
|
TrackableObjectBase::TrackableObjectBase()
|
||||||
: weak_map_id_(0), weak_factory_(this) {
|
: weak_map_id_(0), weak_factory_(this) {
|
||||||
cleanup_ = RegisterDestructionCallback(GetDestroyClosure());
|
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
|
||||||
|
GetDestroyClosure());
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackableObjectBase::~TrackableObjectBase() {
|
TrackableObjectBase::~TrackableObjectBase() {
|
||||||
cleanup_.Run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
base::Closure TrackableObjectBase::GetDestroyClosure() {
|
base::OnceClosure TrackableObjectBase::GetDestroyClosure() {
|
||||||
return base::Bind(&TrackableObjectBase::Destroy, weak_factory_.GetWeakPtr());
|
return base::BindOnce(&TrackableObjectBase::Destroy,
|
||||||
|
weak_factory_.GetWeakPtr());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackableObjectBase::Destroy() {
|
void TrackableObjectBase::Destroy() {
|
||||||
|
@ -62,10 +63,4 @@ int32_t TrackableObjectBase::GetIDFromWrappedClass(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
base::Closure TrackableObjectBase::RegisterDestructionCallback(
|
|
||||||
const base::Closure& c) {
|
|
||||||
return atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace mate
|
} // namespace mate
|
||||||
|
|
|
@ -37,18 +37,13 @@ class TrackableObjectBase {
|
||||||
virtual ~TrackableObjectBase();
|
virtual ~TrackableObjectBase();
|
||||||
|
|
||||||
// Returns a closure that can destroy the native class.
|
// Returns a closure that can destroy the native class.
|
||||||
base::Closure GetDestroyClosure();
|
base::OnceClosure GetDestroyClosure();
|
||||||
|
|
||||||
// Register a callback that should be destroyed before JavaScript environment
|
|
||||||
// gets destroyed.
|
|
||||||
static base::Closure RegisterDestructionCallback(const base::Closure& c);
|
|
||||||
|
|
||||||
int32_t weak_map_id_;
|
int32_t weak_map_id_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
base::Closure cleanup_;
|
|
||||||
base::WeakPtrFactory<TrackableObjectBase> weak_factory_;
|
base::WeakPtrFactory<TrackableObjectBase> weak_factory_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(TrackableObjectBase);
|
DISALLOW_COPY_AND_ASSIGN(TrackableObjectBase);
|
||||||
|
|
|
@ -59,6 +59,13 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||||
|
|
||||||
AtomBlobReader* GetBlobReader();
|
AtomBlobReader* GetBlobReader();
|
||||||
|
|
||||||
|
void set_cookie_change_subscription(
|
||||||
|
std::unique_ptr<
|
||||||
|
base::CallbackList<void(const CookieDetails*)>::Subscription>
|
||||||
|
subscription) {
|
||||||
|
cookie_change_subscription_.swap(subscription);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AtomBrowserContext(const std::string& partition, bool in_memory,
|
AtomBrowserContext(const std::string& partition, bool in_memory,
|
||||||
const base::DictionaryValue& options);
|
const base::DictionaryValue& options);
|
||||||
|
@ -73,6 +80,8 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||||
bool use_cache_;
|
bool use_cache_;
|
||||||
|
|
||||||
base::CallbackList<void(const CookieDetails*)> cookie_change_sub_list_;
|
base::CallbackList<void(const CookieDetails*)> cookie_change_sub_list_;
|
||||||
|
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
|
||||||
|
cookie_change_subscription_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
|
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
|
||||||
};
|
};
|
||||||
|
|
|
@ -110,10 +110,9 @@ int AtomBrowserMainParts::GetExitCode() {
|
||||||
return exit_code_ != nullptr ? *exit_code_ : 0;
|
return exit_code_ != nullptr ? *exit_code_ : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
base::Closure AtomBrowserMainParts::RegisterDestructionCallback(
|
void AtomBrowserMainParts::RegisterDestructionCallback(
|
||||||
const base::Closure& callback) {
|
base::OnceClosure callback) {
|
||||||
auto iter = destructors_.insert(destructors_.end(), callback);
|
destructors_.insert(destructors_.end(), std::move(callback));
|
||||||
return base::Bind(&Erase<std::list<base::Closure>>, &destructors_, iter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomBrowserMainParts::PreEarlyInitialization() {
|
void AtomBrowserMainParts::PreEarlyInitialization() {
|
||||||
|
@ -242,9 +241,10 @@ void AtomBrowserMainParts::PostMainMessageLoopRun() {
|
||||||
// We don't use ranged for loop because iterators are getting invalided when
|
// We don't use ranged for loop because iterators are getting invalided when
|
||||||
// the callback runs.
|
// the callback runs.
|
||||||
for (auto iter = destructors_.begin(); iter != destructors_.end();) {
|
for (auto iter = destructors_.begin(); iter != destructors_.end();) {
|
||||||
base::Closure& callback = *iter;
|
base::OnceClosure callback = std::move(*iter);
|
||||||
|
if (!callback.is_null())
|
||||||
|
std::move(callback).Run();
|
||||||
++iter;
|
++iter;
|
||||||
callback.Run();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||||
// Register a callback that should be destroyed before JavaScript environment
|
// Register a callback that should be destroyed before JavaScript environment
|
||||||
// gets destroyed.
|
// gets destroyed.
|
||||||
// Returns a closure that can be used to remove |callback| from the list.
|
// Returns a closure that can be used to remove |callback| from the list.
|
||||||
base::Closure RegisterDestructionCallback(const base::Closure& callback);
|
void RegisterDestructionCallback(base::OnceClosure callback);
|
||||||
|
|
||||||
Browser* browser() { return browser_.get(); }
|
Browser* browser() { return browser_.get(); }
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||||
base::Timer gc_timer_;
|
base::Timer gc_timer_;
|
||||||
|
|
||||||
// List of callbacks should be executed before destroying JS env.
|
// List of callbacks should be executed before destroying JS env.
|
||||||
std::list<base::Closure> destructors_;
|
std::list<base::OnceClosure> destructors_;
|
||||||
|
|
||||||
static AtomBrowserMainParts* self_;
|
static AtomBrowserMainParts* self_;
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,7 @@ void AtomURLRequestJobFactory::Clear() {
|
||||||
for (auto& it : protocol_handler_map_)
|
for (auto& it : protocol_handler_map_)
|
||||||
delete it.second;
|
delete it.second;
|
||||||
protocol_handler_map_.clear();
|
protocol_handler_map_.clear();
|
||||||
|
original_protocols_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
|
net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
|
||||||
|
|
|
@ -92,11 +92,17 @@ BrowserContext::BrowserContext(const std::string& partition, bool in_memory)
|
||||||
}
|
}
|
||||||
|
|
||||||
BrowserContext::~BrowserContext() {
|
BrowserContext::~BrowserContext() {
|
||||||
|
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||||
NotifyWillBeDestroyed(this);
|
NotifyWillBeDestroyed(this);
|
||||||
ShutdownStoragePartitions();
|
ShutdownStoragePartitions();
|
||||||
BrowserThread::DeleteSoon(BrowserThread::IO,
|
if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
|
||||||
FROM_HERE,
|
BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE,
|
||||||
resource_context_.release());
|
resource_context_.release());
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::IO, FROM_HERE,
|
||||||
|
base::BindOnce(&URLRequestContextGetter::NotifyContextShutdownOnIO,
|
||||||
|
base::RetainedRef(url_request_getter_)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserContext::InitPrefs() {
|
void BrowserContext::InitPrefs() {
|
||||||
|
|
|
@ -130,7 +130,8 @@ URLRequestContextGetter::URLRequestContextGetter(
|
||||||
in_memory_(in_memory),
|
in_memory_(in_memory),
|
||||||
io_task_runner_(io_task_runner),
|
io_task_runner_(io_task_runner),
|
||||||
protocol_interceptors_(std::move(protocol_interceptors)),
|
protocol_interceptors_(std::move(protocol_interceptors)),
|
||||||
job_factory_(nullptr) {
|
job_factory_(nullptr),
|
||||||
|
context_shutting_down_(false) {
|
||||||
// Must first be created on the UI thread.
|
// Must first be created on the UI thread.
|
||||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||||
|
|
||||||
|
@ -150,12 +151,24 @@ URLRequestContextGetter::URLRequestContextGetter(
|
||||||
URLRequestContextGetter::~URLRequestContextGetter() {
|
URLRequestContextGetter::~URLRequestContextGetter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void URLRequestContextGetter::NotifyContextShutdownOnIO() {
|
||||||
|
context_shutting_down_ = true;
|
||||||
|
cookie_change_sub_.reset();
|
||||||
|
http_network_session_.reset();
|
||||||
|
http_auth_preferences_.reset();
|
||||||
|
host_mapping_rules_.reset();
|
||||||
|
url_request_context_.reset();
|
||||||
|
storage_.reset();
|
||||||
|
ct_delegate_.reset();
|
||||||
|
net::URLRequestContextGetter::NotifyContextShuttingDown();
|
||||||
|
}
|
||||||
|
|
||||||
void URLRequestContextGetter::OnCookieChanged(
|
void URLRequestContextGetter::OnCookieChanged(
|
||||||
const net::CanonicalCookie& cookie,
|
const net::CanonicalCookie& cookie,
|
||||||
net::CookieStore::ChangeCause cause) {
|
net::CookieStore::ChangeCause cause) {
|
||||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||||
|
|
||||||
if (!delegate_)
|
if (!delegate_ || context_shutting_down_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
|
@ -172,6 +185,9 @@ net::HostResolver* URLRequestContextGetter::host_resolver() {
|
||||||
net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
|
net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
|
||||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||||
|
|
||||||
|
if (context_shutting_down_)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
if (!url_request_context_.get()) {
|
if (!url_request_context_.get()) {
|
||||||
ct_delegate_.reset(new RequireCTDelegate);
|
ct_delegate_.reset(new RequireCTDelegate);
|
||||||
auto& command_line = *base::CommandLine::ForCurrentProcess();
|
auto& command_line = *base::CommandLine::ForCurrentProcess();
|
||||||
|
@ -342,14 +358,14 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
|
||||||
// Set up interceptors in the reverse order.
|
// Set up interceptors in the reverse order.
|
||||||
std::unique_ptr<net::URLRequestJobFactory> top_job_factory =
|
std::unique_ptr<net::URLRequestJobFactory> top_job_factory =
|
||||||
std::move(job_factory);
|
std::move(job_factory);
|
||||||
content::URLRequestInterceptorScopedVector::reverse_iterator it;
|
if (!protocol_interceptors_.empty()) {
|
||||||
for (it = protocol_interceptors_.rbegin();
|
for (auto it = protocol_interceptors_.rbegin();
|
||||||
it != protocol_interceptors_.rend();
|
it != protocol_interceptors_.rend(); ++it) {
|
||||||
++it) {
|
top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
|
||||||
top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
|
std::move(top_job_factory), std::move(*it)));
|
||||||
std::move(top_job_factory), std::move(*it)));
|
}
|
||||||
|
protocol_interceptors_.clear();
|
||||||
}
|
}
|
||||||
protocol_interceptors_.clear();
|
|
||||||
|
|
||||||
storage_->set_job_factory(std::move(top_job_factory));
|
storage_->set_job_factory(std::move(top_job_factory));
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,10 @@
|
||||||
#include "net/url_request/url_request_context.h"
|
#include "net/url_request/url_request_context.h"
|
||||||
#include "net/url_request/url_request_context_getter.h"
|
#include "net/url_request/url_request_context_getter.h"
|
||||||
|
|
||||||
|
#if DCHECK_IS_ON()
|
||||||
|
#include "base/debug/leak_tracker.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
class MessageLoop;
|
class MessageLoop;
|
||||||
}
|
}
|
||||||
|
@ -83,6 +87,8 @@ class URLRequestContextGetter : public net::URLRequestContextGetter {
|
||||||
net::HostResolver* host_resolver();
|
net::HostResolver* host_resolver();
|
||||||
net::URLRequestJobFactory* job_factory() const { return job_factory_; }
|
net::URLRequestJobFactory* job_factory() const { return job_factory_; }
|
||||||
|
|
||||||
|
void NotifyContextShutdownOnIO();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Delegate* delegate_;
|
Delegate* delegate_;
|
||||||
|
|
||||||
|
@ -93,6 +99,10 @@ class URLRequestContextGetter : public net::URLRequestContextGetter {
|
||||||
|
|
||||||
std::string user_agent_;
|
std::string user_agent_;
|
||||||
|
|
||||||
|
#if DCHECK_IS_ON()
|
||||||
|
base::debug::LeakTracker<URLRequestContextGetter> leak_tracker_;
|
||||||
|
#endif
|
||||||
|
|
||||||
std::unique_ptr<RequireCTDelegate> ct_delegate_;
|
std::unique_ptr<RequireCTDelegate> ct_delegate_;
|
||||||
std::unique_ptr<net::ProxyConfigService> proxy_config_service_;
|
std::unique_ptr<net::ProxyConfigService> proxy_config_service_;
|
||||||
std::unique_ptr<net::URLRequestContextStorage> storage_;
|
std::unique_ptr<net::URLRequestContextStorage> storage_;
|
||||||
|
@ -107,6 +117,8 @@ class URLRequestContextGetter : public net::URLRequestContextGetter {
|
||||||
|
|
||||||
net::URLRequestJobFactory* job_factory_; // weak ref
|
net::URLRequestJobFactory* job_factory_; // weak ref
|
||||||
|
|
||||||
|
bool context_shutting_down_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter);
|
DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue