| Index: chrome/browser/cancelable_request.h
|
| ===================================================================
|
| --- chrome/browser/cancelable_request.h (revision 75626)
|
| +++ chrome/browser/cancelable_request.h (working copy)
|
| @@ -2,703 +2,11 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -// CancelableRequestProviders and Consumers work together to make requests that
|
| -// execute on a background thread in the provider and return data to the
|
| -// consumer. These class collaborate to keep a list of open requests and to
|
| -// make sure that requests to not outlive either of the objects involved in the
|
| -// transaction.
|
| -//
|
| -// If you do not need to return data to the consumer, do not use this system,
|
| -// just use the regular Task/RunnableMethod stuff.
|
| -//
|
| -// The CancelableRequest object is used internally to each provider to track
|
| -// request data and callback information.
|
| -//
|
| -// Example consumer calling |StartRequest| on a frontend service:
|
| -//
|
| -// class MyClass {
|
| -// void MakeRequest() {
|
| -// frontend_service->StartRequest(some_input1, some_input2,
|
| -// &callback_consumer_,
|
| -// NewCallback(this, &MyClass:RequestComplete));
|
| -// // StartRequest() returns a Handle which may be retained for use with
|
| -// // CancelRequest() if required, e.g. in MyClass's destructor.
|
| -// }
|
| -//
|
| -// void RequestComplete(int status) {
|
| -// ...
|
| -// }
|
| -//
|
| -// private:
|
| -// CancelableRequestConsumer callback_consumer_;
|
| -// };
|
| -//
|
| -//
|
| -// Example frontend provider. It receives requests and forwards them to the
|
| -// backend on another thread:
|
| -//
|
| -// class Frontend : public CancelableRequestProvider {
|
| -// typedef Callback1<int>::Type RequestCallbackType;
|
| -//
|
| -// Handle StartRequest(int some_input1, int some_input2,
|
| -// CancelableRequestConsumerBase* consumer,
|
| -// RequestCallbackType* callback) {
|
| -// scoped_refptr<CancelableRequest<RequestCallbackType> > request(
|
| -// new CancelableRequest<RequestCallbackType>(callback));
|
| -// AddRequest(request, consumer);
|
| -//
|
| -// // Send the parameters and the request to the backend thread.
|
| -// backend_thread_->PostTask(FROM_HERE,
|
| -// NewRunnableMethod(backend_, &Backend::DoRequest, request,
|
| -// some_input1, some_input2));
|
| -//
|
| -// // The handle will have been set by AddRequest.
|
| -// return request->handle();
|
| -// }
|
| -// };
|
| -//
|
| -//
|
| -// Example backend provider that does work and dispatches the callback back
|
| -// to the original thread. Note that we need to pass it as a scoped_refptr so
|
| -// that the object will be kept alive if the request is canceled (releasing
|
| -// the provider's reference to it).
|
| -//
|
| -// class Backend {
|
| -// void DoRequest(
|
| -// scoped_refptr< CancelableRequest<Frontend::RequestCallbackType> >
|
| -// request,
|
| -// int some_input1, int some_input2) {
|
| -// if (request->canceled())
|
| -// return;
|
| -//
|
| -// ... do your processing ...
|
| -//
|
| -// // Depending on your typedefs, one of these two forms will be more
|
| -// // convenient:
|
| -// request->ForwardResult(Tuple1<int>(return_value));
|
| -//
|
| -// // -- or -- (inferior in this case)
|
| -// request->ForwardResult(Frontend::RequestCallbackType::TupleType(
|
| -// return_value));
|
| -// }
|
| -// };
|
| -
|
| -#ifndef CHROME_BROWSER_CANCELABLE_REQUEST_H__
|
| -#define CHROME_BROWSER_CANCELABLE_REQUEST_H__
|
| +#ifndef CHROME_BROWSER_CANCELABLE_REQUEST_H_
|
| +#define CHROME_BROWSER_CANCELABLE_REQUEST_H_
|
| #pragma once
|
|
|
| -#include <map>
|
| -#include <vector>
|
| +// TODO(jam): remove this file when all files have been converted.
|
| +#include "content/browser/cancelable_request.h"
|
|
|
| -#include "base/basictypes.h"
|
| -#include "base/callback.h"
|
| -#include "base/logging.h"
|
| -#include "base/message_loop.h"
|
| -#include "base/ref_counted.h"
|
| -#include "base/scoped_ptr.h"
|
| -#include "base/synchronization/cancellation_flag.h"
|
| -#include "base/synchronization/lock.h"
|
| -#include "base/task.h"
|
| -#include "build/build_config.h"
|
| -
|
| -class CancelableRequestBase;
|
| -class CancelableRequestConsumerBase;
|
| -
|
| -// CancelableRequestProvider --------------------------------------------------
|
| -//
|
| -// This class is threadsafe. Requests may be added or canceled from any thread,
|
| -// but a task must only be canceled from the same thread it was initially run
|
| -// on.
|
| -//
|
| -// It is intended that providers inherit from this class to provide the
|
| -// necessary functionality.
|
| -
|
| -class CancelableRequestProvider {
|
| - public:
|
| - // Identifies a specific request from this provider.
|
| - typedef int Handle;
|
| -
|
| - CancelableRequestProvider();
|
| - virtual ~CancelableRequestProvider();
|
| -
|
| - // Called by the enduser of the request to cancel it. This MUST be called on
|
| - // the same thread that originally issued the request (which is also the same
|
| - // thread that would have received the callback if it was not canceled).
|
| - // handle must be for a valid pending (not yet complete or cancelled) request.
|
| - void CancelRequest(Handle handle);
|
| -
|
| - protected:
|
| - // Adds a new request and initializes it. This is called by a derived class
|
| - // to add a new request. The request's Init() will be called (which is why
|
| - // the consumer is required. The handle to the new request is returned.
|
| - Handle AddRequest(CancelableRequestBase* request,
|
| - CancelableRequestConsumerBase* consumer);
|
| -
|
| - // Called by the CancelableRequest when the request has executed. It will
|
| - // be removed from the list of pending requests (as opposed to canceling,
|
| - // which will also set some state on the request).
|
| - void RequestCompleted(Handle handle);
|
| -
|
| - private:
|
| - typedef std::map<Handle, scoped_refptr<CancelableRequestBase> >
|
| - CancelableRequestMap;
|
| -
|
| - // Only call this when you already have acquired pending_request_lock_.
|
| - void CancelRequestLocked(const CancelableRequestMap::iterator& item);
|
| -
|
| - friend class CancelableRequestBase;
|
| -
|
| - base::Lock pending_request_lock_;
|
| -
|
| - // Lists all outstanding requests. Protected by the |lock_|.
|
| - CancelableRequestMap pending_requests_;
|
| -
|
| - // The next handle value we will return. Protected by the |lock_|.
|
| - int next_handle_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(CancelableRequestProvider);
|
| -};
|
| -
|
| -// CancelableRequestConsumer --------------------------------------------------
|
| -//
|
| -// Classes wishing to make requests on a provider should have an instance of
|
| -// this class. Callers will need to pass a pointer to this consumer object
|
| -// when they make the request. It will automatically track any pending
|
| -// requests, and will automatically cancel them on destruction to prevent the
|
| -// accidental calling of freed memory.
|
| -//
|
| -// It is recommended to just have this class as a member variable since there
|
| -// is nothing to be gained by inheriting from it other than polluting your
|
| -// namespace.
|
| -//
|
| -// THIS CLASS IS NOT THREADSAFE (unlike the provider). You must make requests
|
| -// and get callbacks all from the same thread.
|
| -
|
| -// Base class used to notify of new requests.
|
| -class CancelableRequestConsumerBase {
|
| - protected:
|
| - friend class CancelableRequestBase;
|
| - friend class CancelableRequestProvider;
|
| -
|
| - virtual ~CancelableRequestConsumerBase() {
|
| - }
|
| -
|
| - // Adds a new request to the list of requests that are being tracked. This
|
| - // is called by the provider when a new request is created.
|
| - virtual void OnRequestAdded(CancelableRequestProvider* provider,
|
| - CancelableRequestProvider::Handle handle) = 0;
|
| -
|
| - // Removes the given request from the list of pending requests. Called
|
| - // by the CancelableRequest immediately after the callback has executed for a
|
| - // given request, and by the provider when a request is canceled.
|
| - virtual void OnRequestRemoved(CancelableRequestProvider* provider,
|
| - CancelableRequestProvider::Handle handle) = 0;
|
| -
|
| - // Sent to provider before executing a callback.
|
| - virtual void WillExecute(CancelableRequestProvider* provider,
|
| - CancelableRequestProvider::Handle handle) = 0;
|
| -
|
| - // Sent after executing a callback.
|
| - virtual void DidExecute(CancelableRequestProvider* provider,
|
| - CancelableRequestProvider::Handle handle) = 0;
|
| -};
|
| -
|
| -// Template for clients to use. It allows them to associate random "client
|
| -// data" with a specific request. The default value for this type is 0.
|
| -// The type T should be small and easily copyable (like a pointer
|
| -// or an integer).
|
| -template<class T>
|
| -class CancelableRequestConsumerTSimple : public CancelableRequestConsumerBase {
|
| - public:
|
| - CancelableRequestConsumerTSimple();
|
| -
|
| - // Cancel any outstanding requests so that we do not get called back after we
|
| - // are destroyed. As these requests are removed, the providers will call us
|
| - // back on OnRequestRemoved, which will then update the list. To iterate
|
| - // successfully while the list is changing out from under us, we make a copy.
|
| - virtual ~CancelableRequestConsumerTSimple();
|
| -
|
| - // Associates some random data with a specified request. The request MUST be
|
| - // outstanding, or it will assert. This is intended to be called immediately
|
| - // after a request is issued.
|
| - void SetClientData(CancelableRequestProvider* p,
|
| - CancelableRequestProvider::Handle h,
|
| - T client_data);
|
| -
|
| - // Retrieves previously associated data for a specified request. The request
|
| - // MUST be outstanding, or it will assert. This is intended to be called
|
| - // during processing of a callback to retrieve extra data.
|
| - T GetClientData(CancelableRequestProvider* p,
|
| - CancelableRequestProvider::Handle h);
|
| -
|
| - // Returns the data associated with the current request being processed. This
|
| - // is only valid during the time a callback is being processed.
|
| - T GetClientDataForCurrentRequest();
|
| -
|
| - // Returns true if there are any pending requests.
|
| - bool HasPendingRequests() const;
|
| -
|
| - // Returns the number of pending requests.
|
| - size_t PendingRequestCount() const;
|
| -
|
| - // Cancels all requests outstanding.
|
| - void CancelAllRequests();
|
| -
|
| - // Returns the handle for the first request that has the specified client data
|
| - // (in |handle|). Returns true if there is a request for the specified client
|
| - // data, false otherwise.
|
| - bool GetFirstHandleForClientData(T client_data,
|
| - CancelableRequestProvider::Handle* handle);
|
| -
|
| - // Gets the client data for all pending requests.
|
| - void GetAllClientData(std::vector<T>* data);
|
| -
|
| - protected:
|
| - struct PendingRequest {
|
| - PendingRequest(CancelableRequestProvider* p,
|
| - CancelableRequestProvider::Handle h)
|
| - : provider(p), handle(h) {
|
| - }
|
| -
|
| - PendingRequest() : provider(NULL), handle(0) {}
|
| -
|
| - // Comparison operator for stl.
|
| - bool operator<(const PendingRequest& other) const {
|
| - if (provider != other.provider)
|
| - return provider < other.provider;
|
| - return handle < other.handle;
|
| - }
|
| -
|
| - bool is_valid() const { return provider != NULL; }
|
| -
|
| - CancelableRequestProvider* provider;
|
| - CancelableRequestProvider::Handle handle;
|
| - };
|
| - typedef std::map<PendingRequest, T> PendingRequestList;
|
| -
|
| - virtual T get_initial_t() const;
|
| -
|
| - virtual void OnRequestAdded(CancelableRequestProvider* provider,
|
| - CancelableRequestProvider::Handle handle);
|
| -
|
| - virtual void OnRequestRemoved(CancelableRequestProvider* provider,
|
| - CancelableRequestProvider::Handle handle);
|
| -
|
| - virtual void WillExecute(CancelableRequestProvider* provider,
|
| - CancelableRequestProvider::Handle handle);
|
| -
|
| - virtual void DidExecute(CancelableRequestProvider* provider,
|
| - CancelableRequestProvider::Handle handle);
|
| -
|
| - // Lists all outstanding requests.
|
| - PendingRequestList pending_requests_;
|
| -
|
| - // This is valid while processing a request and is used to identify the
|
| - // provider/handle of request.
|
| - PendingRequest current_request_;
|
| -};
|
| -
|
| -template<class T>
|
| -CancelableRequestConsumerTSimple<T>::CancelableRequestConsumerTSimple() {
|
| -}
|
| -
|
| -template<class T>
|
| -CancelableRequestConsumerTSimple<T>::~CancelableRequestConsumerTSimple() {
|
| - CancelAllRequests();
|
| -}
|
| -
|
| -template<class T>
|
| -void CancelableRequestConsumerTSimple<T>::SetClientData(
|
| - CancelableRequestProvider* p,
|
| - CancelableRequestProvider::Handle h,
|
| - T client_data) {
|
| - PendingRequest request(p, h);
|
| - DCHECK(pending_requests_.find(request) != pending_requests_.end());
|
| - pending_requests_[request] = client_data;
|
| -}
|
| -
|
| -template<class T>
|
| -T CancelableRequestConsumerTSimple<T>::GetClientData(
|
| - CancelableRequestProvider* p,
|
| - CancelableRequestProvider::Handle h) {
|
| - PendingRequest request(p, h);
|
| - DCHECK(pending_requests_.find(request) != pending_requests_.end());
|
| - return pending_requests_[request];
|
| -}
|
| -
|
| -template<class T>
|
| -T CancelableRequestConsumerTSimple<T>::GetClientDataForCurrentRequest() {
|
| - DCHECK(current_request_.is_valid());
|
| - return GetClientData(current_request_.provider, current_request_.handle);
|
| -}
|
| -
|
| -template<class T>
|
| -bool CancelableRequestConsumerTSimple<T>::HasPendingRequests() const {
|
| - return !pending_requests_.empty();
|
| -}
|
| -
|
| -template<class T>
|
| -size_t CancelableRequestConsumerTSimple<T>::PendingRequestCount() const {
|
| - return pending_requests_.size();
|
| -}
|
| -
|
| -template<class T>
|
| -void CancelableRequestConsumerTSimple<T>::CancelAllRequests() {
|
| - PendingRequestList copied_requests(pending_requests_);
|
| - for (typename PendingRequestList::iterator i = copied_requests.begin();
|
| - i != copied_requests.end(); ++i)
|
| - i->first.provider->CancelRequest(i->first.handle);
|
| - copied_requests.clear();
|
| -
|
| - // That should have cleared all the pending items.
|
| - DCHECK(pending_requests_.empty());
|
| -}
|
| -
|
| -template<class T>
|
| -bool CancelableRequestConsumerTSimple<T>::GetFirstHandleForClientData(
|
| - T client_data,
|
| - CancelableRequestProvider::Handle* handle) {
|
| - for (typename PendingRequestList::const_iterator i =
|
| - pending_requests_.begin(); i != pending_requests_.end(); ++i) {
|
| - if (i->second == client_data) {
|
| - *handle = i->first.handle;
|
| - return true;
|
| - }
|
| - }
|
| - *handle = 0;
|
| - return false;
|
| -}
|
| -
|
| -template<class T>
|
| -void CancelableRequestConsumerTSimple<T>::GetAllClientData(
|
| - std::vector<T>* data) {
|
| - DCHECK(data);
|
| - for (typename PendingRequestList::iterator i = pending_requests_.begin();
|
| - i != pending_requests_.end(); ++i)
|
| - data->push_back(i->second);
|
| -}
|
| -
|
| -template<class T>
|
| -T CancelableRequestConsumerTSimple<T>::get_initial_t() const {
|
| - return 0;
|
| -}
|
| -
|
| -template<class T>
|
| -void CancelableRequestConsumerTSimple<T>::OnRequestAdded(
|
| - CancelableRequestProvider* provider,
|
| - CancelableRequestProvider::Handle handle) {
|
| - DCHECK(pending_requests_.find(PendingRequest(provider, handle)) ==
|
| - pending_requests_.end());
|
| - pending_requests_[PendingRequest(provider, handle)] = get_initial_t();
|
| -}
|
| -
|
| -template<class T>
|
| -void CancelableRequestConsumerTSimple<T>::OnRequestRemoved(
|
| - CancelableRequestProvider* provider,
|
| - CancelableRequestProvider::Handle handle) {
|
| - typename PendingRequestList::iterator i =
|
| - pending_requests_.find(PendingRequest(provider, handle));
|
| - if (i == pending_requests_.end()) {
|
| - NOTREACHED() << "Got a complete notification for a nonexistent request";
|
| - return;
|
| - }
|
| -
|
| - pending_requests_.erase(i);
|
| -}
|
| -
|
| -template<class T>
|
| -void CancelableRequestConsumerTSimple<T>::WillExecute(
|
| - CancelableRequestProvider* provider,
|
| - CancelableRequestProvider::Handle handle) {
|
| - current_request_ = PendingRequest(provider, handle);
|
| -}
|
| -
|
| -template<class T>
|
| -void CancelableRequestConsumerTSimple<T>::DidExecute(
|
| - CancelableRequestProvider* provider,
|
| - CancelableRequestProvider::Handle handle) {
|
| - current_request_ = PendingRequest();
|
| -}
|
| -
|
| -// See CancelableRequestConsumerTSimple. The default value for T
|
| -// is given in |initial_t|.
|
| -template<class T, T initial_t>
|
| -class CancelableRequestConsumerT : public CancelableRequestConsumerTSimple<T> {
|
| - public:
|
| - CancelableRequestConsumerT();
|
| - virtual ~CancelableRequestConsumerT();
|
| -
|
| - protected:
|
| - virtual T get_initial_t() const;
|
| -};
|
| -
|
| -template<class T, T initial_t>
|
| -CancelableRequestConsumerT<T, initial_t>::CancelableRequestConsumerT() {
|
| -}
|
| -
|
| -template<class T, T initial_t>
|
| -CancelableRequestConsumerT<T, initial_t>::~CancelableRequestConsumerT() {
|
| -}
|
| -
|
| -template<class T, T initial_t>
|
| -T CancelableRequestConsumerT<T, initial_t>::get_initial_t() const {
|
| - return initial_t;
|
| -}
|
| -
|
| -// Some clients may not want to store data. Rather than do some complicated
|
| -// thing with virtual functions to allow some consumers to store extra data and
|
| -// some not to, we just define a default one that stores some dummy data.
|
| -typedef CancelableRequestConsumerT<int, 0> CancelableRequestConsumer;
|
| -
|
| -// MSVC doesn't like complex extern templates and DLLs.
|
| -#if !defined(COMPILER_MSVC)
|
| -// The vast majority of CancelableRequestConsumers are instantiated on <int>,
|
| -// so prevent that template from being expanded in normal code.
|
| -extern template class CancelableRequestConsumerTSimple<int>;
|
| -
|
| -// We'll also want to extern-template the most common, typedef-ed
|
| -// CancelableRequestConsumerT.
|
| -extern template class CancelableRequestConsumerT<int, 0>;
|
| -#endif
|
| -
|
| -// CancelableRequest ----------------------------------------------------------
|
| -//
|
| -// The request object that is used by a CancelableRequestProvider to send
|
| -// results to a CancelableRequestConsumer. This request handles the returning
|
| -// of results from a thread where the request is being executed to the thread
|
| -// and callback where the results are used. IT SHOULD BE PASSED AS A
|
| -// scoped_refptr TO KEEP IT ALIVE.
|
| -//
|
| -// It does not handle input parameters to the request. The caller must either
|
| -// transfer those separately or derive from this class to add the desired
|
| -// parameters.
|
| -//
|
| -// When the processing is complete on this message, the caller MUST call
|
| -// ForwardResult() with the return arguments that will be passed to the
|
| -// callback. If the request has been canceled, Return is optional (it will not
|
| -// do anything). If you do not have to return to the caller, the cancelable
|
| -// request system should not be used! (just use regular fire-and-forget tasks).
|
| -//
|
| -// Callback parameters are passed by value. In some cases, the request will
|
| -// want to return a large amount of data (for example, an image). One good
|
| -// approach is to derive from the CancelableRequest and make the data object
|
| -// (for example, a std::vector) owned by the CancelableRequest. The pointer
|
| -// to this data would be passed for the callback parameter. Since the
|
| -// CancelableRequest outlives the callback call, the data will be valid on the
|
| -// other thread for the callback, but will still be destroyed properly.
|
| -
|
| -// Non-templatized base class that provides cancellation
|
| -class CancelableRequestBase
|
| - : public base::RefCountedThreadSafe<CancelableRequestBase> {
|
| - public:
|
| - friend class CancelableRequestProvider;
|
| -
|
| - // Initializes most things to empty, Init() must be called to complete
|
| - // initialization of the object. This will be done by the provider when
|
| - // the request is dispatched.
|
| - //
|
| - // This must be called on the same thread the callback will be executed on,
|
| - // it will save that thread for later.
|
| - //
|
| - // This two-phase init is done so that the constructor can have no
|
| - // parameters, which makes it much more convenient for derived classes,
|
| - // which can be common. The derived classes need only declare the variables
|
| - // they provide in the constructor rather than many lines of internal
|
| - // tracking data that are passed to the base class (us).
|
| - //
|
| - // In addition, not all of the information (for example, the handle) is known
|
| - // at construction time.
|
| - CancelableRequestBase();
|
| -
|
| - CancelableRequestConsumerBase* consumer() const {
|
| - return consumer_;
|
| - }
|
| -
|
| - CancelableRequestProvider::Handle handle() const {
|
| - return handle_;
|
| - }
|
| -
|
| - // The canceled flag indicates that the request should not be executed.
|
| - // A request can never be uncanceled, so only a setter for true is provided.
|
| - // This can be called multiple times, but only from one thread.
|
| - void set_canceled() {
|
| - canceled_.Set();
|
| - }
|
| - bool canceled() {
|
| - return canceled_.IsSet();
|
| - }
|
| -
|
| - protected:
|
| - friend class base::RefCountedThreadSafe<CancelableRequestBase>;
|
| - virtual ~CancelableRequestBase();
|
| -
|
| - // Initializes the object with the particulars from the provider. It may only
|
| - // be called once (it is called by the provider, which is a friend).
|
| - void Init(CancelableRequestProvider* provider,
|
| - CancelableRequestProvider::Handle handle,
|
| - CancelableRequestConsumerBase* consumer);
|
| -
|
| - // Tells the provider that the request is complete, which then tells the
|
| - // consumer.
|
| - void NotifyCompleted() const {
|
| - provider_->RequestCompleted(handle());
|
| - consumer_->DidExecute(provider_, handle_);
|
| - }
|
| -
|
| - // Cover method for CancelableRequestConsumerBase::WillExecute.
|
| - void WillExecute() {
|
| - consumer_->WillExecute(provider_, handle_);
|
| - }
|
| -
|
| - // The message loop that this request was created on. The callback will
|
| - // happen on the same thread.
|
| - MessageLoop* callback_thread_;
|
| -
|
| - // The provider for this request. When we execute, we will notify this that
|
| - // request is complete to it can remove us from the requests it tracks.
|
| - CancelableRequestProvider* provider_;
|
| -
|
| - // Notified after we execute that the request is complete. This should only
|
| - // be accessed if !canceled_.IsSet(), otherwise the pointer is invalid.
|
| - CancelableRequestConsumerBase* consumer_;
|
| -
|
| - // The handle to this request inside the provider. This will be initialized
|
| - // to 0 when the request is created, and the provider will set it once the
|
| - // request has been dispatched.
|
| - CancelableRequestProvider::Handle handle_;
|
| -
|
| - // Set if the caller cancels this request. No callbacks should be made when
|
| - // this is set.
|
| - base::CancellationFlag canceled_;
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(CancelableRequestBase);
|
| -};
|
| -
|
| -// Templatized class. This is the one you should use directly or inherit from.
|
| -// The callback can be invoked by calling the ForwardResult() method. For this,
|
| -// you must either pack the parameters into a tuple, or use DispatchToMethod
|
| -// (in tuple.h).
|
| -//
|
| -// If you inherit to add additional input parameters or to do more complex
|
| -// memory management (see the bigger comment about this above), you can put
|
| -// those on a subclass of this.
|
| -//
|
| -// We have decided to allow users to treat derived classes of this as structs,
|
| -// so you can add members without getters and setters (which just makes the
|
| -// code harder to read). Don't use underscores after these vars. For example:
|
| -//
|
| -// typedef Callback1<int>::Type DoodieCallback;
|
| -//
|
| -// class DoodieRequest : public CancelableRequest<DoodieCallback> {
|
| -// public:
|
| -// DoodieRequest(CallbackType* callback) : CancelableRequest(callback) {
|
| -// }
|
| -//
|
| -// private:
|
| -// ~DoodieRequest() {}
|
| -//
|
| -// int input_arg1;
|
| -// std::wstring input_arg2;
|
| -// };
|
| -template<typename CB>
|
| -class CancelableRequest : public CancelableRequestBase {
|
| - public:
|
| - typedef CB CallbackType; // CallbackRunner<...>
|
| - typedef typename CB::TupleType TupleType; // Tuple of the callback args.
|
| -
|
| - // The provider MUST call Init() (on the base class) before this is valid.
|
| - // This class will take ownership of the callback object and destroy it when
|
| - // appropriate.
|
| - explicit CancelableRequest(CallbackType* callback)
|
| - : CancelableRequestBase(),
|
| - callback_(callback) {
|
| - DCHECK(callback) << "We should always have a callback";
|
| - }
|
| -
|
| - // Dispatches the parameters to the correct thread so the callback can be
|
| - // executed there. The caller does not need to check for cancel before
|
| - // calling this. It is optional in the cancelled case. In the non-cancelled
|
| - // case, this MUST be called.
|
| - //
|
| - // If there are any pointers in the parameters, they must live at least as
|
| - // long as the request so that it can be forwarded to the other thread.
|
| - // For complex objects, this would typically be done by having a derived
|
| - // request own the data itself.
|
| - void ForwardResult(const TupleType& param) {
|
| - DCHECK(callback_.get());
|
| - if (!canceled()) {
|
| - if (callback_thread_ == MessageLoop::current()) {
|
| - // We can do synchronous callbacks when we're on the same thread.
|
| - ExecuteCallback(param);
|
| - } else {
|
| - callback_thread_->PostTask(FROM_HERE, NewRunnableMethod(this,
|
| - &CancelableRequest<CB>::ExecuteCallback, param));
|
| - }
|
| - }
|
| - }
|
| -
|
| - // Like |ForwardResult| but this never does a synchronous callback.
|
| - void ForwardResultAsync(const TupleType& param) {
|
| - DCHECK(callback_.get());
|
| - if (!canceled()) {
|
| - callback_thread_->PostTask(FROM_HERE, NewRunnableMethod(this,
|
| - &CancelableRequest<CB>::ExecuteCallback, param));
|
| - }
|
| - }
|
| -
|
| - protected:
|
| - virtual ~CancelableRequest() {}
|
| -
|
| - private:
|
| - // Executes the callback and notifies the provider and the consumer that this
|
| - // request has been completed. This must be called on the callback_thread_.
|
| - void ExecuteCallback(const TupleType& param) {
|
| - if (!canceled_.IsSet()) {
|
| - WillExecute();
|
| -
|
| - // Execute the callback.
|
| - callback_->RunWithParams(param);
|
| -
|
| - // Notify the provider that the request is complete. The provider will
|
| - // notify the consumer for us.
|
| - NotifyCompleted();
|
| - }
|
| - }
|
| -
|
| - // This should only be executed if !canceled_.IsSet(),
|
| - // otherwise the pointers may be invalid.
|
| - scoped_ptr<CallbackType> callback_;
|
| -};
|
| -
|
| -// A CancelableRequest with a single value. This is intended for use when
|
| -// the provider provides a single value. The provider fills the result into
|
| -// the value, and notifies the request with a pointer to the value. For example,
|
| -// HistoryService has many methods that callback with a vector. Use the
|
| -// following pattern for this:
|
| -// 1. Define the callback:
|
| -// typedef Callback2<Handle, std::vector<Foo>*>::Type FooCallback;
|
| -// 2. Define the CancelableRequest1 type.
|
| -// typedef CancelableRequest1<FooCallback, std::vector<Foo>> FooRequest;
|
| -// 3. The provider method should then fillin the contents of the vector,
|
| -// forwarding the result like so:
|
| -// request->ForwardResult(FooRequest::TupleType(request->handle(),
|
| -// &request->value));
|
| -//
|
| -// Tip: for passing more than one value, use a Tuple for the value.
|
| -template<typename CB, typename Type>
|
| -class CancelableRequest1 : public CancelableRequest<CB> {
|
| - public:
|
| - explicit CancelableRequest1(
|
| - typename CancelableRequest<CB>::CallbackType* callback)
|
| - : CancelableRequest<CB>(callback) {
|
| - }
|
| -
|
| - // The value.
|
| - Type value;
|
| -
|
| - protected:
|
| - virtual ~CancelableRequest1() {}
|
| -};
|
| -
|
| -#endif // CHROME_BROWSER_CANCELABLE_REQUEST_H__
|
| +#endif // CHROME_BROWSER_CANCELABLE_REQUEST_H_
|
|
|