Home | History | Annotate | Download | only in common
      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 
    106 class CancelableRequestBase;
    107 class 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 
    118 class 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.
    181 class 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).
    213 template<class T>
    214 class 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 
    308 template<class T>
    309 CancelableRequestConsumerTSimple<T>::CancelableRequestConsumerTSimple() {
    310 }
    311 
    312 template<class T>
    313 CancelableRequestConsumerTSimple<T>::~CancelableRequestConsumerTSimple() {
    314   CancelAllRequests();
    315 }
    316 
    317 template<class T>
    318 void 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 
    327 template<class T>
    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];
    334 }
    335 
    336 template<class T>
    337 T CancelableRequestConsumerTSimple<T>::GetClientDataForCurrentRequest() {
    338   DCHECK(current_request_.is_valid());
    339   return GetClientData(current_request_.provider, current_request_.handle);
    340 }
    341 
    342 template<class T>
    343 bool CancelableRequestConsumerTSimple<T>::HasPendingRequests() const {
    344   return !pending_requests_.empty();
    345 }
    346 
    347 template<class T>
    348 size_t CancelableRequestConsumerTSimple<T>::PendingRequestCount() const {
    349   return pending_requests_.size();
    350 }
    351 
    352 template<class T>
    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);
    361   }
    362   copied_requests.clear();
    363 
    364   // That should have cleared all the pending items.
    365   DCHECK(pending_requests_.empty());
    366 }
    367 
    368 template<class T>
    369 void 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 
    380 template<class T>
    381 bool 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 
    395 template<class T>
    396 void 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 
    404 template<class T>
    405 T CancelableRequestConsumerTSimple<T>::get_initial_t() const {
    406   return T();
    407 }
    408 
    409 template<class T>
    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).
    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 
    425 template<class 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";
    433     return;
    434   }
    435 
    436   pending_requests_.erase(i);
    437 }
    438 
    439 template<class T>
    440 void CancelableRequestConsumerTSimple<T>::WillExecute(
    441     CancelableRequestProvider* provider,
    442     CancelableRequestProvider::Handle handle) {
    443   current_request_ = PendingRequest(provider, handle);
    444 }
    445 
    446 template<class T>
    447 void 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|.
    455 template<class T, T initial_t>
    456 class CancelableRequestConsumerT
    457     : public CancelableRequestConsumerTSimple<T> {
    458  public:
    459   CancelableRequestConsumerT();
    460   virtual ~CancelableRequestConsumerT();
    461 
    462  protected:
    463   virtual T get_initial_t() const;
    464 };
    465 
    466 template<class T, T initial_t>
    467 CancelableRequestConsumerT<T, initial_t>::CancelableRequestConsumerT() {
    468 }
    469 
    470 template<class T, T initial_t>
    471 CancelableRequestConsumerT<T, initial_t>::~CancelableRequestConsumerT() {
    472 }
    473 
    474 template<class T, T initial_t>
    475 T 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.
    482 typedef 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.
    488 extern template class CancelableRequestConsumerTSimple<int>;
    489 
    490 // We'll also want to extern-template the most common, typedef-ed
    491 // CancelableRequestConsumerT.
    492 extern 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
    522 class 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 //   };
    644 template<typename CB>
    645 class 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<>.
    741 template<>
    742 class 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 
    769 template<typename A1>
    770 class 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 
    800 template<typename A1, typename A2>
    801 class 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 
    833 template<typename A1, typename A2, typename A3>
    834 class 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 
    868 template<typename A1, typename A2, typename A3, typename A4>
    869 class 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 
    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 {
    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 
    944 template<typename A1, typename A2, typename A3, typename A4, typename A5,
    945          typename A6>
    946 class 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.
   1001 template<typename CB, typename Type>
   1002 class 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