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 |
574 (*self->dispatcher_)(object, result); | 574 // Please note that |object| may be NULL at this point. But we still need |
| 575 // to call into Dispatcher::operator() in that case, so that it can do |
| 576 // necessary cleanup. |
| 577 (*self->dispatcher_)(object, result); |
| 578 |
575 delete self; | 579 delete self; |
576 } | 580 } |
577 | 581 |
578 private: | 582 private: |
579 typedef CallbackData<Dispatcher> Self; | 583 typedef CallbackData<Dispatcher> Self; |
580 BackPointer* back_pointer_; // We own a ref to this refcounted object. | 584 BackPointer* back_pointer_; // We own a ref to this refcounted object. |
581 Dispatcher* dispatcher_; // We own this pointer. | 585 Dispatcher* dispatcher_; // We own this pointer. |
582 | 586 |
583 // Disallow copying & assignment. | 587 // Disallow copying & assignment. |
584 CallbackData(const CallbackData<Dispatcher>&); | 588 CallbackData(const CallbackData<Dispatcher>&); |
585 CallbackData<Dispatcher>& operator=(const CallbackData<Dispatcher>&); | 589 CallbackData<Dispatcher>& operator=(const CallbackData<Dispatcher>&); |
586 }; | 590 }; |
587 | 591 |
588 template <typename Method> | 592 template <typename Method> |
589 class Dispatcher0 { | 593 class Dispatcher0 { |
590 public: | 594 public: |
591 Dispatcher0() : method_(NULL) {} | 595 Dispatcher0() : method_(NULL) {} |
592 explicit Dispatcher0(Method method) : method_(method) { | 596 explicit Dispatcher0(Method method) : method_(method) { |
593 } | 597 } |
594 void operator()(T* object, int32_t result) { | 598 void operator()(T* object, int32_t result) { |
595 (object->*method_)(result); | 599 if (object) |
| 600 (object->*method_)(result); |
596 } | 601 } |
597 private: | 602 private: |
598 Method method_; | 603 Method method_; |
599 }; | 604 }; |
600 | 605 |
601 template <typename Output, typename Method> | 606 template <typename Output, typename Method> |
602 class DispatcherWithOutput0 { | 607 class DispatcherWithOutput0 { |
603 public: | 608 public: |
604 typedef Output OutputType; | 609 typedef Output OutputType; |
605 typedef internal::CallbackOutputTraits<Output> Traits; | 610 typedef internal::CallbackOutputTraits<Output> Traits; |
606 | 611 |
607 DispatcherWithOutput0() : method_(NULL) {} | 612 DispatcherWithOutput0() |
608 DispatcherWithOutput0(Method method) : method_(method) { | 613 : method_(NULL), |
| 614 output_() { |
| 615 } |
| 616 DispatcherWithOutput0(Method method) |
| 617 : method_(method), |
| 618 output_() { |
609 } | 619 } |
610 void operator()(T* object, int32_t result) { | 620 void operator()(T* object, int32_t result) { |
611 (object->*method_)(result, Traits::StorageToPluginArg(output_)); | 621 // We must call Traits::StorageToPluginArg() even if we don't need to call |
| 622 // the callback anymore, otherwise we may leak resource or var references. |
| 623 if (object) |
| 624 (object->*method_)(result, Traits::StorageToPluginArg(output_)); |
| 625 else |
| 626 Traits::StorageToPluginArg(output_); |
612 } | 627 } |
613 typename Traits::StorageType* output() { | 628 typename Traits::StorageType* output() { |
614 return &output_; | 629 return &output_; |
615 } | 630 } |
616 private: | 631 private: |
617 Method method_; | 632 Method method_; |
618 | 633 |
619 typename Traits::StorageType output_; | 634 typename Traits::StorageType output_; |
620 }; | 635 }; |
621 | 636 |
622 template <typename Method, typename A> | 637 template <typename Method, typename A> |
623 class Dispatcher1 { | 638 class Dispatcher1 { |
624 public: | 639 public: |
625 Dispatcher1() : method_(NULL) {} | 640 Dispatcher1() |
| 641 : method_(NULL), |
| 642 a_() { |
| 643 } |
626 Dispatcher1(Method method, const A& a) | 644 Dispatcher1(Method method, const A& a) |
627 : method_(method), | 645 : method_(method), |
628 a_(a) { | 646 a_(a) { |
629 } | 647 } |
630 void operator()(T* object, int32_t result) { | 648 void operator()(T* object, int32_t result) { |
631 (object->*method_)(result, a_); | 649 if (object) |
| 650 (object->*method_)(result, a_); |
632 } | 651 } |
633 private: | 652 private: |
634 Method method_; | 653 Method method_; |
635 A a_; | 654 A a_; |
636 }; | 655 }; |
637 | 656 |
638 template <typename Output, typename Method, typename A> | 657 template <typename Output, typename Method, typename A> |
639 class DispatcherWithOutput1 { | 658 class DispatcherWithOutput1 { |
640 public: | 659 public: |
641 typedef Output OutputType; | 660 typedef Output OutputType; |
642 typedef internal::CallbackOutputTraits<Output> Traits; | 661 typedef internal::CallbackOutputTraits<Output> Traits; |
643 | 662 |
644 DispatcherWithOutput1() : method_(NULL) {} | 663 DispatcherWithOutput1() |
| 664 : method_(NULL), |
| 665 a_(), |
| 666 output_() { |
| 667 } |
645 DispatcherWithOutput1(Method method, const A& a) | 668 DispatcherWithOutput1(Method method, const A& a) |
646 : method_(method), | 669 : method_(method), |
647 a_(a) { | 670 a_(a), |
| 671 output_() { |
648 } | 672 } |
649 void operator()(T* object, int32_t result) { | 673 void operator()(T* object, int32_t result) { |
650 (object->*method_)(result, Traits::StorageToPluginArg(output_), a_); | 674 // We must call Traits::StorageToPluginArg() even if we don't need to call |
| 675 // the callback anymore, otherwise we may leak resource or var references. |
| 676 if (object) |
| 677 (object->*method_)(result, Traits::StorageToPluginArg(output_), a_); |
| 678 else |
| 679 Traits::StorageToPluginArg(output_); |
651 } | 680 } |
652 typename Traits::StorageType* output() { | 681 typename Traits::StorageType* output() { |
653 return &output_; | 682 return &output_; |
654 } | 683 } |
655 private: | 684 private: |
656 Method method_; | 685 Method method_; |
657 A a_; | 686 A a_; |
658 | 687 |
659 typename Traits::StorageType output_; | 688 typename Traits::StorageType output_; |
660 }; | 689 }; |
661 | 690 |
662 template <typename Method, typename A, typename B> | 691 template <typename Method, typename A, typename B> |
663 class Dispatcher2 { | 692 class Dispatcher2 { |
664 public: | 693 public: |
665 Dispatcher2() : method_(NULL) {} | 694 Dispatcher2() |
| 695 : method_(NULL), |
| 696 a_(), |
| 697 b_() { |
| 698 } |
666 Dispatcher2(Method method, const A& a, const B& b) | 699 Dispatcher2(Method method, const A& a, const B& b) |
667 : method_(method), | 700 : method_(method), |
668 a_(a), | 701 a_(a), |
669 b_(b) { | 702 b_(b) { |
670 } | 703 } |
671 void operator()(T* object, int32_t result) { | 704 void operator()(T* object, int32_t result) { |
672 (object->*method_)(result, a_, b_); | 705 if (object) |
| 706 (object->*method_)(result, a_, b_); |
673 } | 707 } |
674 private: | 708 private: |
675 Method method_; | 709 Method method_; |
676 A a_; | 710 A a_; |
677 B b_; | 711 B b_; |
678 }; | 712 }; |
679 | 713 |
680 template <typename Output, typename Method, typename A, typename B> | 714 template <typename Output, typename Method, typename A, typename B> |
681 class DispatcherWithOutput2 { | 715 class DispatcherWithOutput2 { |
682 public: | 716 public: |
683 typedef Output OutputType; | 717 typedef Output OutputType; |
684 typedef internal::CallbackOutputTraits<Output> Traits; | 718 typedef internal::CallbackOutputTraits<Output> Traits; |
685 | 719 |
686 DispatcherWithOutput2() : method_(NULL) {} | 720 DispatcherWithOutput2() |
| 721 : method_(NULL), |
| 722 a_(), |
| 723 b_(), |
| 724 output_() { |
| 725 } |
687 DispatcherWithOutput2(Method method, const A& a, const B& b) | 726 DispatcherWithOutput2(Method method, const A& a, const B& b) |
688 : method_(method), | 727 : method_(method), |
689 a_(a), | 728 a_(a), |
690 b_(b) { | 729 b_(b), |
| 730 output_() { |
691 } | 731 } |
692 void operator()(T* object, int32_t result) { | 732 void operator()(T* object, int32_t result) { |
693 (object->*method_)(result, Traits::StorageToPluginArg(output_), a_, b_); | 733 // We must call Traits::StorageToPluginArg() even if we don't need to call |
| 734 // the callback anymore, otherwise we may leak resource or var references. |
| 735 if (object) |
| 736 (object->*method_)(result, Traits::StorageToPluginArg(output_), a_, b_); |
| 737 else |
| 738 Traits::StorageToPluginArg(output_); |
694 } | 739 } |
695 typename Traits::StorageType* output() { | 740 typename Traits::StorageType* output() { |
696 return &output_; | 741 return &output_; |
697 } | 742 } |
698 private: | 743 private: |
699 Method method_; | 744 Method method_; |
700 A a_; | 745 A a_; |
701 B b_; | 746 B b_; |
702 | 747 |
703 typename Traits::StorageType output_; | 748 typename Traits::StorageType output_; |
704 }; | 749 }; |
705 | 750 |
706 template <typename Method, typename A, typename B, typename C> | 751 template <typename Method, typename A, typename B, typename C> |
707 class Dispatcher3 { | 752 class Dispatcher3 { |
708 public: | 753 public: |
709 Dispatcher3() : method_(NULL) {} | 754 Dispatcher3() |
| 755 : method_(NULL), |
| 756 a_(), |
| 757 b_(), |
| 758 c_() { |
| 759 } |
710 Dispatcher3(Method method, const A& a, const B& b, const C& c) | 760 Dispatcher3(Method method, const A& a, const B& b, const C& c) |
711 : method_(method), | 761 : method_(method), |
712 a_(a), | 762 a_(a), |
713 b_(b), | 763 b_(b), |
714 c_(c) { | 764 c_(c) { |
715 } | 765 } |
716 void operator()(T* object, int32_t result) { | 766 void operator()(T* object, int32_t result) { |
717 (object->*method_)(result, a_, b_, c_); | 767 if (object) |
| 768 (object->*method_)(result, a_, b_, c_); |
718 } | 769 } |
719 private: | 770 private: |
720 Method method_; | 771 Method method_; |
721 A a_; | 772 A a_; |
722 B b_; | 773 B b_; |
723 C c_; | 774 C c_; |
724 }; | 775 }; |
725 | 776 |
726 template <typename Output, typename Method, typename A, typename B, | 777 template <typename Output, typename Method, typename A, typename B, |
727 typename C> | 778 typename C> |
728 class DispatcherWithOutput3 { | 779 class DispatcherWithOutput3 { |
729 public: | 780 public: |
730 typedef Output OutputType; | 781 typedef Output OutputType; |
731 typedef internal::CallbackOutputTraits<Output> Traits; | 782 typedef internal::CallbackOutputTraits<Output> Traits; |
732 | 783 |
733 DispatcherWithOutput3() : method_(NULL) {} | 784 DispatcherWithOutput3() |
| 785 : method_(NULL), |
| 786 a_(), |
| 787 b_(), |
| 788 c_(), |
| 789 output_() { |
| 790 } |
734 DispatcherWithOutput3(Method method, const A& a, const B& b, const C& c) | 791 DispatcherWithOutput3(Method method, const A& a, const B& b, const C& c) |
735 : method_(method), | 792 : method_(method), |
736 a_(a), | 793 a_(a), |
737 b_(b), | 794 b_(b), |
738 c_(c) { | 795 c_(c), |
| 796 output_() { |
739 } | 797 } |
740 void operator()(T* object, int32_t result) { | 798 void operator()(T* object, int32_t result) { |
741 (object->*method_)(result, Traits::StorageToPluginArg(output_), | 799 // We must call Traits::StorageToPluginArg() even if we don't need to call |
742 a_, b_, c_); | 800 // the callback anymore, otherwise we may leak resource or var references. |
| 801 if (object) { |
| 802 (object->*method_)(result, Traits::StorageToPluginArg(output_), |
| 803 a_, b_, c_); |
| 804 } else { |
| 805 Traits::StorageToPluginArg(output_); |
| 806 } |
743 } | 807 } |
744 typename Traits::StorageType* output() { | 808 typename Traits::StorageType* output() { |
745 return &output_; | 809 return &output_; |
746 } | 810 } |
747 private: | 811 private: |
748 Method method_; | 812 Method method_; |
749 A a_; | 813 A a_; |
750 B b_; | 814 B b_; |
751 C c_; | 815 C c_; |
752 | 816 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
791 CompletionCallbackFactory(const CompletionCallbackFactory&); | 855 CompletionCallbackFactory(const CompletionCallbackFactory&); |
792 CompletionCallbackFactory& operator=(const CompletionCallbackFactory&); | 856 CompletionCallbackFactory& operator=(const CompletionCallbackFactory&); |
793 | 857 |
794 T* object_; | 858 T* object_; |
795 BackPointer* back_pointer_; | 859 BackPointer* back_pointer_; |
796 }; | 860 }; |
797 | 861 |
798 } // namespace pp | 862 } // namespace pp |
799 | 863 |
800 #endif // PPAPI_UTILITY_COMPLETION_CALLBACK_FACTORY_H_ | 864 #endif // PPAPI_UTILITY_COMPLETION_CALLBACK_FACTORY_H_ |
OLD | NEW |