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.
4
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
9// transaction.
10//
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.
13//
14// The CancelableRequest object is used internally to each provider to track
15// request data and callback information.
16//
17// Example consumer calling |StartRequest| on a frontend service:
18//
19//   class MyClass {
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.
27//     }
28//
29//     void RequestComplete(int status) {
30//       ...
31//     }
32//
33//    private:
34//     CancelableRequestConsumer callback_consumer_;
35//   };
36//
37//
38// Example frontend provider. It receives requests and forwards them to the
39// backend on another thread:
40//
41//   class Frontend : public CancelableRequestProvider {
42//     typedef Callback1<int>::Type RequestCallbackType;
43//
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);
50//
51//       // Send the parameters and the request to the backend thread.
52//       backend_thread_->PostTask(
53//           FROM_HERE,
54//           base::Bind(&Backend::DoRequest, backend_, request,
55//                             some_input1, some_input2));
56//
57//       // The handle will have been set by AddRequest.
58//       return request->handle();
59//     }
60//   };
61//
62//
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).
67//
68//   class Backend {
69//     void DoRequest(
70//         scoped_refptr< CancelableRequest<Frontend::RequestCallbackType> >
71//             request,
72//         int some_input1, int some_input2) {
73//       if (request->canceled())
74//         return;
75//
76//       ... do your processing ...
77//
78//       // Depending on your typedefs, one of these two forms will be more
79//       // convenient:
80//       request->ForwardResult(Tuple1<int>(return_value));
81//
82//       // -- or --  (inferior in this case)
83//       request->ForwardResult(Frontend::RequestCallbackType::TupleType(
84//           return_value));
85//     }
86//   };
87
88#ifndef CHROME_BROWSER_COMMON_CANCELABLE_REQUEST_H_
89#define CHROME_BROWSER_COMMON_CANCELABLE_REQUEST_H_
90
91#include <map>
92#include <vector>
93
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/message_loop.h"
102#include "base/synchronization/cancellation_flag.h"
103#include "base/synchronization/lock.h"
104#include "build/build_config.h"
105
106class CancelableRequestBase;
107class CancelableRequestConsumerBase;
108
109// CancelableRequestProvider --------------------------------------------------
110//
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
113// on.
114//
115// It is intended that providers inherit from this class to provide the
116// necessary functionality.
117
118class CancelableRequestProvider {
119 public:
120  // Identifies a specific request from this provider.
121  typedef int Handle;
122
123  CancelableRequestProvider();
124
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);
130
131 protected:
132  virtual ~CancelableRequestProvider();
133
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);
139
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);
144
145 private:
146  typedef std::map<Handle, scoped_refptr<CancelableRequestBase> >
147      CancelableRequestMap;
148
149  // Only call this when you already have acquired pending_request_lock_.
150  void CancelRequestLocked(const CancelableRequestMap::iterator& item);
151
152  friend class CancelableRequestBase;
153
154  base::Lock pending_request_lock_;
155
156  // Lists all outstanding requests. Protected by the |lock_|.
157  CancelableRequestMap pending_requests_;
158
159  // The next handle value we will return. Protected by the |lock_|.
160  int next_handle_;
161
162  DISALLOW_COPY_AND_ASSIGN(CancelableRequestProvider);
163};
164
165// CancelableRequestConsumer --------------------------------------------------
166//
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.
172//
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
175// namespace.
176//
177// THIS CLASS IS NOT THREADSAFE (unlike the provider). You must make requests
178// and get callbacks all from the same thread.
179
180// Base class used to notify of new requests.
181class CancelableRequestConsumerBase {
182 protected:
183  friend class CancelableRequestBase;
184  friend class CancelableRequestProvider;
185
186  virtual ~CancelableRequestConsumerBase() {
187  }
188
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;
193
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;
199
200  // Sent to provider before executing a callback.
201  virtual void WillExecute(CancelableRequestProvider* provider,
202                           CancelableRequestProvider::Handle handle) = 0;
203
204  // Sent after executing a callback.
205  virtual void DidExecute(CancelableRequestProvider* provider,
206                          CancelableRequestProvider::Handle handle) = 0;
207};
208
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
212// or an integer).
213template<class T>
214class CancelableRequestConsumerTSimple
215    : public CancelableRequestConsumerBase {
216 public:
217  CancelableRequestConsumerTSimple();
218
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();
224
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,
230                     T client_data);
231
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);
237
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();
241
242  // Returns true if there are any pending requests.
243  bool HasPendingRequests() const;
244
245  // Returns the number of pending requests.
246  size_t PendingRequestCount() const;
247
248  // Cancels all requests outstanding.
249  void CancelAllRequests();
250
251  // Cancels all requests outstanding matching the client data.
252  void CancelAllRequestsForClientData(T client_data);
253
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);
259
260  // Gets the client data for all pending requests.
261  void GetAllClientData(std::vector<T>* data);
262
263 protected:
264  struct PendingRequest {
265    PendingRequest(CancelableRequestProvider* p,
266                   CancelableRequestProvider::Handle h)
267        : provider(p), handle(h) {
268    }
269
270    PendingRequest() : provider(NULL), handle(0) {}
271
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;
277    }
278
279    bool is_valid() const { return provider != NULL; }
280
281    CancelableRequestProvider* provider;
282    CancelableRequestProvider::Handle handle;
283  };
284  typedef std::map<PendingRequest, T> PendingRequestList;
285
286  virtual T get_initial_t() const;
287
288  virtual void OnRequestAdded(CancelableRequestProvider* provider,
289                              CancelableRequestProvider::Handle handle);
290
291  virtual void OnRequestRemoved(CancelableRequestProvider* provider,
292                                CancelableRequestProvider::Handle handle);
293
294  virtual void WillExecute(CancelableRequestProvider* provider,
295                           CancelableRequestProvider::Handle handle);
296
297  virtual void DidExecute(CancelableRequestProvider* provider,
298                          CancelableRequestProvider::Handle handle);
299
300  // Lists all outstanding requests.
301  PendingRequestList pending_requests_;
302
303  // This is valid while processing a request and is used to identify the
304  // provider/handle of request.
305  PendingRequest current_request_;
306};
307
308template<class T>
309CancelableRequestConsumerTSimple<T>::CancelableRequestConsumerTSimple() {
310}
311
312template<class T>
313CancelableRequestConsumerTSimple<T>::~CancelableRequestConsumerTSimple() {
314  CancelAllRequests();
315}
316
317template<class T>
318void CancelableRequestConsumerTSimple<T>::SetClientData(
319    CancelableRequestProvider* p,
320    CancelableRequestProvider::Handle h,
321    T client_data) {
322  PendingRequest request(p, h);
323  DCHECK(pending_requests_.find(request) != pending_requests_.end());
324  pending_requests_[request] = client_data;
325}
326
327template<class T>
328T 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];
334}
335
336template<class T>
337T CancelableRequestConsumerTSimple<T>::GetClientDataForCurrentRequest() {
338  DCHECK(current_request_.is_valid());
339  return GetClientData(current_request_.provider, current_request_.handle);
340}
341
342template<class T>
343bool CancelableRequestConsumerTSimple<T>::HasPendingRequests() const {
344  return !pending_requests_.empty();
345}
346
347template<class T>
348size_t CancelableRequestConsumerTSimple<T>::PendingRequestCount() const {
349  return pending_requests_.size();
350}
351
352template<class T>
353void 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);
361  }
362  copied_requests.clear();
363
364  // That should have cleared all the pending items.
365  DCHECK(pending_requests_.empty());
366}
367
368template<class T>
369void CancelableRequestConsumerTSimple<T>::CancelAllRequestsForClientData(
370    T client_data) {
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);
376  }
377  copied_requests.clear();
378}
379
380template<class T>
381bool CancelableRequestConsumerTSimple<T>::GetFirstHandleForClientData(
382    T client_data,
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;
388      return true;
389    }
390  }
391  *handle = 0;
392  return false;
393}
394
395template<class T>
396void CancelableRequestConsumerTSimple<T>::GetAllClientData(
397    std::vector<T>* data) {
398  DCHECK(data);
399  for (typename PendingRequestList::iterator i = pending_requests_.begin();
400       i != pending_requests_.end(); ++i)
401    data->push_back(i->second);
402}
403
404template<class T>
405T CancelableRequestConsumerTSimple<T>::get_initial_t() const {
406  return T();
407}
408
409template<class T>
410void 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).
416#ifndef NDEBUG
417  if (!pending_requests_.empty())
418    DCHECK(pending_requests_.begin()->first.provider == provider);
419#endif
420  DCHECK(pending_requests_.find(PendingRequest(provider, handle)) ==
421         pending_requests_.end());
422  pending_requests_[PendingRequest(provider, handle)] = get_initial_t();
423}
424
425template<class T>
426void 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";
433    return;
434  }
435
436  pending_requests_.erase(i);
437}
438
439template<class T>
440void CancelableRequestConsumerTSimple<T>::WillExecute(
441    CancelableRequestProvider* provider,
442    CancelableRequestProvider::Handle handle) {
443  current_request_ = PendingRequest(provider, handle);
444}
445
446template<class T>
447void CancelableRequestConsumerTSimple<T>::DidExecute(
448    CancelableRequestProvider* provider,
449    CancelableRequestProvider::Handle handle) {
450  current_request_ = PendingRequest();
451}
452
453// See CancelableRequestConsumerTSimple. The default value for T
454// is given in |initial_t|.
455template<class T, T initial_t>
456class CancelableRequestConsumerT
457    : public CancelableRequestConsumerTSimple<T> {
458 public:
459  CancelableRequestConsumerT();
460  virtual ~CancelableRequestConsumerT();
461
462 protected:
463  virtual T get_initial_t() const;
464};
465
466template<class T, T initial_t>
467CancelableRequestConsumerT<T, initial_t>::CancelableRequestConsumerT() {
468}
469
470template<class T, T initial_t>
471CancelableRequestConsumerT<T, initial_t>::~CancelableRequestConsumerT() {
472}
473
474template<class T, T initial_t>
475T CancelableRequestConsumerT<T, initial_t>::get_initial_t() const {
476  return initial_t;
477}
478
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.
482typedef CancelableRequestConsumerT<int, 0> CancelableRequestConsumer;
483
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.
488extern template class CancelableRequestConsumerTSimple<int>;
489
490// We'll also want to extern-template the most common, typedef-ed
491// CancelableRequestConsumerT.
492extern template class CancelableRequestConsumerT<int, 0>;
493#endif
494
495// CancelableRequest ----------------------------------------------------------
496//
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.
502//
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
505// parameters.
506//
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).
512//
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.
520
521// Non-templatized base class that provides cancellation
522class CancelableRequestBase
523    : public base::RefCountedThreadSafe<CancelableRequestBase> {
524 public:
525  friend class CancelableRequestProvider;
526
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.
530  //
531  // This must be called on the same thread the callback will be executed on, it
532  // will save that thread for later.
533  //
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).
539  //
540  // In addition, not all of the information (for example, the handle) is known
541  // at construction time.
542  CancelableRequestBase();
543
544  CancelableRequestConsumerBase* consumer() const {
545    return consumer_;
546  }
547
548  CancelableRequestProvider::Handle handle() const {
549    return handle_;
550  }
551
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() {
556    canceled_.Set();
557  }
558  bool canceled() {
559    return canceled_.IsSet();
560  }
561
562 protected:
563  friend class base::RefCountedThreadSafe<CancelableRequestBase>;
564  virtual ~CancelableRequestBase();
565
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);
571
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);
575
576  // Tells the provider that the request is complete, which then tells the
577  // consumer.
578  void NotifyCompleted() const {
579    provider_->RequestCompleted(handle());
580    consumer_->DidExecute(provider_, handle_);
581  }
582
583  // Cover method for CancelableRequestConsumerBase::WillExecute.
584  void WillExecute() {
585    consumer_->WillExecute(provider_, handle_);
586  }
587
588  // The message loop that this request was created on. The callback will
589  // happen on the same thread.
590  base::MessageLoop* callback_thread_;
591
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_;
595
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_;
599
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_;
604
605  // Set if the caller cancels this request. No callbacks should be made when
606  // this is set.
607  base::CancellationFlag canceled_;
608
609 private:
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);
614
615  DISALLOW_COPY_AND_ASSIGN(CancelableRequestBase);
616};
617
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
621// (in tuple.h).
622//
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.
626//
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:
630//
631//   typedef Callback1<int>::Type DoodieCallback;
632//
633//   class DoodieRequest : public CancelableRequest<DoodieCallback> {
634//    public:
635//     DoodieRequest(CallbackType* callback) : CancelableRequest(callback) {
636//     }
637//
638//    private:
639//     ~DoodieRequest() {}
640//
641//     int input_arg1;
642//     std::wstring input_arg2;
643//   };
644template<typename CB>
645class CancelableRequest : public CancelableRequestBase {
646 public:
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.
651
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
654  // appropriate.
655  explicit CancelableRequest(CallbackType* callback)
656      : CancelableRequestBase(),
657        callback_(callback) {
658    DCHECK(callback) << "We should always have a callback";
659  }
660
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.
665  //
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());
672    if (!canceled()) {
673      if (callback_thread_ == base::MessageLoop::current()) {
674        // We can do synchronous callbacks when we're on the same thread.
675        ExecuteCallback(param);
676      } else {
677        callback_thread_->PostTask(
678            FROM_HERE,
679            base::Bind(&CancelableRequest<CB>::ExecuteCallback, this, param));
680      }
681    }
682  }
683
684  // Like |ForwardResult| but this never does a synchronous callback.
685  void ForwardResultAsync(const TupleType& param) {
686    DCHECK(callback_.get());
687    if (!canceled()) {
688      callback_thread_->PostTask(
689          FROM_HERE,
690          base::Bind(&CancelableRequest<CB>::ExecuteCallback, this, param));
691    }
692  }
693
694 protected:
695  virtual ~CancelableRequest() {}
696
697 private:
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()) {
702      WillExecute();
703
704      // Execute the callback.
705      callback_->RunWithParams(param);
706    }
707
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())
712      NotifyCompleted();
713  }
714
715  // This should only be executed if !canceled_.IsSet(),
716  // otherwise the pointers may be invalid.
717  scoped_ptr<CallbackType> callback_;
718};
719
720// CancelableRequest<> wraps a normal base::Callback<> for use in the
721// CancelableRequest framework.
722//
723// When using this class, the provider MUST call Init() (on the base class)
724// before this is valid.
725//
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.
730//
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.
734//
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.
739//
740// The following specializations handle different arities of base::Callbacks<>.
741template<>
742class CancelableRequest<base::Closure> : public CancelableRequestBase {
743 public:
744  typedef base::Closure CallbackType;
745
746  explicit CancelableRequest(const CallbackType& callback)
747      : CancelableRequestBase(),
748        callback_(callback) {
749    DCHECK(!callback.is_null()) << "Callback must be initialized.";
750  }
751
752  void ForwardResult(void) {
753    if (canceled()) return;
754    DoForward(callback_, false);
755  }
756
757  void ForwardResultAsync() {
758    if (canceled()) return;
759    DoForward(callback_, true);
760  }
761
762 protected:
763  virtual ~CancelableRequest() {}
764
765 private:
766  CallbackType callback_;
767};
768
769template<typename A1>
770class CancelableRequest<base::Callback<void(A1)> >
771    : public CancelableRequestBase {
772 public:
773  typedef base::Callback<void(A1)> CallbackType;
774
775  explicit CancelableRequest(const CallbackType& callback)
776      : CancelableRequestBase(),
777        callback_(callback) {
778    DCHECK(!callback.is_null()) << "Callback must be initialized.";
779  }
780
781  void ForwardResult(
782      typename base::internal::CallbackParamTraits<A1>::ForwardType a1) {
783    if (canceled()) return;
784    DoForward(base::Bind(callback_, a1), false);
785  }
786
787  void ForwardResultAsync(
788      typename base::internal::CallbackParamTraits<A1>::ForwardType a1) {
789    if (canceled()) return;
790    DoForward(base::Bind(callback_, a1), true);
791  }
792
793 protected:
794  virtual ~CancelableRequest() {}
795
796 private:
797  CallbackType callback_;
798};
799
800template<typename A1, typename A2>
801class CancelableRequest<base::Callback<void(A1,A2)> >
802    : public CancelableRequestBase {
803 public:
804  typedef base::Callback<void(A1,A2)> CallbackType;
805
806  explicit CancelableRequest(const CallbackType& callback)
807      : CancelableRequestBase(),
808        callback_(callback) {
809    DCHECK(!callback.is_null()) << "Callback must be initialized.";
810  }
811
812  void ForwardResult(
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);
817  }
818
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);
824  }
825
826 protected:
827  virtual ~CancelableRequest() {}
828
829 private:
830  CallbackType callback_;
831};
832
833template<typename A1, typename A2, typename A3>
834class CancelableRequest<base::Callback<void(A1,A2,A3)> >
835    : public CancelableRequestBase {
836 public:
837  typedef base::Callback<void(A1,A2,A3)> CallbackType;
838
839  explicit CancelableRequest(const CallbackType& callback)
840      : CancelableRequestBase(),
841        callback_(callback) {
842    DCHECK(!callback.is_null()) << "Callback must be initialized.";
843  }
844
845  void ForwardResult(
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);
851  }
852
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);
859  }
860
861 protected:
862  virtual ~CancelableRequest() {}
863
864 private:
865  CallbackType callback_;
866};
867
868template<typename A1, typename A2, typename A3, typename A4>
869class CancelableRequest<base::Callback<void(A1, A2, A3, A4)> >
870    : public CancelableRequestBase {
871 public:
872  typedef base::Callback<void(A1, A2, A3, A4)> CallbackType;
873
874  explicit CancelableRequest(const CallbackType& callback)
875      : CancelableRequestBase(),
876        callback_(callback) {
877    DCHECK(!callback.is_null()) << "Callback must be initialized.";
878  }
879
880  void ForwardResult(
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);
887  }
888
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);
896  }
897
898 protected:
899  virtual ~CancelableRequest() {}
900
901 private:
902  CallbackType callback_;
903};
904
905template<typename A1, typename A2, typename A3, typename A4, typename A5>
906class CancelableRequest<base::Callback<void(A1, A2, A3, A4, A5)> >
907    : public CancelableRequestBase {
908 public:
909  typedef base::Callback<void(A1, A2, A3, A4, A5)> CallbackType;
910
911  explicit CancelableRequest(const CallbackType& callback)
912      : CancelableRequestBase(),
913        callback_(callback) {
914    DCHECK(!callback.is_null()) << "Callback must be initialized.";
915  }
916
917  void ForwardResult(
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);
925  }
926
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);
935  }
936
937 protected:
938  virtual ~CancelableRequest() {}
939
940 private:
941  CallbackType callback_;
942};
943
944template<typename A1, typename A2, typename A3, typename A4, typename A5,
945         typename A6>
946class CancelableRequest<base::Callback<void(A1, A2, A3, A4, A5, A6)> >
947    : public CancelableRequestBase {
948 public:
949  typedef base::Callback<void(A1, A2, A3, A4, A5, A6)> CallbackType;
950
951  explicit CancelableRequest(const CallbackType& callback)
952      : CancelableRequestBase(),
953        callback_(callback) {
954    DCHECK(!callback.is_null()) << "Callback must be initialized.";
955  }
956
957  void ForwardResult(
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);
966  }
967
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);
977  }
978
979 protected:
980  virtual ~CancelableRequest() {}
981
982 private:
983  CallbackType callback_;
984};
985
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));
999//
1000// Tip: for passing more than one value, use a Tuple for the value.
1001template<typename CB, typename Type>
1002class CancelableRequest1 : public CancelableRequest<CB> {
1003 public:
1004  explicit CancelableRequest1(
1005      const typename CancelableRequest<CB>::CallbackType& callback)
1006      : CancelableRequest<CB>(callback), value() {
1007  }
1008
1009  // The value.
1010  Type value;
1011
1012 protected:
1013  virtual ~CancelableRequest1() {}
1014};
1015
1016#endif  // CHROME_BROWSER_COMMON_CANCELABLE_REQUEST_H_
1017