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

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, 5 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
« no previous file with comments | « ppapi/c/trusted/ppb_file_io_trusted.h ('k') | ppapi/cpp/dev/directory_reader_dev.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // Use this when implementing functions taking callbacks.
57 // If the callback is required and |result| indicates that it has not
58 // been scheduled, it will be forced on the main thread.
59 //
60 // EXAMPLE USAGE:
61 //
62 // int32_t OpenURL(pp::URLLoader* loader,
63 // pp::URLRequestInfo* url_request_info,
64 // const CompletionCallback& cc) {
65 // if (loader == NULL || url_request_info == NULL)
66 // return cc.MayForce(PP_ERROR_BADRESOURCE);
67 // return loader->Open(*loader, *url_request_info, cc);
68 // }
69 //
70 int32_t MayForce(int32_t result) const {
71 if (result == PP_OK_COMPLETIONPENDING || IsOptional())
72 return result;
73 Module::Get()->core()->CallOnMainThread(0, *this, result);
74 return PP_OK_COMPLETIONPENDING;
75 }
40 76
41 protected: 77 protected:
42 PP_CompletionCallback cc_; 78 PP_CompletionCallback cc_;
43 }; 79 };
44 80
45 // CompletionCallbackFactory<T> may be used to create CompletionCallback 81 // CompletionCallbackFactory<T> may be used to create CompletionCallback
46 // objects that are bound to member functions. 82 // objects that are bound to member functions.
47 // 83 //
48 // If a factory is destroyed, then any pending callbacks will be cancelled 84 // If a factory is destroyed, then any pending callbacks will be cancelled
49 // preventing any bound member functions from being called. The CancelAll 85 // preventing any bound member functions from being called. The CancelAll
(...skipping 10 matching lines...) Expand all
60 // CallOnMainThread. 96 // CallOnMainThread.
61 // 97 //
62 // EXAMPLE USAGE: 98 // EXAMPLE USAGE:
63 // 99 //
64 // class MyHandler { 100 // class MyHandler {
65 // public: 101 // public:
66 // MyHandler() : factory_(this), offset_(0) { 102 // MyHandler() : factory_(this), offset_(0) {
67 // } 103 // }
68 // 104 //
69 // void ProcessFile(const FileRef& file) { 105 // void ProcessFile(const FileRef& file) {
70 // CompletionCallback cc = factory_.NewCallback(&MyHandler::DidOpen); 106 // CompletionCallback cc = factory_.NewRequiredCallback(
107 // &MyHandler::DidOpen);
71 // int32_t rv = fio_.Open(file, PP_FileOpenFlag_Read, cc); 108 // int32_t rv = fio_.Open(file, PP_FileOpenFlag_Read, cc);
72 // if (rv != PP_OK_COMPLETIONPENDING) 109 // CHECK(rv == PP_OK_COMPLETIONPENDING);
73 // cc.Run(rv);
74 // } 110 // }
75 // 111 //
76 // private: 112 // private:
77 // CompletionCallback NewCallback() { 113 // CompletionCallback NewCallback() {
78 // return factory_.NewCallback(&MyHandler::DidCompleteIO); 114 // return factory_.NewCallback(&MyHandler::DidCompleteIO);
79 // } 115 // }
80 // 116 //
81 // void DidOpen(int32_t result) { 117 // void DidOpen(int32_t result) {
82 // if (result == PP_OK) { 118 // if (result == PP_OK) {
83 // // The file is open, and we can begin reading. 119 // // The file is open, and we can begin reading.
84 // offset_ = 0; 120 // offset_ = 0;
85 // ReadMore(); 121 // ReadMore();
86 // } else { 122 // } else {
87 // // Failed to open the file with error given by 'result'. 123 // // Failed to open the file with error given by 'result'.
88 // } 124 // }
89 // } 125 // }
90 // 126 //
91 // void DidRead(int32_t result) { 127 // void DidRead(int32_t result) {
92 // if (result > 0) { 128 // if (result > 0) {
93 // // buf_ now contains 'result' number of bytes from the file. 129 // // buf_ now contains 'result' number of bytes from the file.
94 // ProcessBytes(buf_, result); 130 // ProcessBytes(buf_, result);
95 // offset_ += result; 131 // offset_ += result;
96 // ReadMore(); 132 // ReadMore();
97 // } else { 133 // } else {
98 // // Done reading (possibly with an error given by 'result'). 134 // // Done reading (possibly with an error given by 'result').
99 // } 135 // }
100 // } 136 // }
101 // 137 //
102 // void ReadMore() { 138 // void ReadMore() {
103 // CompletionCallback cc = factory_.NewCallback(&MyHandler::DidRead); 139 // CompletionCallback cc =
140 // factory_.NewOptionalCallback(&MyHandler::DidRead);
104 // int32_t rv = fio_.Read(offset_, buf_, sizeof(buf_), 141 // int32_t rv = fio_.Read(offset_, buf_, sizeof(buf_),
105 // cc.pp_completion_callback()); 142 // cc.pp_completion_callback());
106 // if (rv != PP_OK_COMPLETIONPENDING) 143 // if (rv != PP_OK_COMPLETIONPENDING)
107 // cc.Run(rv); 144 // cc.Run(rv);
108 // } 145 // }
109 // 146 //
110 // void ProcessBytes(const char* bytes, int32_t length) { 147 // void ProcessBytes(const char* bytes, int32_t length) {
111 // // Do work ... 148 // // Do work ...
112 // } 149 // }
113 // 150 //
(...skipping 24 matching lines...) Expand all
138 void Initialize(T* object) { 175 void Initialize(T* object) {
139 PP_DCHECK(object); 176 PP_DCHECK(object);
140 PP_DCHECK(!object_); // May only initialize once! 177 PP_DCHECK(!object_); // May only initialize once!
141 object_ = object; 178 object_ = object;
142 } 179 }
143 180
144 T* GetObject() { 181 T* GetObject() {
145 return object_; 182 return object_;
146 } 183 }
147 184
148 // Allocates a new, single-use CompletionCallback. The CompletionCallback 185 // Methods for allocating new, single-use CompletionCallbacks.
149 // must be run in order for the memory allocated by NewCallback to be freed. 186 // The CompletionCallback must be run in order for the memory
150 // If after passing the CompletionCallback to a PPAPI method, the method does 187 // allocated by the methods to be freed.
151 // not return PP_OK_COMPLETIONPENDING, then you should manually call the 188 // NewRequiredCallback() creates callbacks that will always run.
152 // CompletionCallback's Run method otherwise memory will be leaked. 189 // NewOptionalCallback() creates callbacks that might not run if the method
190 // taking them can complete synchronously. Thus, if after passing the
191 // CompletionCallback to a PPAPI method, the method does not return
192 // PP_OK_COMPLETIONPENDING, then you should manually call the
193 // CompletionCallback's Run method, or memory will be leaked.
194 // NewCallback() is equivalent to NewOptionalCallback().
195 // TODO(polina): update this comment when this is no longer true.
153 196
154 template <typename Method> 197 template <typename Method>
155 CompletionCallback NewCallback(Method method) { 198 CompletionCallback NewCallback(Method method) {
156 PP_DCHECK(object_); 199 PP_DCHECK(object_);
157 return NewCallbackHelper(Dispatcher0<Method>(method)); 200 return NewCallbackHelper(Dispatcher0<Method>(method));
158 } 201 }
159 202
203 template <typename Method>
204 CompletionCallback NewRequiredCallback(Method method) {
205 CompletionCallback cc = NewCallback(method);
206 cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
207 return cc;
208 }
209
210 template <typename Method>
211 CompletionCallback NewOptionalCallback(Method method) {
212 CompletionCallback cc = NewCallback(method);
213 cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
214 return cc;
215 }
216
160 // A copy of "a" will be passed to "method" when the completion callback 217 // A copy of "a" will be passed to "method" when the completion callback
161 // runs. 218 // runs.
162 // 219 //
163 // Method should be of type: 220 // Method should be of type:
164 // void (T::*)(int32_t result, const A& a) 221 // void (T::*)(int32_t result, const A& a)
165 // 222 //
166 template <typename Method, typename A> 223 template <typename Method, typename A>
167 CompletionCallback NewCallback(Method method, const A& a) { 224 CompletionCallback NewCallback(Method method, const A& a) {
168 PP_DCHECK(object_); 225 PP_DCHECK(object_);
169 return NewCallbackHelper(Dispatcher1<Method, A>(method, a)); 226 return NewCallbackHelper(Dispatcher1<Method, A>(method, a));
170 } 227 }
171 228
229 template <typename Method, typename A>
230 CompletionCallback NewRequiredCallback(Method method, const A& a) {
231 CompletionCallback cc = NewCallback(method, a);
232 cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
233 return cc;
234 }
235
236 template <typename Method, typename A>
237 CompletionCallback NewOptionalCallback(Method method, const A& a) {
238 CompletionCallback cc = NewCallback(method, a);
239 cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
240 return cc;
241 }
242
172 // A copy of "a" and "b" will be passed to "method" when the completion 243 // A copy of "a" and "b" will be passed to "method" when the completion
173 // callback runs. 244 // callback runs.
174 // 245 //
175 // Method should be of type: 246 // Method should be of type:
176 // void (T::*)(int32_t result, const A& a, const B& b) 247 // void (T::*)(int32_t result, const A& a, const B& b)
177 // 248 //
178 template <typename Method, typename A, typename B> 249 template <typename Method, typename A, typename B>
179 CompletionCallback NewCallback(Method method, const A& a, const B& b) { 250 CompletionCallback NewCallback(Method method, const A& a, const B& b) {
180 PP_DCHECK(object_); 251 PP_DCHECK(object_);
181 return NewCallbackHelper(Dispatcher2<Method, A, B>(method, a, b)); 252 return NewCallbackHelper(Dispatcher2<Method, A, B>(method, a, b));
182 } 253 }
183 254
255 template <typename Method, typename A, typename B>
256 CompletionCallback NewRequiredCallback(Method method, const A& a,
257 const B& b) {
258 CompletionCallback cc = NewCallback(method, a, b);
259 cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
260 return cc;
261 }
262
263 template <typename Method, typename A, typename B>
264 CompletionCallback NewOptionalCallback(Method method, const A& a,
265 const B& b) {
266 CompletionCallback cc = NewCallback(method, a, b);
267 cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
268 return cc;
269 }
270
184 private: 271 private:
185 class BackPointer { 272 class BackPointer {
186 public: 273 public:
187 typedef CompletionCallbackFactory<T, RefCount> FactoryType; 274 typedef CompletionCallbackFactory<T, RefCount> FactoryType;
188 275
189 BackPointer(FactoryType* factory) 276 BackPointer(FactoryType* factory)
190 : factory_(factory) { 277 : factory_(factory) {
191 } 278 }
192 279
193 void AddRef() { 280 void AddRef() {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 CompletionCallbackFactory(const CompletionCallbackFactory&); 392 CompletionCallbackFactory(const CompletionCallbackFactory&);
306 CompletionCallbackFactory& operator=(const CompletionCallbackFactory&); 393 CompletionCallbackFactory& operator=(const CompletionCallbackFactory&);
307 394
308 T* object_; 395 T* object_;
309 BackPointer* back_pointer_; 396 BackPointer* back_pointer_;
310 }; 397 };
311 398
312 } // namespace pp 399 } // namespace pp
313 400
314 #endif // PPAPI_CPP_COMPLETION_CALLBACK_H_ 401 #endif // PPAPI_CPP_COMPLETION_CALLBACK_H_
OLDNEW
« no previous file with comments | « ppapi/c/trusted/ppb_file_io_trusted.h ('k') | ppapi/cpp/dev/directory_reader_dev.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698