Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(787)

Side by Side Diff: ppapi/cpp/completion_callback.h

Issue 6899055: PPAPI: Force async callback invocation option. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698