Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Unified Diff: content/browser/cancelable_request.h

Issue 8068013: Add interface to CancelableRequest that allows use of base::Callback<>. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address brett's comments. Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/ui/webui/fileicon_source.cc ('k') | content/browser/cancelable_request.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/cancelable_request.h
diff --git a/content/browser/cancelable_request.h b/content/browser/cancelable_request.h
index a9e6f4fccef39e15db3564d3b7f24bfc4a2245bd..f614cbcd3662996b683b999b21281b1a1884b835 100644
--- a/content/browser/cancelable_request.h
+++ b/content/browser/cancelable_request.h
@@ -91,6 +91,7 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
@@ -565,6 +566,10 @@ class CONTENT_EXPORT CancelableRequestBase
CancelableRequestProvider::Handle handle,
CancelableRequestConsumerBase* consumer);
+ // Attempts to execute callback on |callback_thread_| if the request has not
+ // been canceled yet.
+ void DoForward(const base::Closure& forwarded_call, bool force_async);
+
// Tells the provider that the request is complete, which then tells the
// consumer.
void NotifyCompleted() const {
@@ -599,6 +604,11 @@ class CONTENT_EXPORT CancelableRequestBase
base::CancellationFlag canceled_;
private:
+ // Executes the |forwarded_call| and notifies the provider and the consumer
+ // that this request has been completed. This must be called on the
+ // |callback_thread_|.
+ void ExecuteCallback(const base::Closure& forwarded_call);
+
DISALLOW_COPY_AND_ASSIGN(CancelableRequestBase);
};
@@ -631,6 +641,8 @@ class CONTENT_EXPORT CancelableRequestBase
template<typename CB>
class CancelableRequest : public CancelableRequestBase {
public:
+ // TODO(ajwong): After all calls have been migrated, remove this template in
+ // favor of the specialization on base::Callback<Sig>.
typedef CB CallbackType; // CallbackRunner<...>
typedef typename CB::TupleType TupleType; // Tuple of the callback args.
@@ -700,6 +712,235 @@ class CancelableRequest : public CancelableRequestBase {
scoped_ptr<CallbackType> callback_;
};
+// CancelableRequest<> wraps a normal base::Callback<> for use in the
+// CancelableRequest framework.
+//
+// When using this class, the provider MUST call Init() (on the base class)
+// before this is valid.
+//
+// The two functions ForwardResult(), and ForwardResultAsync() are used to
+// invoke the wrapped callback on the correct thread. They are the same
+// except that ForwardResult() will run the callback synchronously if
+// we are already on the right thread.
+//
+// The caller does not need to check for cancel before calling ForwardResult()
+// or ForwardResultAsync(). If the request has not been canceled, one of the
+// these MUST be called.
+//
+// If there are any pointers in the parameters, they must live at least as
+// long as the request so that it can be forwarded to the other thread.
+// For complex objects, this would typically be done by having a derived
+// request own the data itself.
+//
+// The following specializations handle different arities of base::Callbacks<>.
+template<>
+class CancelableRequest<base::Closure> : public CancelableRequestBase {
+ public:
+ typedef base::Closure CallbackType;
+
+ explicit CancelableRequest(const CallbackType& callback)
+ : CancelableRequestBase(),
+ callback_(callback) {
+ DCHECK(!callback.is_null()) << "Callback must be initialized.";
+ }
+
+ void ForwardResult(void) {
+ if (canceled()) return;
+ DoForward(callback_, false);
+ }
+
+ void ForwardResultAsync() {
+ if (canceled()) return;
+ DoForward(callback_, true);
+ }
+
+ protected:
+ virtual ~CancelableRequest() {}
+
+ private:
+ CallbackType callback_;
+};
+
+template<typename A1>
+class CancelableRequest<base::Callback<void(A1)> > :
+ public CancelableRequestBase {
+ public:
+ typedef base::Callback<void(A1)> CallbackType;
+
+ explicit CancelableRequest(const CallbackType& callback)
+ : CancelableRequestBase(),
+ callback_(callback) {
+ DCHECK(!callback.is_null()) << "Callback must be initialized.";
+ }
+
+ void ForwardResult(const A1& a1) {
+ if (canceled()) return;
+ DoForward(base::Bind(callback_, a1), false);
+ }
+
+ void ForwardResultAsync(const A1& a1) {
+ if (canceled()) return;
+ DoForward(base::Bind(callback_, a1), true);
+ }
+
+ protected:
+ virtual ~CancelableRequest() {}
+
+ private:
+ CallbackType callback_;
+};
+
+template<typename A1, typename A2>
+class CancelableRequest<base::Callback<void(A1,A2)> > :
+ public CancelableRequestBase {
+ public:
+ typedef base::Callback<void(A1,A2)> CallbackType;
+
+ explicit CancelableRequest(const CallbackType& callback)
+ : CancelableRequestBase(),
+ callback_(callback) {
+ DCHECK(!callback.is_null()) << "Callback must be initialized.";
+ }
+
+ void ForwardResult(const A1& a1, const A2& a2) {
+ if (canceled()) return;
+ DoForward(base::Bind(callback_, a1, a2), false);
+ }
+
+ void ForwardResultAsync(const A1& a1, const A2& a2) {
+ if (canceled()) return;
+ DoForward(base::Bind(callback_, a1, a2), true);
+ }
+
+ protected:
+ virtual ~CancelableRequest() {}
+
+ private:
+ CallbackType callback_;
+};
+
+template<typename A1, typename A2, typename A3>
+class CancelableRequest<base::Callback<void(A1,A2,A3)> > :
+ public CancelableRequestBase {
+ public:
+ typedef base::Callback<void(A1,A2,A3)> CallbackType;
+
+ explicit CancelableRequest(const CallbackType& callback)
+ : CancelableRequestBase(),
+ callback_(callback) {
+ DCHECK(!callback.is_null()) << "Callback must be initialized.";
+ }
+
+ void ForwardResult(const A1& a1, const A2& a2, const A3& a3) {
+ if (canceled()) return;
+ DoForward(base::Bind(callback_, a1, a2, a3), false);
+ }
+
+ void ForwardResultAsync(const A1& a1, const A2& a2, const A3& a3) {
+ if (canceled()) return;
+ DoForward(base::Bind(callback_, a1, a2, a3), true);
+ }
+
+ protected:
+ virtual ~CancelableRequest() {}
+
+ private:
+ CallbackType callback_;
+};
+
+template<typename A1, typename A2, typename A3, typename A4>
+class CancelableRequest<base::Callback<void(A1, A2, A3, A4)> > :
+ public CancelableRequestBase {
+ public:
+ typedef base::Callback<void(A1, A2, A3, A4)> CallbackType;
+
+ explicit CancelableRequest(const CallbackType& callback)
+ : CancelableRequestBase(),
+ callback_(callback) {
+ DCHECK(!callback.is_null()) << "Callback must be initialized.";
+ }
+
+ void ForwardResult(const A1& a1, const A2& a2, const A3& a3, const A4& a4) {
+ if (canceled()) return;
+ DoForward(base::Bind(callback_, a1, a2, a3, a4), false);
+ }
+
+ void ForwardResultAsync(const A1& a1, const A2& a2, const A3& a3,
+ const A4& a4) {
+ if (canceled()) return;
+ DoForward(base::Bind(callback_, a1, a2, a3, a4), true);
+ }
+
+ protected:
+ virtual ~CancelableRequest() {}
+
+ private:
+ CallbackType callback_;
+};
+
+template<typename A1, typename A2, typename A3, typename A4, typename A5>
+class CancelableRequest<base::Callback<void(A1, A2, A3, A4, A5)> > :
+ public CancelableRequestBase {
+ public:
+ typedef base::Callback<void(A1, A2, A3, A4, A5)> CallbackType;
+
+ explicit CancelableRequest(const CallbackType& callback)
+ : CancelableRequestBase(),
+ callback_(callback) {
+ DCHECK(!callback.is_null()) << "Callback must be initialized.";
+ }
+
+ void ForwardResult(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
+ const A5& a5) {
+ if (canceled()) return;
+ DoForward(base::Bind(callback_, a1, a2, a3, a4, a5), false);
+ }
+
+ void ForwardResultAsync(const A1& a1, const A2& a2, const A3& a3,
+ const A4& a4, const A5& a5) {
+ if (canceled()) return;
+ DoForward(base::Bind(callback_, a1, a2, a3, a4, a5), true);
+ }
+
+ protected:
+ virtual ~CancelableRequest() {}
+
+ private:
+ CallbackType callback_;
+};
+
+template<typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6>
+class CancelableRequest<base::Callback<void(A1, A2, A3, A4, A5, A6)> > :
+ public CancelableRequestBase {
+ public:
+ typedef base::Callback<void(A1, A2, A3, A4, A5, A6)> CallbackType;
+
+ explicit CancelableRequest(const CallbackType& callback)
+ : CancelableRequestBase(),
+ callback_(callback) {
+ DCHECK(!callback.is_null()) << "Callback must be initialized.";
+ }
+
+ void ForwardResult(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
+ const A5& a5, const A6& a6) {
+ if (canceled()) return;
+ DoForward(base::Bind(callback_, a1, a2, a3, a4, a5, a6), false);
+ }
+
+ void ForwardResultAsync(const A1& a1, const A2& a2, const A3& a3,
+ const A4& a4, const A5& a5, const A6& a6) {
+ if (canceled()) return;
+ DoForward(base::Bind(callback_, a1, a2, a3, a4, a5, a6), true);
+ }
+
+ protected:
+ virtual ~CancelableRequest() {}
+
+ private:
+ CallbackType callback_;
+};
+
// A CancelableRequest with a single value. This is intended for use when
// the provider provides a single value. The provider fills the result into
// the value, and notifies the request with a pointer to the value. For example,
« no previous file with comments | « chrome/browser/ui/webui/fileicon_source.cc ('k') | content/browser/cancelable_request.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698