1 // Copyright 2010-2018, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 #ifndef MOZC_BASE_PEPPER_SCOPED_OBJ_H_
31 #define MOZC_BASE_PEPPER_SCOPED_OBJ_H_
32 
33 #ifdef OS_NACL
34 
35 #include <ppapi/utility/completion_callback_factory.h>
36 
37 #include "base/port.h"
38 #include "base/unnamed_event.h"
39 
40 namespace mozc {
41 
42 // Some Pepper classes have to be deleted in the NaCl main thread.
43 // scoped_main_thread_destructed_object template guarantees that the object will
44 // be deleted in the NaCl main thread.
45 template <class C>
46 class scoped_main_thread_destructed_object {
47  public:
48   typedef C element_type;
49 
ptr_(p)50   explicit scoped_main_thread_destructed_object(C *p = NULL) : ptr_(p) {
51     cc_factory_.Initialize(this);
52   }
53 
~scoped_main_thread_destructed_object()54   ~scoped_main_thread_destructed_object() {
55     if (ptr_ != NULL) {
56       DeleteObject();
57     }
58   }
59 
60   void reset(C *p = NULL) {
61     if (p != ptr_) {
62       if (ptr_ != NULL) {
63         DeleteObject();
64       }
65       ptr_ = p;
66     }
67   }
68 
69   C &operator*() const {
70     assert(ptr_ != NULL);
71     return *ptr_;
72   }
73 
74   C *operator->() const  {
75     assert(ptr_ != NULL);
76     return ptr_;
77   }
78 
get()79   C *get() const {
80     return ptr_;
81   }
82 
83  private:
DeleteObject()84   void DeleteObject() {
85     if (!pp::Module::Get()->core()->IsMainThread()) {
86       pp::Module::Get()->core()->CallOnMainThread(
87           0,
88           cc_factory_.NewCallback(
89               &scoped_main_thread_destructed_object::DeleteObjectImpl));
90     } else {
91       DeleteObjectImpl(PP_OK);
92     }
93     event_.Wait(-1);
94   }
95 
DeleteObjectImpl(int32_t result)96   void DeleteObjectImpl(int32_t result) {
97     delete ptr_;
98     event_.Notify();
99   }
100 
101   C *ptr_;
102   UnnamedEvent event_;
103   pp::CompletionCallbackFactory<scoped_main_thread_destructed_object>
104       cc_factory_;
105   DISALLOW_COPY_AND_ASSIGN(scoped_main_thread_destructed_object);
106 };
107 
108 }  // namespace mozc
109 
110 #endif  // OS_NACL
111 
112 #endif  // MOZC_BASE_PEPPER_SCOPED_OBJ_H_
113