Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // CancelableRequestProviders and Consumers work together to make requests that | 5 // CancelableRequestProviders and Consumers work together to make requests that |
| 6 // execute on a background thread in the provider and return data to the | 6 // execute on a background thread in the provider and return data to the |
| 7 // consumer. These class collaborate to keep a list of open requests and to | 7 // consumer. These class collaborate to keep a list of open requests and to |
| 8 // make sure that requests to not outlive either of the objects involved in the | 8 // make sure that requests to not outlive either of the objects involved in the |
| 9 // transaction. | 9 // transaction. |
| 10 // | 10 // |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 // }; | 84 // }; |
| 85 | 85 |
| 86 #ifndef CONTENT_BROWSER_CANCELABLE_REQUEST_H_ | 86 #ifndef CONTENT_BROWSER_CANCELABLE_REQUEST_H_ |
| 87 #define CONTENT_BROWSER_CANCELABLE_REQUEST_H_ | 87 #define CONTENT_BROWSER_CANCELABLE_REQUEST_H_ |
| 88 #pragma once | 88 #pragma once |
| 89 | 89 |
| 90 #include <map> | 90 #include <map> |
| 91 #include <vector> | 91 #include <vector> |
| 92 | 92 |
| 93 #include "base/basictypes.h" | 93 #include "base/basictypes.h" |
| 94 #include "base/bind.h" | |
| 94 #include "base/callback.h" | 95 #include "base/callback.h" |
| 95 #include "base/logging.h" | 96 #include "base/logging.h" |
| 96 #include "base/memory/ref_counted.h" | 97 #include "base/memory/ref_counted.h" |
| 97 #include "base/memory/scoped_ptr.h" | 98 #include "base/memory/scoped_ptr.h" |
| 98 #include "base/message_loop.h" | 99 #include "base/message_loop.h" |
| 99 #include "base/synchronization/cancellation_flag.h" | 100 #include "base/synchronization/cancellation_flag.h" |
| 100 #include "base/synchronization/lock.h" | 101 #include "base/synchronization/lock.h" |
| 101 #include "base/task.h" | 102 #include "base/task.h" |
| 102 #include "build/build_config.h" | 103 #include "build/build_config.h" |
| 103 #include "content/common/content_export.h" | 104 #include "content/common/content_export.h" |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 570 void NotifyCompleted() const { | 571 void NotifyCompleted() const { |
| 571 provider_->RequestCompleted(handle()); | 572 provider_->RequestCompleted(handle()); |
| 572 consumer_->DidExecute(provider_, handle_); | 573 consumer_->DidExecute(provider_, handle_); |
| 573 } | 574 } |
| 574 | 575 |
| 575 // Cover method for CancelableRequestConsumerBase::WillExecute. | 576 // Cover method for CancelableRequestConsumerBase::WillExecute. |
| 576 void WillExecute() { | 577 void WillExecute() { |
| 577 consumer_->WillExecute(provider_, handle_); | 578 consumer_->WillExecute(provider_, handle_); |
| 578 } | 579 } |
| 579 | 580 |
| 581 // Attempts to execute callback on |callback_thread_| if the request has not | |
| 582 // been canceled yet. | |
| 583 void DoForward(const base::Closure& forwarded_call, bool force_async) { | |
|
brettw
2011/10/01 16:26:12
This should be non-inline (the whole point of the
awong
2011/10/03 05:18:39
Done.
| |
| 584 if (force_async || callback_thread_ != MessageLoop::current()) { | |
| 585 callback_thread_->PostTask( | |
| 586 FROM_HERE, | |
| 587 base::Bind(&CancelableRequestBase::ExecuteCallback, this, | |
| 588 forwarded_call)); | |
| 589 } else { | |
| 590 // We can do synchronous callbacks when we're on the same thread. | |
| 591 ExecuteCallback(forwarded_call); | |
| 592 } | |
| 593 } | |
| 594 | |
| 580 // The message loop that this request was created on. The callback will | 595 // The message loop that this request was created on. The callback will |
| 581 // happen on the same thread. | 596 // happen on the same thread. |
| 582 MessageLoop* callback_thread_; | 597 MessageLoop* callback_thread_; |
| 583 | 598 |
| 584 // The provider for this request. When we execute, we will notify this that | 599 // The provider for this request. When we execute, we will notify this that |
| 585 // request is complete to it can remove us from the requests it tracks. | 600 // request is complete to it can remove us from the requests it tracks. |
| 586 CancelableRequestProvider* provider_; | 601 CancelableRequestProvider* provider_; |
| 587 | 602 |
| 588 // Notified after we execute that the request is complete. This should only | 603 // Notified after we execute that the request is complete. This should only |
| 589 // be accessed if !canceled_.IsSet(), otherwise the pointer is invalid. | 604 // be accessed if !canceled_.IsSet(), otherwise the pointer is invalid. |
| 590 CancelableRequestConsumerBase* consumer_; | 605 CancelableRequestConsumerBase* consumer_; |
| 591 | 606 |
| 592 // The handle to this request inside the provider. This will be initialized | 607 // The handle to this request inside the provider. This will be initialized |
| 593 // to 0 when the request is created, and the provider will set it once the | 608 // to 0 when the request is created, and the provider will set it once the |
| 594 // request has been dispatched. | 609 // request has been dispatched. |
| 595 CancelableRequestProvider::Handle handle_; | 610 CancelableRequestProvider::Handle handle_; |
| 596 | 611 |
| 597 // Set if the caller cancels this request. No callbacks should be made when | 612 // Set if the caller cancels this request. No callbacks should be made when |
| 598 // this is set. | 613 // this is set. |
| 599 base::CancellationFlag canceled_; | 614 base::CancellationFlag canceled_; |
| 600 | 615 |
| 601 private: | 616 private: |
| 617 // Executes the |forwarded_call| and notifies the provider and the consumer | |
| 618 // that this request has been completed. This must be called on the | |
| 619 // |callback_thread_|. | |
| 620 void ExecuteCallback(const base::Closure& forwarded_call) { | |
|
brettw
2011/10/01 16:26:12
Ditto
awong
2011/10/03 05:18:39
Done.
| |
| 621 DCHECK_EQ(callback_thread_, MessageLoop::current()); | |
| 622 | |
| 623 if (!canceled_.IsSet()) { | |
| 624 WillExecute(); | |
| 625 | |
| 626 // Execute the callback. | |
| 627 forwarded_call.Run(); | |
| 628 } | |
| 629 | |
| 630 // Notify the provider that the request is complete. The provider will | |
| 631 // notify the consumer for us. Note that it is possible for the callback to | |
| 632 // cancel this request; we must check canceled again. | |
| 633 if (!canceled_.IsSet()) | |
| 634 NotifyCompleted(); | |
| 635 } | |
| 636 | |
| 602 DISALLOW_COPY_AND_ASSIGN(CancelableRequestBase); | 637 DISALLOW_COPY_AND_ASSIGN(CancelableRequestBase); |
| 603 }; | 638 }; |
| 604 | 639 |
| 605 // Templatized class. This is the one you should use directly or inherit from. | 640 // Templatized class. This is the one you should use directly or inherit from. |
| 606 // The callback can be invoked by calling the ForwardResult() method. For this, | 641 // The callback can be invoked by calling the ForwardResult() method. For this, |
| 607 // you must either pack the parameters into a tuple, or use DispatchToMethod | 642 // you must either pack the parameters into a tuple, or use DispatchToMethod |
| 608 // (in tuple.h). | 643 // (in tuple.h). |
| 609 // | 644 // |
| 610 // If you inherit to add additional input parameters or to do more complex | 645 // If you inherit to add additional input parameters or to do more complex |
| 611 // memory management (see the bigger comment about this above), you can put | 646 // memory management (see the bigger comment about this above), you can put |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 624 // | 659 // |
| 625 // private: | 660 // private: |
| 626 // ~DoodieRequest() {} | 661 // ~DoodieRequest() {} |
| 627 // | 662 // |
| 628 // int input_arg1; | 663 // int input_arg1; |
| 629 // std::wstring input_arg2; | 664 // std::wstring input_arg2; |
| 630 // }; | 665 // }; |
| 631 template<typename CB> | 666 template<typename CB> |
| 632 class CancelableRequest : public CancelableRequestBase { | 667 class CancelableRequest : public CancelableRequestBase { |
| 633 public: | 668 public: |
| 669 // TODO(ajwong): After all calls have been migrated, remove this template in | |
| 670 // favor of the specialization on base::Callback<Sig>. | |
| 634 typedef CB CallbackType; // CallbackRunner<...> | 671 typedef CB CallbackType; // CallbackRunner<...> |
| 635 typedef typename CB::TupleType TupleType; // Tuple of the callback args. | 672 typedef typename CB::TupleType TupleType; // Tuple of the callback args. |
| 636 | 673 |
| 637 // The provider MUST call Init() (on the base class) before this is valid. | 674 // The provider MUST call Init() (on the base class) before this is valid. |
| 638 // This class will take ownership of the callback object and destroy it when | 675 // This class will take ownership of the callback object and destroy it when |
| 639 // appropriate. | 676 // appropriate. |
| 640 explicit CancelableRequest(CallbackType* callback) | 677 explicit CancelableRequest(CallbackType* callback) |
| 641 : CancelableRequestBase(), | 678 : CancelableRequestBase(), |
| 642 callback_(callback) { | 679 callback_(callback) { |
| 643 DCHECK(callback) << "We should always have a callback"; | 680 DCHECK(callback) << "We should always have a callback"; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 693 // cancel this request; we must check canceled again. | 730 // cancel this request; we must check canceled again. |
| 694 if (!canceled_.IsSet()) | 731 if (!canceled_.IsSet()) |
| 695 NotifyCompleted(); | 732 NotifyCompleted(); |
| 696 } | 733 } |
| 697 | 734 |
| 698 // This should only be executed if !canceled_.IsSet(), | 735 // This should only be executed if !canceled_.IsSet(), |
| 699 // otherwise the pointers may be invalid. | 736 // otherwise the pointers may be invalid. |
| 700 scoped_ptr<CallbackType> callback_; | 737 scoped_ptr<CallbackType> callback_; |
| 701 }; | 738 }; |
| 702 | 739 |
| 740 // CancelableRequest<> wraps a normal base::Callback<> for use in the | |
| 741 // CancelableRequest framework. | |
| 742 // | |
| 743 // When suing this class, the provider MUST call Init() (on the base class) | |
|
brettw
2011/10/01 16:26:12
suing -> using
awong
2011/10/03 05:18:39
Done.
| |
| 744 // before this is valid. | |
| 745 // | |
| 746 // The two functions ForwardResult(), and ForwardResultAsync() are used to | |
| 747 // invoke the wrapped callback on the correct thread. They are the same | |
| 748 // except that ForwardResult() will run the callback synchronously if | |
| 749 // we are already on the right thread. | |
| 750 // | |
| 751 // The caller does not need to check for cancel before calling ForwardResult() | |
| 752 // or ForwardResultAsync(). If the request has not been canceled, one of the | |
| 753 // these MUST be called. | |
| 754 // | |
| 755 // If there are any pointers in the parameters, they must live at least as | |
| 756 // long as the request so that it can be forwarded to the other thread. | |
| 757 // For complex objects, this would typically be done by having a derived | |
| 758 // request own the data itself. | |
| 759 // | |
| 760 // The following specializations handle different arities of base::Callbacks<>. | |
| 761 template<> | |
| 762 class CancelableRequest<base::Closure> : public CancelableRequestBase { | |
| 763 public: | |
| 764 typedef base::Closure CallbackType; | |
| 765 | |
| 766 explicit CancelableRequest(const CallbackType& callback) | |
| 767 : CancelableRequestBase(), | |
| 768 callback_(callback) { | |
| 769 DCHECK(!callback.is_null()) << "Callback must be initialized."; | |
| 770 } | |
| 771 | |
| 772 void ForwardResult(void) { | |
| 773 if (canceled()) return; | |
| 774 DoForward(callback_, false); | |
| 775 } | |
| 776 | |
| 777 void ForwardResultAsync() { | |
| 778 if (canceled()) return; | |
| 779 DoForward(callback_, true); | |
| 780 } | |
| 781 | |
| 782 protected: | |
| 783 virtual ~CancelableRequest() {} | |
| 784 | |
| 785 private: | |
| 786 CallbackType callback_; | |
| 787 }; | |
| 788 | |
| 789 template<typename A1> | |
| 790 class CancelableRequest<base::Callback<void(A1)> > : | |
| 791 public CancelableRequestBase { | |
| 792 public: | |
| 793 typedef base::Callback<void(A1)> CallbackType; | |
| 794 | |
| 795 explicit CancelableRequest(const CallbackType& callback) | |
| 796 : CancelableRequestBase(), | |
| 797 callback_(callback) { | |
| 798 DCHECK(!callback.is_null()) << "Callback must be initialized."; | |
| 799 } | |
| 800 | |
| 801 void ForwardResult(const A1& a1) { | |
| 802 if (canceled()) return; | |
| 803 DoForward(base::Bind(callback_, a1), false); | |
| 804 } | |
| 805 | |
| 806 void ForwardResultAsync(const A1& a1) { | |
| 807 if (canceled()) return; | |
| 808 DoForward(base::Bind(callback_, a1), true); | |
| 809 } | |
| 810 | |
| 811 protected: | |
| 812 virtual ~CancelableRequest() {} | |
| 813 | |
| 814 private: | |
| 815 CallbackType callback_; | |
| 816 }; | |
| 817 | |
| 818 template<typename A1, typename A2> | |
| 819 class CancelableRequest<base::Callback<void(A1,A2)> > : | |
| 820 public CancelableRequestBase { | |
| 821 public: | |
| 822 typedef base::Callback<void(A1,A2)> CallbackType; | |
| 823 | |
| 824 explicit CancelableRequest(const CallbackType& callback) | |
| 825 : CancelableRequestBase(), | |
| 826 callback_(callback) { | |
| 827 DCHECK(!callback.is_null()) << "Callback must be initialized."; | |
| 828 } | |
| 829 | |
| 830 void ForwardResult(const A1& a1, const A2& a2) { | |
| 831 if (canceled()) return; | |
| 832 DoForward(base::Bind(callback_, a1, a2), false); | |
| 833 } | |
| 834 | |
| 835 void ForwardResultAsync(const A1& a1, const A2& a2) { | |
| 836 if (canceled()) return; | |
| 837 DoForward(base::Bind(callback_, a1, a2), true); | |
| 838 } | |
| 839 | |
| 840 protected: | |
| 841 virtual ~CancelableRequest() {} | |
| 842 | |
| 843 private: | |
| 844 CallbackType callback_; | |
| 845 }; | |
| 846 | |
| 847 template<typename A1, typename A2, typename A3> | |
| 848 class CancelableRequest<base::Callback<void(A1,A2,A3)> > : | |
| 849 public CancelableRequestBase { | |
| 850 public: | |
| 851 typedef base::Callback<void(A1,A2,A3)> CallbackType; | |
| 852 | |
| 853 explicit CancelableRequest(const CallbackType& callback) | |
| 854 : CancelableRequestBase(), | |
| 855 callback_(callback) { | |
| 856 DCHECK(!callback.is_null()) << "Callback must be initialized."; | |
| 857 } | |
| 858 | |
| 859 void ForwardResult(const A1& a1, const A2& a2, const A3& a3) { | |
| 860 if (canceled()) return; | |
| 861 DoForward(base::Bind(callback_, a1, a2, a3), false); | |
| 862 } | |
| 863 | |
| 864 void ForwardResultAsync(const A1& a1, const A2& a2, const A3& a3) { | |
| 865 if (canceled()) return; | |
| 866 DoForward(base::Bind(callback_, a1, a2, a3), true); | |
| 867 } | |
| 868 | |
| 869 protected: | |
| 870 virtual ~CancelableRequest() {} | |
| 871 | |
| 872 private: | |
| 873 CallbackType callback_; | |
| 874 }; | |
| 875 | |
| 876 template<typename A1, typename A2, typename A3, typename A4> | |
| 877 class CancelableRequest<base::Callback<void(A1, A2, A3, A4)> > : | |
| 878 public CancelableRequestBase { | |
| 879 public: | |
| 880 typedef base::Callback<void(A1, A2, A3, A4)> CallbackType; | |
| 881 | |
| 882 explicit CancelableRequest(const CallbackType& callback) | |
| 883 : CancelableRequestBase(), | |
| 884 callback_(callback) { | |
| 885 DCHECK(!callback.is_null()) << "Callback must be initialized."; | |
| 886 } | |
| 887 | |
| 888 void ForwardResult(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { | |
| 889 if (canceled()) return; | |
| 890 DoForward(base::Bind(callback_, a1, a2, a3, a4), false); | |
| 891 } | |
| 892 | |
| 893 void ForwardResultAsync(const A1& a1, const A2& a2, const A3& a3, | |
| 894 const A4& a4) { | |
| 895 if (canceled()) return; | |
| 896 DoForward(base::Bind(callback_, a1, a2, a3, a4), true); | |
| 897 } | |
| 898 | |
| 899 protected: | |
| 900 virtual ~CancelableRequest() {} | |
| 901 | |
| 902 private: | |
| 903 CallbackType callback_; | |
| 904 }; | |
| 905 | |
| 906 template<typename A1, typename A2, typename A3, typename A4, typename A5> | |
| 907 class CancelableRequest<base::Callback<void(A1, A2, A3, A4, A5)> > : | |
| 908 public CancelableRequestBase { | |
| 909 public: | |
| 910 typedef base::Callback<void(A1, A2, A3, A4, A5)> CallbackType; | |
| 911 | |
| 912 explicit CancelableRequest(const CallbackType& callback) | |
| 913 : CancelableRequestBase(), | |
| 914 callback_(callback) { | |
| 915 DCHECK(!callback.is_null()) << "Callback must be initialized."; | |
| 916 } | |
| 917 | |
| 918 void ForwardResult(const A1& a1, const A2& a2, const A3& a3, const A4& a4, | |
| 919 const A5& a5) { | |
| 920 if (canceled()) return; | |
| 921 DoForward(base::Bind(callback_, a1, a2, a3, a4, a5), false); | |
| 922 } | |
| 923 | |
| 924 void ForwardResultAsync(const A1& a1, const A2& a2, const A3& a3, | |
| 925 const A4& a4, const A5& a5) { | |
| 926 if (canceled()) return; | |
| 927 DoForward(base::Bind(callback_, a1, a2, a3, a4, a5), true); | |
| 928 } | |
| 929 | |
| 930 protected: | |
| 931 virtual ~CancelableRequest() {} | |
| 932 | |
| 933 private: | |
| 934 CallbackType callback_; | |
| 935 }; | |
| 936 | |
| 937 template<typename A1, typename A2, typename A3, typename A4, typename A5, | |
| 938 typename A6> | |
| 939 class CancelableRequest<base::Callback<void(A1, A2, A3, A4, A5, A6)> > : | |
| 940 public CancelableRequestBase { | |
| 941 public: | |
| 942 typedef base::Callback<void(A1, A2, A3, A4, A5, A6)> CallbackType; | |
| 943 | |
| 944 explicit CancelableRequest(const CallbackType& callback) | |
| 945 : CancelableRequestBase(), | |
| 946 callback_(callback) { | |
| 947 DCHECK(!callback.is_null()) << "Callback must be initialized."; | |
| 948 } | |
| 949 | |
| 950 void ForwardResult(const A1& a1, const A2& a2, const A3& a3, const A4& a4, | |
| 951 const A5& a5, const A6& a6) { | |
| 952 if (canceled()) return; | |
| 953 DoForward(base::Bind(callback_, a1, a2, a3, a4, a5, a6), false); | |
| 954 } | |
| 955 | |
| 956 void ForwardResultAsync(const A1& a1, const A2& a2, const A3& a3, | |
| 957 const A4& a4, const A5& a5, const A6& a6) { | |
| 958 if (canceled()) return; | |
| 959 DoForward(base::Bind(callback_, a1, a2, a3, a4, a5, a6), true); | |
| 960 } | |
| 961 | |
| 962 protected: | |
| 963 virtual ~CancelableRequest() {} | |
| 964 | |
| 965 private: | |
| 966 CallbackType callback_; | |
| 967 }; | |
| 968 | |
| 703 // A CancelableRequest with a single value. This is intended for use when | 969 // A CancelableRequest with a single value. This is intended for use when |
| 704 // the provider provides a single value. The provider fills the result into | 970 // the provider provides a single value. The provider fills the result into |
| 705 // the value, and notifies the request with a pointer to the value. For example, | 971 // the value, and notifies the request with a pointer to the value. For example, |
| 706 // HistoryService has many methods that callback with a vector. Use the | 972 // HistoryService has many methods that callback with a vector. Use the |
| 707 // following pattern for this: | 973 // following pattern for this: |
| 708 // 1. Define the callback: | 974 // 1. Define the callback: |
| 709 // typedef Callback2<Handle, std::vector<Foo>*>::Type FooCallback; | 975 // typedef Callback2<Handle, std::vector<Foo>*>::Type FooCallback; |
| 710 // 2. Define the CancelableRequest1 type. | 976 // 2. Define the CancelableRequest1 type. |
| 711 // typedef CancelableRequest1<FooCallback, std::vector<Foo>> FooRequest; | 977 // typedef CancelableRequest1<FooCallback, std::vector<Foo>> FooRequest; |
| 712 // 3. The provider method should then fillin the contents of the vector, | 978 // 3. The provider method should then fillin the contents of the vector, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 724 } | 990 } |
| 725 | 991 |
| 726 // The value. | 992 // The value. |
| 727 Type value; | 993 Type value; |
| 728 | 994 |
| 729 protected: | 995 protected: |
| 730 virtual ~CancelableRequest1() {} | 996 virtual ~CancelableRequest1() {} |
| 731 }; | 997 }; |
| 732 | 998 |
| 733 #endif // CONTENT_BROWSER_CANCELABLE_REQUEST_H_ | 999 #endif // CONTENT_BROWSER_CANCELABLE_REQUEST_H_ |
| OLD | NEW |