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 #ifndef PPAPI_CPP_COMPLETION_CALLBACK_H_ | 5 #ifndef PPAPI_CPP_COMPLETION_CALLBACK_H_ |
6 #define PPAPI_CPP_COMPLETION_CALLBACK_H_ | 6 #define PPAPI_CPP_COMPLETION_CALLBACK_H_ |
7 | 7 |
8 #include "ppapi/c/pp_completion_callback.h" | 8 #include "ppapi/c/pp_completion_callback.h" |
9 #include "ppapi/c/pp_errors.h" | |
9 #include "ppapi/cpp/logging.h" | 10 #include "ppapi/cpp/logging.h" |
10 #include "ppapi/cpp/non_thread_safe_ref_count.h" | 11 #include "ppapi/cpp/non_thread_safe_ref_count.h" |
11 | 12 |
12 namespace pp { | 13 namespace pp { |
13 | 14 |
14 // A CompletionCallback provides a wrapper around PP_CompletionCallback. | 15 // A CompletionCallback provides a wrapper around PP_CompletionCallback. |
15 class CompletionCallback { | 16 class CompletionCallback { |
16 public: | 17 public: |
17 // Use this special constructor to create a 'blocking' CompletionCallback | 18 // Use this special constructor to create a 'blocking' CompletionCallback |
18 // that may be passed to a method to indicate that the calling thread should | 19 // that may be passed to a method to indicate that the calling thread should |
19 // be blocked until the asynchronous operation corresponding to the method | 20 // be blocked until the asynchronous operation corresponding to the method |
20 // completes. | 21 // completes. |
21 struct Block {}; | 22 struct Block {}; |
22 CompletionCallback(Block) { | 23 CompletionCallback(Block) { |
23 cc_ = PP_BlockUntilComplete(); | 24 cc_ = PP_BlockUntilComplete(); |
24 } | 25 } |
25 | 26 |
26 CompletionCallback(PP_CompletionCallback_Func func, void* user_data) { | 27 CompletionCallback(PP_CompletionCallback_Func func, void* user_data) { |
27 cc_ = PP_MakeCompletionCallback(func, user_data); | 28 cc_ = PP_MakeCompletionCallback(func, user_data); |
28 } | 29 } |
29 | 30 |
31 CompletionCallback(PP_CompletionCallback_Func func, void* user_data, | |
32 int32_t flags) { | |
33 cc_ = PP_MakeCompletionCallback(func, user_data); | |
34 cc_.flags = flags; | |
35 } | |
36 | |
37 void set_flags(int32_t flags) { cc_.flags = flags; } | |
38 | |
30 // Call this method to explicitly run the CompletionCallback. Normally, the | 39 // Call this method to explicitly run the CompletionCallback. Normally, the |
31 // system runs a CompletionCallback after an asynchronous operation | 40 // system runs a CompletionCallback after an asynchronous operation |
32 // completes, but programs may wish to run the CompletionCallback manually | 41 // completes, but programs may wish to run the CompletionCallback manually |
33 // in order to reuse the same code paths. | 42 // in order to reuse the same code paths. |
34 void Run(int32_t result) { | 43 void Run(int32_t result) { |
35 PP_DCHECK(cc_.func); | 44 PP_DCHECK(cc_.func); |
36 PP_RunCompletionCallback(&cc_, result); | 45 PP_RunCompletionCallback(&cc_, result); |
37 } | 46 } |
38 | 47 |
48 bool IsOptional() const { | |
49 return (cc_.func == NULL || | |
50 (cc_.flags & PP_COMPLETIONCALLBACK_FLAG_OPTIONAL) != 0); | |
51 } | |
52 | |
39 const PP_CompletionCallback& pp_completion_callback() const { return cc_; } | 53 const PP_CompletionCallback& pp_completion_callback() const { return cc_; } |
54 int32_t flags() const { return cc_.flags; } | |
55 | |
56 int32_t MayForce(int32_t result) const { | |
brettw
2011/06/21 22:56:41
Can you provide a comment for this? It's a bit har
polina
2011/06/21 23:40:01
Done.
| |
57 if (result == PP_OK_COMPLETIONPENDING || IsOptional()) | |
58 return result; | |
59 Module::Get()->core()->CallOnMainThread(0, *this, result); | |
60 return PP_OK_COMPLETIONPENDING; | |
61 } | |
40 | 62 |
41 protected: | 63 protected: |
42 PP_CompletionCallback cc_; | 64 PP_CompletionCallback cc_; |
43 }; | 65 }; |
44 | 66 |
45 // CompletionCallbackFactory<T> may be used to create CompletionCallback | 67 // CompletionCallbackFactory<T> may be used to create CompletionCallback |
46 // objects that are bound to member functions. | 68 // objects that are bound to member functions. |
47 // | 69 // |
48 // If a factory is destroyed, then any pending callbacks will be cancelled | 70 // If a factory is destroyed, then any pending callbacks will be cancelled |
49 // preventing any bound member functions from being called. The CancelAll | 71 // preventing any bound member functions from being called. The CancelAll |
(...skipping 10 matching lines...) Expand all Loading... | |
60 // CallOnMainThread. | 82 // CallOnMainThread. |
61 // | 83 // |
62 // EXAMPLE USAGE: | 84 // EXAMPLE USAGE: |
63 // | 85 // |
64 // class MyHandler { | 86 // class MyHandler { |
65 // public: | 87 // public: |
66 // MyHandler() : factory_(this), offset_(0) { | 88 // MyHandler() : factory_(this), offset_(0) { |
67 // } | 89 // } |
68 // | 90 // |
69 // void ProcessFile(const FileRef& file) { | 91 // void ProcessFile(const FileRef& file) { |
70 // CompletionCallback cc = factory_.NewCallback(&MyHandler::DidOpen); | 92 // CompletionCallback cc = factory_.NewRequiredCallback( |
93 // &MyHandler::DidOpen); | |
71 // int32_t rv = fio_.Open(file, PP_FileOpenFlag_Read, cc); | 94 // int32_t rv = fio_.Open(file, PP_FileOpenFlag_Read, cc); |
72 // if (rv != PP_OK_COMPLETIONPENDING) | 95 // CHECK(rv == PP_OK_COMPLETIONPENDING); |
73 // cc.Run(rv); | |
74 // } | 96 // } |
75 // | 97 // |
76 // private: | 98 // private: |
77 // CompletionCallback NewCallback() { | 99 // CompletionCallback NewCallback() { |
78 // return factory_.NewCallback(&MyHandler::DidCompleteIO); | 100 // return factory_.NewCallback(&MyHandler::DidCompleteIO); |
79 // } | 101 // } |
80 // | 102 // |
81 // void DidOpen(int32_t result) { | 103 // void DidOpen(int32_t result) { |
82 // if (result == PP_OK) { | 104 // if (result == PP_OK) { |
83 // // The file is open, and we can begin reading. | 105 // // The file is open, and we can begin reading. |
84 // offset_ = 0; | 106 // offset_ = 0; |
85 // ReadMore(); | 107 // ReadMore(); |
86 // } else { | 108 // } else { |
87 // // Failed to open the file with error given by 'result'. | 109 // // Failed to open the file with error given by 'result'. |
88 // } | 110 // } |
89 // } | 111 // } |
90 // | 112 // |
91 // void DidRead(int32_t result) { | 113 // void DidRead(int32_t result) { |
92 // if (result > 0) { | 114 // if (result > 0) { |
93 // // buf_ now contains 'result' number of bytes from the file. | 115 // // buf_ now contains 'result' number of bytes from the file. |
94 // ProcessBytes(buf_, result); | 116 // ProcessBytes(buf_, result); |
95 // offset_ += result; | 117 // offset_ += result; |
96 // ReadMore(); | 118 // ReadMore(); |
97 // } else { | 119 // } else { |
98 // // Done reading (possibly with an error given by 'result'). | 120 // // Done reading (possibly with an error given by 'result'). |
99 // } | 121 // } |
100 // } | 122 // } |
101 // | 123 // |
102 // void ReadMore() { | 124 // void ReadMore() { |
103 // CompletionCallback cc = factory_.NewCallback(&MyHandler::DidRead); | 125 // CompletionCallback cc = |
126 // factory_.NewOptionalCallback(&MyHandler::DidRead); | |
104 // int32_t rv = fio_.Read(offset_, buf_, sizeof(buf_), | 127 // int32_t rv = fio_.Read(offset_, buf_, sizeof(buf_), |
105 // cc.pp_completion_callback()); | 128 // cc.pp_completion_callback()); |
106 // if (rv != PP_OK_COMPLETIONPENDING) | 129 // if (rv != PP_OK_COMPLETIONPENDING) |
107 // cc.Run(rv); | 130 // cc.Run(rv); |
108 // } | 131 // } |
109 // | 132 // |
110 // void ProcessBytes(const char* bytes, int32_t length) { | 133 // void ProcessBytes(const char* bytes, int32_t length) { |
111 // // Do work ... | 134 // // Do work ... |
112 // } | 135 // } |
113 // | 136 // |
(...skipping 24 matching lines...) Expand all Loading... | |
138 void Initialize(T* object) { | 161 void Initialize(T* object) { |
139 PP_DCHECK(object); | 162 PP_DCHECK(object); |
140 PP_DCHECK(!object_); // May only initialize once! | 163 PP_DCHECK(!object_); // May only initialize once! |
141 object_ = object; | 164 object_ = object; |
142 } | 165 } |
143 | 166 |
144 T* GetObject() { | 167 T* GetObject() { |
145 return object_; | 168 return object_; |
146 } | 169 } |
147 | 170 |
148 // Allocates a new, single-use CompletionCallback. The CompletionCallback | 171 // Methods for allocating new, single-use CompletionCallbacks. |
149 // must be run in order for the memory allocated by NewCallback to be freed. | 172 // The CompletionCallback must be run in order for the memory |
150 // If after passing the CompletionCallback to a PPAPI method, the method does | 173 // allocated by the methods to be freed. |
151 // not return PP_OK_COMPLETIONPENDING, then you should manually call the | 174 // NewRequiredCallback() creates callbacks that will always run. |
152 // CompletionCallback's Run method otherwise memory will be leaked. | 175 // NewOptionalCallback() creates callbacks that might not run if the method |
176 // taking them can complete synchronously. Thus, if after passing the | |
177 // CompletionCallback to a PPAPI method, the method does not return | |
178 // PP_OK_COMPLETIONPENDING, then you should manually call the | |
179 // CompletionCallback's Run method, or memory will be leaked. | |
180 // NewCallback() is equivalent to NewOptionalCallback(). | |
181 // TODO(polina): update this comment when this is no longer true. | |
153 | 182 |
154 template <typename Method> | 183 template <typename Method> |
155 CompletionCallback NewCallback(Method method) { | 184 CompletionCallback NewCallback(Method method) { |
156 PP_DCHECK(object_); | 185 PP_DCHECK(object_); |
157 return NewCallbackHelper(Dispatcher0<Method>(method)); | 186 return NewCallbackHelper(Dispatcher0<Method>(method)); |
158 } | 187 } |
159 | 188 |
189 template <typename Method> | |
190 CompletionCallback NewRequiredCallback(Method method) { | |
191 CompletionCallback cc = NewCallback(method); | |
192 cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | |
193 return cc; | |
194 } | |
195 | |
196 template <typename Method> | |
197 CompletionCallback NewOptionalCallback(Method method) { | |
198 CompletionCallback cc = NewCallback(method); | |
199 cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | |
200 return cc; | |
201 } | |
202 | |
160 // A copy of "a" will be passed to "method" when the completion callback | 203 // A copy of "a" will be passed to "method" when the completion callback |
161 // runs. | 204 // runs. |
162 // | 205 // |
163 // Method should be of type: | 206 // Method should be of type: |
164 // void (T::*)(int32_t result, const A& a) | 207 // void (T::*)(int32_t result, const A& a) |
165 // | 208 // |
166 template <typename Method, typename A> | 209 template <typename Method, typename A> |
167 CompletionCallback NewCallback(Method method, const A& a) { | 210 CompletionCallback NewCallback(Method method, const A& a) { |
168 PP_DCHECK(object_); | 211 PP_DCHECK(object_); |
169 return NewCallbackHelper(Dispatcher1<Method, A>(method, a)); | 212 return NewCallbackHelper(Dispatcher1<Method, A>(method, a)); |
170 } | 213 } |
171 | 214 |
215 template <typename Method, typename A> | |
216 CompletionCallback NewRequiredCallback(Method method, const A& a) { | |
217 CompletionCallback cc = NewCallback(method, a); | |
218 cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | |
219 return cc; | |
220 } | |
221 | |
222 template <typename Method, typename A> | |
223 CompletionCallback NewOptionalCallback(Method method, const A& a) { | |
224 CompletionCallback cc = NewCallback(method, a); | |
225 cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | |
226 return cc; | |
227 } | |
228 | |
172 // A copy of "a" and "b" will be passed to "method" when the completion | 229 // A copy of "a" and "b" will be passed to "method" when the completion |
173 // callback runs. | 230 // callback runs. |
174 // | 231 // |
175 // Method should be of type: | 232 // Method should be of type: |
176 // void (T::*)(int32_t result, const A& a, const B& b) | 233 // void (T::*)(int32_t result, const A& a, const B& b) |
177 // | 234 // |
178 template <typename Method, typename A, typename B> | 235 template <typename Method, typename A, typename B> |
179 CompletionCallback NewCallback(Method method, const A& a, const B& b) { | 236 CompletionCallback NewCallback(Method method, const A& a, const B& b) { |
180 PP_DCHECK(object_); | 237 PP_DCHECK(object_); |
181 return NewCallbackHelper(Dispatcher2<Method, A, B>(method, a, b)); | 238 return NewCallbackHelper(Dispatcher2<Method, A, B>(method, a, b)); |
182 } | 239 } |
183 | 240 |
241 template <typename Method, typename A, typename B> | |
242 CompletionCallback NewRequiredCallback(Method method, const A& a, | |
243 const B& b) { | |
244 CompletionCallback cc = NewCallback(method, a, b); | |
245 cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | |
246 return cc; | |
247 } | |
248 | |
249 template <typename Method, typename A, typename B> | |
250 CompletionCallback NewOptionalCallback(Method method, const A& a, | |
251 const B& b) { | |
252 CompletionCallback cc = NewCallback(method, a, b); | |
253 cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | |
254 return cc; | |
255 } | |
256 | |
184 private: | 257 private: |
185 class BackPointer { | 258 class BackPointer { |
186 public: | 259 public: |
187 typedef CompletionCallbackFactory<T, RefCount> FactoryType; | 260 typedef CompletionCallbackFactory<T, RefCount> FactoryType; |
188 | 261 |
189 BackPointer(FactoryType* factory) | 262 BackPointer(FactoryType* factory) |
190 : factory_(factory) { | 263 : factory_(factory) { |
191 } | 264 } |
192 | 265 |
193 void AddRef() { | 266 void AddRef() { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
305 CompletionCallbackFactory(const CompletionCallbackFactory&); | 378 CompletionCallbackFactory(const CompletionCallbackFactory&); |
306 CompletionCallbackFactory& operator=(const CompletionCallbackFactory&); | 379 CompletionCallbackFactory& operator=(const CompletionCallbackFactory&); |
307 | 380 |
308 T* object_; | 381 T* object_; |
309 BackPointer* back_pointer_; | 382 BackPointer* back_pointer_; |
310 }; | 383 }; |
311 | 384 |
312 } // namespace pp | 385 } // namespace pp |
313 | 386 |
314 #endif // PPAPI_CPP_COMPLETION_CALLBACK_H_ | 387 #endif // PPAPI_CPP_COMPLETION_CALLBACK_H_ |
OLD | NEW |