OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 #ifndef PPAPI_UTILITY_COMPLETION_CALLBACK_FACTORY_H_ | 5 #ifndef PPAPI_UTILITY_COMPLETION_CALLBACK_FACTORY_H_ |
6 #define PPAPI_UTILITY_COMPLETION_CALLBACK_FACTORY_H_ | 6 #define PPAPI_UTILITY_COMPLETION_CALLBACK_FACTORY_H_ |
7 | 7 |
8 #include "ppapi/cpp/completion_callback.h" | 8 #include "ppapi/cpp/completion_callback.h" |
9 #include "ppapi/utility/non_thread_safe_ref_count.h" | 9 #include "ppapi/utility/non_thread_safe_ref_count.h" |
10 | 10 |
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
563 ~CallbackData() { | 563 ~CallbackData() { |
564 back_pointer_->Release(); | 564 back_pointer_->Release(); |
565 delete dispatcher_; | 565 delete dispatcher_; |
566 } | 566 } |
567 | 567 |
568 Dispatcher* dispatcher() { return dispatcher_; } | 568 Dispatcher* dispatcher() { return dispatcher_; } |
569 | 569 |
570 static void Thunk(void* user_data, int32_t result) { | 570 static void Thunk(void* user_data, int32_t result) { |
571 Self* self = static_cast<Self*>(user_data); | 571 Self* self = static_cast<Self*>(user_data); |
572 T* object = self->back_pointer_->GetObject(); | 572 T* object = self->back_pointer_->GetObject(); |
573 if (object) | 573 (*self->dispatcher_)(object, result); |
574 (*self->dispatcher_)(object, result); | |
575 delete self; | 574 delete self; |
576 } | 575 } |
577 | 576 |
578 private: | 577 private: |
579 typedef CallbackData<Dispatcher> Self; | 578 typedef CallbackData<Dispatcher> Self; |
580 BackPointer* back_pointer_; // We own a ref to this refcounted object. | 579 BackPointer* back_pointer_; // We own a ref to this refcounted object. |
581 Dispatcher* dispatcher_; // We own this pointer. | 580 Dispatcher* dispatcher_; // We own this pointer. |
582 | 581 |
583 // Disallow copying & assignment. | 582 // Disallow copying & assignment. |
584 CallbackData(const CallbackData<Dispatcher>&); | 583 CallbackData(const CallbackData<Dispatcher>&); |
585 CallbackData<Dispatcher>& operator=(const CallbackData<Dispatcher>&); | 584 CallbackData<Dispatcher>& operator=(const CallbackData<Dispatcher>&); |
586 }; | 585 }; |
587 | 586 |
588 template <typename Method> | 587 template <typename Method> |
589 class Dispatcher0 { | 588 class Dispatcher0 { |
590 public: | 589 public: |
591 Dispatcher0() : method_(NULL) {} | 590 Dispatcher0() : method_(NULL) {} |
592 explicit Dispatcher0(Method method) : method_(method) { | 591 explicit Dispatcher0(Method method) : method_(method) { |
593 } | 592 } |
594 void operator()(T* object, int32_t result) { | 593 void operator()(T* object, int32_t result) { |
595 (object->*method_)(result); | 594 if (object) |
brettw
2012/04/03 21:23:03
I don't totally get this change, can you clarify w
yzshen1
2012/04/04 00:36:34
Because I change Thunk() to call Dispatcher*::oper
| |
595 (object->*method_)(result); | |
596 } | 596 } |
597 private: | 597 private: |
598 Method method_; | 598 Method method_; |
599 }; | 599 }; |
600 | 600 |
601 template <typename Output, typename Method> | 601 template <typename Output, typename Method> |
602 class DispatcherWithOutput0 { | 602 class DispatcherWithOutput0 { |
603 public: | 603 public: |
604 typedef Output OutputType; | 604 typedef Output OutputType; |
605 typedef internal::CallbackOutputTraits<Output> Traits; | 605 typedef internal::CallbackOutputTraits<Output> Traits; |
606 | 606 |
607 DispatcherWithOutput0() : method_(NULL) {} | 607 DispatcherWithOutput0() |
608 DispatcherWithOutput0(Method method) : method_(method) { | 608 : method_(NULL), |
609 output_() { | |
610 } | |
611 DispatcherWithOutput0(Method method) | |
612 : method_(method), | |
613 output_() { | |
609 } | 614 } |
610 void operator()(T* object, int32_t result) { | 615 void operator()(T* object, int32_t result) { |
611 (object->*method_)(result, Traits::StorageToPluginArg(output_)); | 616 // We must call Traits::StorageToPluginArg() even if we don't need to call |
617 // the callback anymore, otherwise we may leak resource or var references. | |
618 if (object) | |
619 (object->*method_)(result, Traits::StorageToPluginArg(output_)); | |
620 else | |
621 Traits::StorageToPluginArg(output_); | |
612 } | 622 } |
613 typename Traits::StorageType* output() { | 623 typename Traits::StorageType* output() { |
614 return &output_; | 624 return &output_; |
615 } | 625 } |
616 private: | 626 private: |
617 Method method_; | 627 Method method_; |
618 | 628 |
619 typename Traits::StorageType output_; | 629 typename Traits::StorageType output_; |
620 }; | 630 }; |
621 | 631 |
622 template <typename Method, typename A> | 632 template <typename Method, typename A> |
623 class Dispatcher1 { | 633 class Dispatcher1 { |
624 public: | 634 public: |
625 Dispatcher1() : method_(NULL) {} | 635 Dispatcher1() |
636 : method_(NULL), | |
637 a_() { | |
brettw
2012/04/03 21:23:03
Do you initialize these arguments just for complet
yzshen1
2012/04/04 00:36:34
Yes. I understand that.
If we want to init |metho
| |
638 } | |
626 Dispatcher1(Method method, const A& a) | 639 Dispatcher1(Method method, const A& a) |
627 : method_(method), | 640 : method_(method), |
628 a_(a) { | 641 a_(a) { |
629 } | 642 } |
630 void operator()(T* object, int32_t result) { | 643 void operator()(T* object, int32_t result) { |
631 (object->*method_)(result, a_); | 644 if (object) |
645 (object->*method_)(result, a_); | |
632 } | 646 } |
633 private: | 647 private: |
634 Method method_; | 648 Method method_; |
635 A a_; | 649 A a_; |
636 }; | 650 }; |
637 | 651 |
638 template <typename Output, typename Method, typename A> | 652 template <typename Output, typename Method, typename A> |
639 class DispatcherWithOutput1 { | 653 class DispatcherWithOutput1 { |
640 public: | 654 public: |
641 typedef Output OutputType; | 655 typedef Output OutputType; |
642 typedef internal::CallbackOutputTraits<Output> Traits; | 656 typedef internal::CallbackOutputTraits<Output> Traits; |
643 | 657 |
644 DispatcherWithOutput1() : method_(NULL) {} | 658 DispatcherWithOutput1() |
659 : method_(NULL), | |
660 a_(), | |
661 output_() { | |
662 } | |
645 DispatcherWithOutput1(Method method, const A& a) | 663 DispatcherWithOutput1(Method method, const A& a) |
646 : method_(method), | 664 : method_(method), |
647 a_(a) { | 665 a_(a), |
666 output_() { | |
648 } | 667 } |
649 void operator()(T* object, int32_t result) { | 668 void operator()(T* object, int32_t result) { |
650 (object->*method_)(result, Traits::StorageToPluginArg(output_), a_); | 669 // We must call Traits::StorageToPluginArg() even if we don't need to call |
670 // the callback anymore, otherwise we may leak resource or var references. | |
671 if (object) | |
672 (object->*method_)(result, Traits::StorageToPluginArg(output_), a_); | |
673 else | |
674 Traits::StorageToPluginArg(output_); | |
651 } | 675 } |
652 typename Traits::StorageType* output() { | 676 typename Traits::StorageType* output() { |
653 return &output_; | 677 return &output_; |
654 } | 678 } |
655 private: | 679 private: |
656 Method method_; | 680 Method method_; |
657 A a_; | 681 A a_; |
658 | 682 |
659 typename Traits::StorageType output_; | 683 typename Traits::StorageType output_; |
660 }; | 684 }; |
661 | 685 |
662 template <typename Method, typename A, typename B> | 686 template <typename Method, typename A, typename B> |
663 class Dispatcher2 { | 687 class Dispatcher2 { |
664 public: | 688 public: |
665 Dispatcher2() : method_(NULL) {} | 689 Dispatcher2() |
690 : method_(NULL), | |
691 a_(), | |
692 b_() { | |
693 } | |
666 Dispatcher2(Method method, const A& a, const B& b) | 694 Dispatcher2(Method method, const A& a, const B& b) |
667 : method_(method), | 695 : method_(method), |
668 a_(a), | 696 a_(a), |
669 b_(b) { | 697 b_(b) { |
670 } | 698 } |
671 void operator()(T* object, int32_t result) { | 699 void operator()(T* object, int32_t result) { |
672 (object->*method_)(result, a_, b_); | 700 if (object) |
701 (object->*method_)(result, a_, b_); | |
673 } | 702 } |
674 private: | 703 private: |
675 Method method_; | 704 Method method_; |
676 A a_; | 705 A a_; |
677 B b_; | 706 B b_; |
678 }; | 707 }; |
679 | 708 |
680 template <typename Output, typename Method, typename A, typename B> | 709 template <typename Output, typename Method, typename A, typename B> |
681 class DispatcherWithOutput2 { | 710 class DispatcherWithOutput2 { |
682 public: | 711 public: |
683 typedef Output OutputType; | 712 typedef Output OutputType; |
684 typedef internal::CallbackOutputTraits<Output> Traits; | 713 typedef internal::CallbackOutputTraits<Output> Traits; |
685 | 714 |
686 DispatcherWithOutput2() : method_(NULL) {} | 715 DispatcherWithOutput2() |
716 : method_(NULL), | |
717 a_(), | |
718 b_(), | |
719 output_() { | |
720 } | |
687 DispatcherWithOutput2(Method method, const A& a, const B& b) | 721 DispatcherWithOutput2(Method method, const A& a, const B& b) |
688 : method_(method), | 722 : method_(method), |
689 a_(a), | 723 a_(a), |
690 b_(b) { | 724 b_(b), |
725 output_() { | |
691 } | 726 } |
692 void operator()(T* object, int32_t result) { | 727 void operator()(T* object, int32_t result) { |
693 (object->*method_)(result, Traits::StorageToPluginArg(output_), a_, b_); | 728 // We must call Traits::StorageToPluginArg() even if we don't need to call |
729 // the callback anymore, otherwise we may leak resource or var references. | |
730 if (object) | |
731 (object->*method_)(result, Traits::StorageToPluginArg(output_), a_, b_); | |
732 else | |
733 Traits::StorageToPluginArg(output_); | |
694 } | 734 } |
695 typename Traits::StorageType* output() { | 735 typename Traits::StorageType* output() { |
696 return &output_; | 736 return &output_; |
697 } | 737 } |
698 private: | 738 private: |
699 Method method_; | 739 Method method_; |
700 A a_; | 740 A a_; |
701 B b_; | 741 B b_; |
702 | 742 |
703 typename Traits::StorageType output_; | 743 typename Traits::StorageType output_; |
704 }; | 744 }; |
705 | 745 |
706 template <typename Method, typename A, typename B, typename C> | 746 template <typename Method, typename A, typename B, typename C> |
707 class Dispatcher3 { | 747 class Dispatcher3 { |
708 public: | 748 public: |
709 Dispatcher3() : method_(NULL) {} | 749 Dispatcher3() |
750 : method_(NULL), | |
751 a_(), | |
752 b_(), | |
753 c_() { | |
754 } | |
710 Dispatcher3(Method method, const A& a, const B& b, const C& c) | 755 Dispatcher3(Method method, const A& a, const B& b, const C& c) |
711 : method_(method), | 756 : method_(method), |
712 a_(a), | 757 a_(a), |
713 b_(b), | 758 b_(b), |
714 c_(c) { | 759 c_(c) { |
715 } | 760 } |
716 void operator()(T* object, int32_t result) { | 761 void operator()(T* object, int32_t result) { |
717 (object->*method_)(result, a_, b_, c_); | 762 if (object) |
763 (object->*method_)(result, a_, b_, c_); | |
718 } | 764 } |
719 private: | 765 private: |
720 Method method_; | 766 Method method_; |
721 A a_; | 767 A a_; |
722 B b_; | 768 B b_; |
723 C c_; | 769 C c_; |
724 }; | 770 }; |
725 | 771 |
726 template <typename Output, typename Method, typename A, typename B, | 772 template <typename Output, typename Method, typename A, typename B, |
727 typename C> | 773 typename C> |
728 class DispatcherWithOutput3 { | 774 class DispatcherWithOutput3 { |
729 public: | 775 public: |
730 typedef Output OutputType; | 776 typedef Output OutputType; |
731 typedef internal::CallbackOutputTraits<Output> Traits; | 777 typedef internal::CallbackOutputTraits<Output> Traits; |
732 | 778 |
733 DispatcherWithOutput3() : method_(NULL) {} | 779 DispatcherWithOutput3() |
780 : method_(NULL), | |
781 a_(), | |
782 b_(), | |
783 c_(), | |
784 output_() { | |
785 } | |
734 DispatcherWithOutput3(Method method, const A& a, const B& b, const C& c) | 786 DispatcherWithOutput3(Method method, const A& a, const B& b, const C& c) |
735 : method_(method), | 787 : method_(method), |
736 a_(a), | 788 a_(a), |
737 b_(b), | 789 b_(b), |
738 c_(c) { | 790 c_(c), |
791 output_() { | |
739 } | 792 } |
740 void operator()(T* object, int32_t result) { | 793 void operator()(T* object, int32_t result) { |
741 (object->*method_)(result, Traits::StorageToPluginArg(output_), | 794 // We must call Traits::StorageToPluginArg() even if we don't need to call |
742 a_, b_, c_); | 795 // the callback anymore, otherwise we may leak resource or var references. |
796 if (object) { | |
797 (object->*method_)(result, Traits::StorageToPluginArg(output_), | |
798 a_, b_, c_); | |
799 } else { | |
800 Traits::StorageToPluginArg(output_); | |
801 } | |
743 } | 802 } |
744 typename Traits::StorageType* output() { | 803 typename Traits::StorageType* output() { |
745 return &output_; | 804 return &output_; |
746 } | 805 } |
747 private: | 806 private: |
748 Method method_; | 807 Method method_; |
749 A a_; | 808 A a_; |
750 B b_; | 809 B b_; |
751 C c_; | 810 C c_; |
752 | 811 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
791 CompletionCallbackFactory(const CompletionCallbackFactory&); | 850 CompletionCallbackFactory(const CompletionCallbackFactory&); |
792 CompletionCallbackFactory& operator=(const CompletionCallbackFactory&); | 851 CompletionCallbackFactory& operator=(const CompletionCallbackFactory&); |
793 | 852 |
794 T* object_; | 853 T* object_; |
795 BackPointer* back_pointer_; | 854 BackPointer* back_pointer_; |
796 }; | 855 }; |
797 | 856 |
798 } // namespace pp | 857 } // namespace pp |
799 | 858 |
800 #endif // PPAPI_UTILITY_COMPLETION_CALLBACK_FACTORY_H_ | 859 #endif // PPAPI_UTILITY_COMPLETION_CALLBACK_FACTORY_H_ |
OLD | NEW |