1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // CancelableRequestProviders and Consumers work together to make requests that
6 // execute on a background thread in the provider and return data to the
7 // consumer. These classes collaborate to keep a list of open requests and to
8 // make sure that requests do not outlive either of the objects involved in the
11 // If you do not need to return data to the consumer, do not use this system,
12 // just use the regular Task/RunnableMethod stuff.
14 // The CancelableRequest object is used internally to each provider to track
15 // request data and callback information.
17 // Example consumer calling |StartRequest| on a frontend service:
20 // void MakeRequest() {
21 // frontend_service->StartRequest(
22 // some_input1, some_input2,
23 // &callback_consumer_,
24 // base::Bind(&MyClass:RequestComplete, base::Unretained(this)));
25 // // StartRequest() returns a Handle which may be retained for use with
26 // // CancelRequest() if required, e.g. in MyClass's destructor.
29 // void RequestComplete(int status) {
34 // CancelableRequestConsumer callback_consumer_;
38 // Example frontend provider. It receives requests and forwards them to the
39 // backend on another thread:
41 // class Frontend : public CancelableRequestProvider {
42 // typedef Callback1<int>::Type RequestCallbackType;
44 // Handle StartRequest(int some_input1, int some_input2,
45 // CancelableRequestConsumerBase* consumer,
46 // RequestCallbackType* callback) {
47 // scoped_refptr<CancelableRequest<RequestCallbackType> > request(
48 // new CancelableRequest<RequestCallbackType>(callback));
49 // AddRequest(request, consumer);
51 // // Send the parameters and the request to the backend thread.
52 // backend_thread_->PostTask(
54 // base::Bind(&Backend::DoRequest, backend_, request,
55 // some_input1, some_input2));
57 // // The handle will have been set by AddRequest.
58 // return request->handle();
63 // Example backend provider that does work and dispatches the callback back
64 // to the original thread. Note that we need to pass it as a scoped_refptr so
65 // that the object will be kept alive if the request is canceled (releasing
66 // the provider's reference to it).
70 // scoped_refptr< CancelableRequest<Frontend::RequestCallbackType> >
72 // int some_input1, int some_input2) {
73 // if (request->canceled())
76 // ... do your processing ...
78 // // Depending on your typedefs, one of these two forms will be more
80 // request->ForwardResult(Tuple1<int>(return_value));
82 // // -- or -- (inferior in this case)
83 // request->ForwardResult(Frontend::RequestCallbackType::TupleType(
88 #ifndef CHROME_BROWSER_COMMON_CANCELABLE_REQUEST_H_
89 #define CHROME_BROWSER_COMMON_CANCELABLE_REQUEST_H_
94 #include "base/basictypes.h"
95 #include "base/bind.h"
96 #include "base/callback.h"
97 #include "base/callback_internal.h"
98 #include "base/logging.h"
99 #include "base/memory/ref_counted.h"
100 #include "base/memory/scoped_ptr.h"
101 #include "base/message_loop.h"
102 #include "base/synchronization/cancellation_flag.h"
103 #include "base/synchronization/lock.h"
104 #include "build/build_config.h"
106 class CancelableRequestBase
;
107 class CancelableRequestConsumerBase
;
109 // CancelableRequestProvider --------------------------------------------------
111 // This class is threadsafe. Requests may be added or canceled from any thread,
112 // but a task must only be canceled from the same thread it was initially run
115 // It is intended that providers inherit from this class to provide the
116 // necessary functionality.
118 class CancelableRequestProvider
{
120 // Identifies a specific request from this provider.
123 CancelableRequestProvider();
125 // Called by the enduser of the request to cancel it. This MUST be called on
126 // the same thread that originally issued the request (which is also the same
127 // thread that would have received the callback if it was not canceled).
128 // handle must be for a valid pending (not yet complete or cancelled) request.
129 void CancelRequest(Handle handle
);
132 virtual ~CancelableRequestProvider();
134 // Adds a new request and initializes it. This is called by a derived class
135 // to add a new request. The request's Init() will be called (which is why
136 // the consumer is required. The handle to the new request is returned.
137 Handle
AddRequest(CancelableRequestBase
* request
,
138 CancelableRequestConsumerBase
* consumer
);
140 // Called by the CancelableRequest when the request has executed. It will
141 // be removed from the list of pending requests (as opposed to canceling,
142 // which will also set some state on the request).
143 void RequestCompleted(Handle handle
);
146 typedef std::map
<Handle
, scoped_refptr
<CancelableRequestBase
> >
147 CancelableRequestMap
;
149 // Only call this when you already have acquired pending_request_lock_.
150 void CancelRequestLocked(const CancelableRequestMap::iterator
& item
);
152 friend class CancelableRequestBase
;
154 base::Lock pending_request_lock_
;
156 // Lists all outstanding requests. Protected by the |lock_|.
157 CancelableRequestMap pending_requests_
;
159 // The next handle value we will return. Protected by the |lock_|.
162 DISALLOW_COPY_AND_ASSIGN(CancelableRequestProvider
);
165 // CancelableRequestConsumer --------------------------------------------------
167 // Classes wishing to make requests on a provider should have an instance of
168 // this class. Callers will need to pass a pointer to this consumer object
169 // when they make the request. It will automatically track any pending
170 // requests, and will automatically cancel them on destruction to prevent the
171 // accidental calling of freed memory.
173 // It is recommended to just have this class as a member variable since there
174 // is nothing to be gained by inheriting from it other than polluting your
177 // THIS CLASS IS NOT THREADSAFE (unlike the provider). You must make requests
178 // and get callbacks all from the same thread.
180 // Base class used to notify of new requests.
181 class CancelableRequestConsumerBase
{
183 friend class CancelableRequestBase
;
184 friend class CancelableRequestProvider
;
186 virtual ~CancelableRequestConsumerBase() {
189 // Adds a new request to the list of requests that are being tracked. This
190 // is called by the provider when a new request is created.
191 virtual void OnRequestAdded(CancelableRequestProvider
* provider
,
192 CancelableRequestProvider::Handle handle
) = 0;
194 // Removes the given request from the list of pending requests. Called
195 // by the CancelableRequest immediately after the callback has executed for a
196 // given request, and by the provider when a request is canceled.
197 virtual void OnRequestRemoved(CancelableRequestProvider
* provider
,
198 CancelableRequestProvider::Handle handle
) = 0;
200 // Sent to provider before executing a callback.
201 virtual void WillExecute(CancelableRequestProvider
* provider
,
202 CancelableRequestProvider::Handle handle
) = 0;
204 // Sent after executing a callback.
205 virtual void DidExecute(CancelableRequestProvider
* provider
,
206 CancelableRequestProvider::Handle handle
) = 0;
209 // Template for clients to use. It allows them to associate random "client
210 // data" with a specific request. The default value for this type is 0.
211 // The type T should be small and easily copyable (like a pointer
214 class CancelableRequestConsumerTSimple
215 : public CancelableRequestConsumerBase
{
217 CancelableRequestConsumerTSimple();
219 // Cancel any outstanding requests so that we do not get called back after we
220 // are destroyed. As these requests are removed, the providers will call us
221 // back on OnRequestRemoved, which will then update the list. To iterate
222 // successfully while the list is changing out from under us, we make a copy.
223 virtual ~CancelableRequestConsumerTSimple();
225 // Associates some random data with a specified request. The request MUST be
226 // outstanding, or it will assert. This is intended to be called immediately
227 // after a request is issued.
228 void SetClientData(CancelableRequestProvider
* p
,
229 CancelableRequestProvider::Handle h
,
232 // Retrieves previously associated data for a specified request. The request
233 // MUST be outstanding, or it will assert. This is intended to be called
234 // during processing of a callback to retrieve extra data.
235 T
GetClientData(CancelableRequestProvider
* p
,
236 CancelableRequestProvider::Handle h
);
238 // Returns the data associated with the current request being processed. This
239 // is only valid during the time a callback is being processed.
240 T
GetClientDataForCurrentRequest();
242 // Returns true if there are any pending requests.
243 bool HasPendingRequests() const;
245 // Returns the number of pending requests.
246 size_t PendingRequestCount() const;
248 // Cancels all requests outstanding.
249 void CancelAllRequests();
251 // Cancels all requests outstanding matching the client data.
252 void CancelAllRequestsForClientData(T client_data
);
254 // Returns the handle for the first request that has the specified client data
255 // (in |handle|). Returns true if there is a request for the specified client
256 // data, false otherwise.
257 bool GetFirstHandleForClientData(T client_data
,
258 CancelableRequestProvider::Handle
* handle
);
260 // Gets the client data for all pending requests.
261 void GetAllClientData(std::vector
<T
>* data
);
264 struct PendingRequest
{
265 PendingRequest(CancelableRequestProvider
* p
,
266 CancelableRequestProvider::Handle h
)
267 : provider(p
), handle(h
) {
270 PendingRequest() : provider(NULL
), handle(0) {}
272 // Comparison operator for stl.
273 bool operator<(const PendingRequest
& other
) const {
274 if (provider
!= other
.provider
)
275 return provider
< other
.provider
;
276 return handle
< other
.handle
;
279 bool is_valid() const { return provider
!= NULL
; }
281 CancelableRequestProvider
* provider
;
282 CancelableRequestProvider::Handle handle
;
284 typedef std::map
<PendingRequest
, T
> PendingRequestList
;
286 virtual T
get_initial_t() const;
288 virtual void OnRequestAdded(CancelableRequestProvider
* provider
,
289 CancelableRequestProvider::Handle handle
);
291 virtual void OnRequestRemoved(CancelableRequestProvider
* provider
,
292 CancelableRequestProvider::Handle handle
);
294 virtual void WillExecute(CancelableRequestProvider
* provider
,
295 CancelableRequestProvider::Handle handle
);
297 virtual void DidExecute(CancelableRequestProvider
* provider
,
298 CancelableRequestProvider::Handle handle
);
300 // Lists all outstanding requests.
301 PendingRequestList pending_requests_
;
303 // This is valid while processing a request and is used to identify the
304 // provider/handle of request.
305 PendingRequest current_request_
;
309 CancelableRequestConsumerTSimple
<T
>::CancelableRequestConsumerTSimple() {
313 CancelableRequestConsumerTSimple
<T
>::~CancelableRequestConsumerTSimple() {
318 void CancelableRequestConsumerTSimple
<T
>::SetClientData(
319 CancelableRequestProvider
* p
,
320 CancelableRequestProvider::Handle h
,
322 PendingRequest
request(p
, h
);
323 DCHECK(pending_requests_
.find(request
) != pending_requests_
.end());
324 pending_requests_
[request
] = client_data
;
328 T CancelableRequestConsumerTSimple
<T
>::GetClientData(
329 CancelableRequestProvider
* p
,
330 CancelableRequestProvider::Handle h
) {
331 PendingRequest
request(p
, h
);
332 DCHECK(pending_requests_
.find(request
) != pending_requests_
.end());
333 return pending_requests_
[request
];
337 T CancelableRequestConsumerTSimple
<T
>::GetClientDataForCurrentRequest() {
338 DCHECK(current_request_
.is_valid());
339 return GetClientData(current_request_
.provider
, current_request_
.handle
);
343 bool CancelableRequestConsumerTSimple
<T
>::HasPendingRequests() const {
344 return !pending_requests_
.empty();
348 size_t CancelableRequestConsumerTSimple
<T
>::PendingRequestCount() const {
349 return pending_requests_
.size();
353 void CancelableRequestConsumerTSimple
<T
>::CancelAllRequests() {
354 // TODO(atwilson): This code is not thread safe as it is called from the
355 // consumer thread (via the destructor) and accesses pending_requests_
356 // without acquiring the provider lock (http://crbug.com/85970).
357 PendingRequestList
copied_requests(pending_requests_
);
358 for (typename
PendingRequestList::iterator i
= copied_requests
.begin();
359 i
!= copied_requests
.end(); ++i
) {
360 i
->first
.provider
->CancelRequest(i
->first
.handle
);
362 copied_requests
.clear();
364 // That should have cleared all the pending items.
365 DCHECK(pending_requests_
.empty());
369 void CancelableRequestConsumerTSimple
<T
>::CancelAllRequestsForClientData(
371 PendingRequestList
copied_requests(pending_requests_
);
372 for (typename
PendingRequestList::const_iterator i
= copied_requests
.begin();
373 i
!= copied_requests
.end(); ++i
) {
374 if (i
->second
== client_data
)
375 i
->first
.provider
->CancelRequest(i
->first
.handle
);
377 copied_requests
.clear();
381 bool CancelableRequestConsumerTSimple
<T
>::GetFirstHandleForClientData(
383 CancelableRequestProvider::Handle
* handle
) {
384 for (typename
PendingRequestList::const_iterator i
=
385 pending_requests_
.begin(); i
!= pending_requests_
.end(); ++i
) {
386 if (i
->second
== client_data
) {
387 *handle
= i
->first
.handle
;
396 void CancelableRequestConsumerTSimple
<T
>::GetAllClientData(
397 std::vector
<T
>* data
) {
399 for (typename
PendingRequestList::iterator i
= pending_requests_
.begin();
400 i
!= pending_requests_
.end(); ++i
)
401 data
->push_back(i
->second
);
405 T CancelableRequestConsumerTSimple
<T
>::get_initial_t() const {
410 void CancelableRequestConsumerTSimple
<T
>::OnRequestAdded(
411 CancelableRequestProvider
* provider
,
412 CancelableRequestProvider::Handle handle
) {
413 // Make sure we're not mixing/matching providers (since the provider is
414 // responsible for providing thread safety until http://crbug.com/85970 is
415 // fixed, we can't use the same consumer with multiple providers).
417 if (!pending_requests_
.empty())
418 DCHECK(pending_requests_
.begin()->first
.provider
== provider
);
420 DCHECK(pending_requests_
.find(PendingRequest(provider
, handle
)) ==
421 pending_requests_
.end());
422 pending_requests_
[PendingRequest(provider
, handle
)] = get_initial_t();
426 void CancelableRequestConsumerTSimple
<T
>::OnRequestRemoved(
427 CancelableRequestProvider
* provider
,
428 CancelableRequestProvider::Handle handle
) {
429 typename
PendingRequestList::iterator i
=
430 pending_requests_
.find(PendingRequest(provider
, handle
));
431 if (i
== pending_requests_
.end()) {
432 NOTREACHED() << "Got a complete notification for a nonexistent request";
436 pending_requests_
.erase(i
);
440 void CancelableRequestConsumerTSimple
<T
>::WillExecute(
441 CancelableRequestProvider
* provider
,
442 CancelableRequestProvider::Handle handle
) {
443 current_request_
= PendingRequest(provider
, handle
);
447 void CancelableRequestConsumerTSimple
<T
>::DidExecute(
448 CancelableRequestProvider
* provider
,
449 CancelableRequestProvider::Handle handle
) {
450 current_request_
= PendingRequest();
453 // See CancelableRequestConsumerTSimple. The default value for T
454 // is given in |initial_t|.
455 template<class T
, T initial_t
>
456 class CancelableRequestConsumerT
457 : public CancelableRequestConsumerTSimple
<T
> {
459 CancelableRequestConsumerT();
460 virtual ~CancelableRequestConsumerT();
463 virtual T
get_initial_t() const;
466 template<class T
, T initial_t
>
467 CancelableRequestConsumerT
<T
, initial_t
>::CancelableRequestConsumerT() {
470 template<class T
, T initial_t
>
471 CancelableRequestConsumerT
<T
, initial_t
>::~CancelableRequestConsumerT() {
474 template<class T
, T initial_t
>
475 T CancelableRequestConsumerT
<T
, initial_t
>::get_initial_t() const {
479 // Some clients may not want to store data. Rather than do some complicated
480 // thing with virtual functions to allow some consumers to store extra data and
481 // some not to, we just define a default one that stores some dummy data.
482 typedef CancelableRequestConsumerT
<int, 0> CancelableRequestConsumer
;
484 // MSVC doesn't like complex extern templates and DLLs.
485 #if !defined(COMPILER_MSVC)
486 // The vast majority of CancelableRequestConsumers are instantiated on <int>,
487 // so prevent that template from being expanded in normal code.
488 extern template class CancelableRequestConsumerTSimple
<int>;
490 // We'll also want to extern-template the most common, typedef-ed
491 // CancelableRequestConsumerT.
492 extern template class CancelableRequestConsumerT
<int, 0>;
495 // CancelableRequest ----------------------------------------------------------
497 // The request object that is used by a CancelableRequestProvider to send
498 // results to a CancelableRequestConsumer. This request handles the returning
499 // of results from a thread where the request is being executed to the thread
500 // and callback where the results are used. IT SHOULD BE PASSED AS A
501 // scoped_refptr TO KEEP IT ALIVE.
503 // It does not handle input parameters to the request. The caller must either
504 // transfer those separately or derive from this class to add the desired
507 // When the processing is complete on this message, the caller MUST call
508 // ForwardResult() with the return arguments that will be passed to the
509 // callback. If the request has been canceled, Return is optional (it will not
510 // do anything). If you do not have to return to the caller, the cancelable
511 // request system should not be used! (just use regular fire-and-forget tasks).
513 // Callback parameters are passed by value. In some cases, the request will
514 // want to return a large amount of data (for example, an image). One good
515 // approach is to derive from the CancelableRequest and make the data object
516 // (for example, a std::vector) owned by the CancelableRequest. The pointer
517 // to this data would be passed for the callback parameter. Since the
518 // CancelableRequest outlives the callback call, the data will be valid on the
519 // other thread for the callback, but will still be destroyed properly.
521 // Non-templatized base class that provides cancellation
522 class CancelableRequestBase
523 : public base::RefCountedThreadSafe
<CancelableRequestBase
> {
525 friend class CancelableRequestProvider
;
527 // Initializes most things to empty, Init() must be called to complete
528 // initialization of the object. This will be done by the provider when the
529 // request is dispatched.
531 // This must be called on the same thread the callback will be executed on, it
532 // will save that thread for later.
534 // This two-phase init is done so that the constructor can have no parameters,
535 // which makes it much more convenient for derived classes, which can be
536 // common. The derived classes need only declare the variables they provide in
537 // the constructor rather than many lines of internal tracking data that are
538 // passed to the base class (us).
540 // In addition, not all of the information (for example, the handle) is known
541 // at construction time.
542 CancelableRequestBase();
544 CancelableRequestConsumerBase
* consumer() const {
548 CancelableRequestProvider::Handle
handle() const {
552 // The canceled flag indicates that the request should not be executed.
553 // A request can never be uncanceled, so only a setter for true is provided.
554 // This can be called multiple times, but only from one thread.
555 void set_canceled() {
559 return canceled_
.IsSet();
563 friend class base::RefCountedThreadSafe
<CancelableRequestBase
>;
564 virtual ~CancelableRequestBase();
566 // Initializes the object with the particulars from the provider. It may only
567 // be called once (it is called by the provider, which is a friend).
568 void Init(CancelableRequestProvider
* provider
,
569 CancelableRequestProvider::Handle handle
,
570 CancelableRequestConsumerBase
* consumer
);
572 // Attempts to execute callback on |callback_thread_| if the request has not
573 // been canceled yet.
574 void DoForward(const base::Closure
& forwarded_call
, bool force_async
);
576 // Tells the provider that the request is complete, which then tells the
578 void NotifyCompleted() const {
579 provider_
->RequestCompleted(handle());
580 consumer_
->DidExecute(provider_
, handle_
);
583 // Cover method for CancelableRequestConsumerBase::WillExecute.
585 consumer_
->WillExecute(provider_
, handle_
);
588 // The message loop that this request was created on. The callback will
589 // happen on the same thread.
590 MessageLoop
* callback_thread_
;
592 // The provider for this request. When we execute, we will notify this that
593 // request is complete to it can remove us from the requests it tracks.
594 CancelableRequestProvider
* provider_
;
596 // Notified after we execute that the request is complete. This should only
597 // be accessed if !canceled_.IsSet(), otherwise the pointer is invalid.
598 CancelableRequestConsumerBase
* consumer_
;
600 // The handle to this request inside the provider. This will be initialized
601 // to 0 when the request is created, and the provider will set it once the
602 // request has been dispatched.
603 CancelableRequestProvider::Handle handle_
;
605 // Set if the caller cancels this request. No callbacks should be made when
607 base::CancellationFlag canceled_
;
610 // Executes the |forwarded_call| and notifies the provider and the consumer
611 // that this request has been completed. This must be called on the
612 // |callback_thread_|.
613 void ExecuteCallback(const base::Closure
& forwarded_call
);
615 DISALLOW_COPY_AND_ASSIGN(CancelableRequestBase
);
618 // Templatized class. This is the one you should use directly or inherit from.
619 // The callback can be invoked by calling the ForwardResult() method. For this,
620 // you must either pack the parameters into a tuple, or use DispatchToMethod
623 // If you inherit to add additional input parameters or to do more complex
624 // memory management (see the bigger comment about this above), you can put
625 // those on a subclass of this.
627 // We have decided to allow users to treat derived classes of this as structs,
628 // so you can add members without getters and setters (which just makes the
629 // code harder to read). Don't use underscores after these vars. For example:
631 // typedef Callback1<int>::Type DoodieCallback;
633 // class DoodieRequest : public CancelableRequest<DoodieCallback> {
635 // DoodieRequest(CallbackType* callback) : CancelableRequest(callback) {
639 // ~DoodieRequest() {}
642 // std::wstring input_arg2;
644 template<typename CB
>
645 class CancelableRequest
: public CancelableRequestBase
{
647 // TODO(ajwong): After all calls have been migrated, remove this template in
648 // favor of the specialization on base::Callback<Sig>.
649 typedef CB CallbackType
; // CallbackRunner<...>
650 typedef typename
CB::TupleType TupleType
; // Tuple of the callback args.
652 // The provider MUST call Init() (on the base class) before this is valid.
653 // This class will take ownership of the callback object and destroy it when
655 explicit CancelableRequest(CallbackType
* callback
)
656 : CancelableRequestBase(),
657 callback_(callback
) {
658 DCHECK(callback
) << "We should always have a callback";
661 // Dispatches the parameters to the correct thread so the callback can be
662 // executed there. The caller does not need to check for cancel before
663 // calling this. It is optional in the cancelled case. In the non-cancelled
664 // case, this MUST be called.
666 // If there are any pointers in the parameters, they must live at least as
667 // long as the request so that it can be forwarded to the other thread.
668 // For complex objects, this would typically be done by having a derived
669 // request own the data itself.
670 void ForwardResult(const TupleType
& param
) {
671 DCHECK(callback_
.get());
673 if (callback_thread_
== MessageLoop::current()) {
674 // We can do synchronous callbacks when we're on the same thread.
675 ExecuteCallback(param
);
677 callback_thread_
->PostTask(
679 base::Bind(&CancelableRequest
<CB
>::ExecuteCallback
, this, param
));
684 // Like |ForwardResult| but this never does a synchronous callback.
685 void ForwardResultAsync(const TupleType
& param
) {
686 DCHECK(callback_
.get());
688 callback_thread_
->PostTask(
690 base::Bind(&CancelableRequest
<CB
>::ExecuteCallback
, this, param
));
695 virtual ~CancelableRequest() {}
698 // Executes the callback and notifies the provider and the consumer that this
699 // request has been completed. This must be called on the callback_thread_.
700 void ExecuteCallback(const TupleType
& param
) {
701 if (!canceled_
.IsSet()) {
704 // Execute the callback.
705 callback_
->RunWithParams(param
);
708 // Notify the provider that the request is complete. The provider will
709 // notify the consumer for us. Note that it is possible for the callback to
710 // cancel this request; we must check canceled again.
711 if (!canceled_
.IsSet())
715 // This should only be executed if !canceled_.IsSet(),
716 // otherwise the pointers may be invalid.
717 scoped_ptr
<CallbackType
> callback_
;
720 // CancelableRequest<> wraps a normal base::Callback<> for use in the
721 // CancelableRequest framework.
723 // When using this class, the provider MUST call Init() (on the base class)
724 // before this is valid.
726 // The two functions ForwardResult(), and ForwardResultAsync() are used to
727 // invoke the wrapped callback on the correct thread. They are the same
728 // except that ForwardResult() will run the callback synchronously if
729 // we are already on the right thread.
731 // The caller does not need to check for cancel before calling ForwardResult()
732 // or ForwardResultAsync(). If the request has not been canceled, one of the
733 // these MUST be called.
735 // If there are any pointers in the parameters, they must live at least as
736 // long as the request so that it can be forwarded to the other thread.
737 // For complex objects, this would typically be done by having a derived
738 // request own the data itself.
740 // The following specializations handle different arities of base::Callbacks<>.
742 class CancelableRequest
<base::Closure
> : public CancelableRequestBase
{
744 typedef base::Closure CallbackType
;
746 explicit CancelableRequest(const CallbackType
& callback
)
747 : CancelableRequestBase(),
748 callback_(callback
) {
749 DCHECK(!callback
.is_null()) << "Callback must be initialized.";
752 void ForwardResult(void) {
753 if (canceled()) return;
754 DoForward(callback_
, false);
757 void ForwardResultAsync() {
758 if (canceled()) return;
759 DoForward(callback_
, true);
763 virtual ~CancelableRequest() {}
766 CallbackType callback_
;
769 template<typename A1
>
770 class CancelableRequest
<base::Callback
<void(A1
)> >
771 : public CancelableRequestBase
{
773 typedef base::Callback
<void(A1
)> CallbackType
;
775 explicit CancelableRequest(const CallbackType
& callback
)
776 : CancelableRequestBase(),
777 callback_(callback
) {
778 DCHECK(!callback
.is_null()) << "Callback must be initialized.";
782 typename
base::internal::CallbackParamTraits
<A1
>::ForwardType a1
) {
783 if (canceled()) return;
784 DoForward(base::Bind(callback_
, a1
), false);
787 void ForwardResultAsync(
788 typename
base::internal::CallbackParamTraits
<A1
>::ForwardType a1
) {
789 if (canceled()) return;
790 DoForward(base::Bind(callback_
, a1
), true);
794 virtual ~CancelableRequest() {}
797 CallbackType callback_
;
800 template<typename A1
, typename A2
>
801 class CancelableRequest
<base::Callback
<void(A1
,A2
)> >
802 : public CancelableRequestBase
{
804 typedef base::Callback
<void(A1
,A2
)> CallbackType
;
806 explicit CancelableRequest(const CallbackType
& callback
)
807 : CancelableRequestBase(),
808 callback_(callback
) {
809 DCHECK(!callback
.is_null()) << "Callback must be initialized.";
813 typename
base::internal::CallbackParamTraits
<A1
>::ForwardType a1
,
814 typename
base::internal::CallbackParamTraits
<A2
>::ForwardType a2
) {
815 if (canceled()) return;
816 DoForward(base::Bind(callback_
, a1
, a2
), false);
819 void ForwardResultAsync(
820 typename
base::internal::CallbackParamTraits
<A1
>::ForwardType a1
,
821 typename
base::internal::CallbackParamTraits
<A2
>::ForwardType a2
) {
822 if (canceled()) return;
823 DoForward(base::Bind(callback_
, a1
, a2
), true);
827 virtual ~CancelableRequest() {}
830 CallbackType callback_
;
833 template<typename A1
, typename A2
, typename A3
>
834 class CancelableRequest
<base::Callback
<void(A1
,A2
,A3
)> >
835 : public CancelableRequestBase
{
837 typedef base::Callback
<void(A1
,A2
,A3
)> CallbackType
;
839 explicit CancelableRequest(const CallbackType
& callback
)
840 : CancelableRequestBase(),
841 callback_(callback
) {
842 DCHECK(!callback
.is_null()) << "Callback must be initialized.";
846 typename
base::internal::CallbackParamTraits
<A1
>::ForwardType a1
,
847 typename
base::internal::CallbackParamTraits
<A2
>::ForwardType a2
,
848 typename
base::internal::CallbackParamTraits
<A3
>::ForwardType a3
) {
849 if (canceled()) return;
850 DoForward(base::Bind(callback_
, a1
, a2
, a3
), false);
853 void ForwardResultAsync(
854 typename
base::internal::CallbackParamTraits
<A1
>::ForwardType a1
,
855 typename
base::internal::CallbackParamTraits
<A2
>::ForwardType a2
,
856 typename
base::internal::CallbackParamTraits
<A3
>::ForwardType a3
) {
857 if (canceled()) return;
858 DoForward(base::Bind(callback_
, a1
, a2
, a3
), true);
862 virtual ~CancelableRequest() {}
865 CallbackType callback_
;
868 template<typename A1
, typename A2
, typename A3
, typename A4
>
869 class CancelableRequest
<base::Callback
<void(A1
, A2
, A3
, A4
)> >
870 : public CancelableRequestBase
{
872 typedef base::Callback
<void(A1
, A2
, A3
, A4
)> CallbackType
;
874 explicit CancelableRequest(const CallbackType
& callback
)
875 : CancelableRequestBase(),
876 callback_(callback
) {
877 DCHECK(!callback
.is_null()) << "Callback must be initialized.";
881 typename
base::internal::CallbackParamTraits
<A1
>::ForwardType a1
,
882 typename
base::internal::CallbackParamTraits
<A2
>::ForwardType a2
,
883 typename
base::internal::CallbackParamTraits
<A3
>::ForwardType a3
,
884 typename
base::internal::CallbackParamTraits
<A4
>::ForwardType a4
) {
885 if (canceled()) return;
886 DoForward(base::Bind(callback_
, a1
, a2
, a3
, a4
), false);
889 void ForwardResultAsync(
890 typename
base::internal::CallbackParamTraits
<A1
>::ForwardType a1
,
891 typename
base::internal::CallbackParamTraits
<A2
>::ForwardType a2
,
892 typename
base::internal::CallbackParamTraits
<A3
>::ForwardType a3
,
893 typename
base::internal::CallbackParamTraits
<A4
>::ForwardType a4
) {
894 if (canceled()) return;
895 DoForward(base::Bind(callback_
, a1
, a2
, a3
, a4
), true);
899 virtual ~CancelableRequest() {}
902 CallbackType callback_
;
905 template<typename A1
, typename A2
, typename A3
, typename A4
, typename A5
>
906 class CancelableRequest
<base::Callback
<void(A1
, A2
, A3
, A4
, A5
)> >
907 : public CancelableRequestBase
{
909 typedef base::Callback
<void(A1
, A2
, A3
, A4
, A5
)> CallbackType
;
911 explicit CancelableRequest(const CallbackType
& callback
)
912 : CancelableRequestBase(),
913 callback_(callback
) {
914 DCHECK(!callback
.is_null()) << "Callback must be initialized.";
918 typename
base::internal::CallbackParamTraits
<A1
>::ForwardType a1
,
919 typename
base::internal::CallbackParamTraits
<A2
>::ForwardType a2
,
920 typename
base::internal::CallbackParamTraits
<A3
>::ForwardType a3
,
921 typename
base::internal::CallbackParamTraits
<A4
>::ForwardType a4
,
922 typename
base::internal::CallbackParamTraits
<A5
>::ForwardType a5
) {
923 if (canceled()) return;
924 DoForward(base::Bind(callback_
, a1
, a2
, a3
, a4
, a5
), false);
927 void ForwardResultAsync(
928 typename
base::internal::CallbackParamTraits
<A1
>::ForwardType a1
,
929 typename
base::internal::CallbackParamTraits
<A2
>::ForwardType a2
,
930 typename
base::internal::CallbackParamTraits
<A3
>::ForwardType a3
,
931 typename
base::internal::CallbackParamTraits
<A4
>::ForwardType a4
,
932 typename
base::internal::CallbackParamTraits
<A5
>::ForwardType a5
) {
933 if (canceled()) return;
934 DoForward(base::Bind(callback_
, a1
, a2
, a3
, a4
, a5
), true);
938 virtual ~CancelableRequest() {}
941 CallbackType callback_
;
944 template<typename A1
, typename A2
, typename A3
, typename A4
, typename A5
,
946 class CancelableRequest
<base::Callback
<void(A1
, A2
, A3
, A4
, A5
, A6
)> >
947 : public CancelableRequestBase
{
949 typedef base::Callback
<void(A1
, A2
, A3
, A4
, A5
, A6
)> CallbackType
;
951 explicit CancelableRequest(const CallbackType
& callback
)
952 : CancelableRequestBase(),
953 callback_(callback
) {
954 DCHECK(!callback
.is_null()) << "Callback must be initialized.";
958 typename
base::internal::CallbackParamTraits
<A1
>::ForwardType a1
,
959 typename
base::internal::CallbackParamTraits
<A2
>::ForwardType a2
,
960 typename
base::internal::CallbackParamTraits
<A3
>::ForwardType a3
,
961 typename
base::internal::CallbackParamTraits
<A4
>::ForwardType a4
,
962 typename
base::internal::CallbackParamTraits
<A5
>::ForwardType a5
,
963 typename
base::internal::CallbackParamTraits
<A6
>::ForwardType a6
) {
964 if (canceled()) return;
965 DoForward(base::Bind(callback_
, a1
, a2
, a3
, a4
, a5
, a6
), false);
968 void ForwardResultAsync(
969 typename
base::internal::CallbackParamTraits
<A1
>::ForwardType a1
,
970 typename
base::internal::CallbackParamTraits
<A2
>::ForwardType a2
,
971 typename
base::internal::CallbackParamTraits
<A3
>::ForwardType a3
,
972 typename
base::internal::CallbackParamTraits
<A4
>::ForwardType a4
,
973 typename
base::internal::CallbackParamTraits
<A5
>::ForwardType a5
,
974 typename
base::internal::CallbackParamTraits
<A6
>::ForwardType a6
) {
975 if (canceled()) return;
976 DoForward(base::Bind(callback_
, a1
, a2
, a3
, a4
, a5
, a6
), true);
980 virtual ~CancelableRequest() {}
983 CallbackType callback_
;
986 // A CancelableRequest with a single value. This is intended for use when
987 // the provider provides a single value. The provider fills the result into
988 // the value, and notifies the request with a pointer to the value. For example,
989 // HistoryService has many methods that callback with a vector. Use the
990 // following pattern for this:
991 // 1. Define the callback:
992 // typedef Callback2<Handle, std::vector<Foo>*>::Type FooCallback;
993 // 2. Define the CancelableRequest1 type.
994 // typedef CancelableRequest1<FooCallback, std::vector<Foo>> FooRequest;
995 // 3. The provider method should then fill in the contents of the vector,
996 // forwarding the result like so:
997 // request->ForwardResult(FooRequest::TupleType(request->handle(),
998 // &request->value));
1000 // Tip: for passing more than one value, use a Tuple for the value.
1001 template<typename CB
, typename Type
>
1002 class CancelableRequest1
: public CancelableRequest
<CB
> {
1004 explicit CancelableRequest1(
1005 const typename CancelableRequest
<CB
>::CallbackType
& callback
)
1006 : CancelableRequest
<CB
>(callback
), value() {
1013 virtual ~CancelableRequest1() {}
1016 #endif // CHROME_BROWSER_COMMON_CANCELABLE_REQUEST_H_