From 3e1edfc9d0e7098458987861c650142b1142b631 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 22 Dec 2015 23:46:25 +0800 Subject: [PATCH] Cancel callback in OnComplete event --- atom/browser/net/atom_network_delegate.cc | 59 ++++++++++++----------- atom/browser/net/atom_network_delegate.h | 12 ++++- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/atom/browser/net/atom_network_delegate.cc b/atom/browser/net/atom_network_delegate.cc index f12911f286e3..228cb5828ec8 100644 --- a/atom/browser/net/atom_network_delegate.cc +++ b/atom/browser/net/atom_network_delegate.cc @@ -185,32 +185,6 @@ void ReadFromResponseObject(const base::DictionaryValue& response, } } -// Deal with the results of Listener. -template -void OnListenerResultInIO(const net::CompletionCallback& callback, - T out, - scoped_ptr response) { - // The request has been destroyed. - if (callback.is_null()) - return; - - ReadFromResponseObject(*response.get(), out); - - bool cancel = false; - response->GetBoolean("cancel", &cancel); - callback.Run(cancel ? net::ERR_BLOCKED_BY_CLIENT : net::OK); -} - -template -void OnListenerResultInUI(const net::CompletionCallback& callback, - T out, - const base::DictionaryValue& response) { - scoped_ptr copy = response.CreateDeepCopy(); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::Bind(OnListenerResultInIO, callback, out, base::Passed(©))); -} - } // namespace AtomNetworkDelegate::AtomNetworkDelegate() { @@ -313,6 +287,9 @@ void AtomNetworkDelegate::OnResponseStarted(net::URLRequest* request) { } void AtomNetworkDelegate::OnCompleted(net::URLRequest* request, bool started) { + // OnCompleted may happen before other events. + callbacks_.erase(request->identifier()); + if (request->status().status() == net::URLRequestStatus::FAILED || request->status().status() == net::URLRequestStatus::CANCELED) { // Error event. @@ -365,11 +342,11 @@ int AtomNetworkDelegate::HandleResponseEvent( FillDetailsObject(details.get(), request, args...); // The |request| could be destroyed before the |callback| is called. - callbacks_[request->identifier()].Reset(callback); - const auto& cancelable = callbacks_[request->identifier()].callback(); + callbacks_[request->identifier()] = callback; ResponseCallback response = - base::Bind(OnListenerResultInUI, cancelable, out); + base::Bind(&AtomNetworkDelegate::OnListenerResultInUI, + base::Unretained(this), request->identifier(), out); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(RunResponseListener, info.listener, base::Passed(&details), @@ -392,4 +369,28 @@ void AtomNetworkDelegate::HandleSimpleEvent( base::Bind(RunSimpleListener, info.listener, base::Passed(&details))); } +template +void AtomNetworkDelegate::OnListenerResultInIO( + uint64_t id, T out, scoped_ptr response) { + // The request has been destroyed. + if (!ContainsKey(callbacks_, id)) + return; + + ReadFromResponseObject(*response.get(), out); + + bool cancel = false; + response->GetBoolean("cancel", &cancel); + callbacks_[id].Run(cancel ? net::ERR_BLOCKED_BY_CLIENT : net::OK); +} + +template +void AtomNetworkDelegate::OnListenerResultInUI( + uint64_t id, T out, const base::DictionaryValue& response) { + scoped_ptr copy = response.CreateDeepCopy(); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&AtomNetworkDelegate::OnListenerResultInIO, + base::Unretained(this), id, out, base::Passed(©))); +} + } // namespace atom diff --git a/atom/browser/net/atom_network_delegate.h b/atom/browser/net/atom_network_delegate.h index 579f33f6d7ad..4f55f7c09863 100644 --- a/atom/browser/net/atom_network_delegate.h +++ b/atom/browser/net/atom_network_delegate.h @@ -9,7 +9,7 @@ #include #include "brightray/browser/network_delegate.h" -#include "base/cancelable_callback.h" +#include "base/callback.h" #include "base/values.h" #include "extensions/common/url_pattern.h" #include "net/base/net_errors.h" @@ -101,9 +101,17 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate { Out out, Args... args); + // Deal with the results of Listener. + template + void OnListenerResultInIO( + uint64_t id, T out, scoped_ptr response); + template + void OnListenerResultInUI( + uint64_t id, T out, const base::DictionaryValue& response); + std::map simple_listeners_; std::map response_listeners_; - std::map> callbacks_; + std::map callbacks_; DISALLOW_COPY_AND_ASSIGN(AtomNetworkDelegate); };