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

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 ||
piman 2011/06/07 17:32:14 nit: only 1 space after return
polina 2011/06/09 23:53:51 good eye! Done.
50 (cc_.flags & PP_COMPLETIONCALLBACK_FLAG_OPTIONAL) != 0);
piman 2011/06/07 17:32:14 nit: Indent looks wrong
polina 2011/06/09 23:53:51 could you be more specific please?
piman 2011/06/10 00:51:20 4 spaces for continuations ?
polina 2011/06/10 19:33:19 Not in this case because we have () and break afte
51 }
52
39 const PP_CompletionCallback& pp_completion_callback() const { return cc_; } 53 const PP_CompletionCallback& pp_completion_callback() const { return cc_; }
40 54
55 int32_t MayForce(int32_t result) const {
56 if (result == PP_OK_COMPLETIONPENDING || IsOptional())
57 return result;
58 Module::Get()->core()->CallOnMainThread(0, *this, result);
59 return PP_OK_COMPLETIONPENDING;
60 }
61
41 protected: 62 protected:
42 PP_CompletionCallback cc_; 63 PP_CompletionCallback cc_;
43 }; 64 };
44 65
45 // CompletionCallbackFactory<T> may be used to create CompletionCallback 66 // CompletionCallbackFactory<T> may be used to create CompletionCallback
46 // objects that are bound to member functions. 67 // objects that are bound to member functions.
47 // 68 //
48 // If a factory is destroyed, then any pending callbacks will be cancelled 69 // If a factory is destroyed, then any pending callbacks will be cancelled
49 // preventing any bound member functions from being called. The CancelAll 70 // preventing any bound member functions from being called. The CancelAll
50 // method allows pending callbacks to be cancelled without destroying the 71 // method allows pending callbacks to be cancelled without destroying the
(...skipping 11 matching lines...) Expand all
62 // EXAMPLE USAGE: 83 // EXAMPLE USAGE:
63 // 84 //
64 // class MyHandler { 85 // class MyHandler {
65 // public: 86 // public:
66 // MyHandler() : factory_(this), offset_(0) { 87 // MyHandler() : factory_(this), offset_(0) {
67 // } 88 // }
68 // 89 //
69 // void ProcessFile(const FileRef& file) { 90 // void ProcessFile(const FileRef& file) {
70 // CompletionCallback cc = factory_.NewCallback(&MyHandler::DidOpen); 91 // CompletionCallback cc = factory_.NewCallback(&MyHandler::DidOpen);
71 // int32_t rv = fio_.Open(file, PP_FileOpenFlag_Read, cc); 92 // int32_t rv = fio_.Open(file, PP_FileOpenFlag_Read, cc);
72 // if (rv != PP_OK_COMPLETIONPENDING) 93 // CHECK(rv == PP_OK_COMPLETIONPENDING);
73 // cc.Run(rv);
74 // } 94 // }
75 // 95 //
76 // private: 96 // private:
77 // CompletionCallback NewCallback() { 97 // CompletionCallback NewCallback() {
78 // return factory_.NewCallback(&MyHandler::DidCompleteIO); 98 // return factory_.NewCallback(&MyHandler::DidCompleteIO);
79 // } 99 // }
80 // 100 //
81 // void DidOpen(int32_t result) { 101 // void DidOpen(int32_t result) {
82 // if (result == PP_OK) { 102 // if (result == PP_OK) {
83 // // The file is open, and we can begin reading. 103 // // The file is open, and we can begin reading.
84 // offset_ = 0; 104 // offset_ = 0;
85 // ReadMore(); 105 // ReadMore();
86 // } else { 106 // } else {
87 // // Failed to open the file with error given by 'result'. 107 // // Failed to open the file with error given by 'result'.
88 // } 108 // }
89 // } 109 // }
90 // 110 //
91 // void DidRead(int32_t result) { 111 // void DidRead(int32_t result) {
92 // if (result > 0) { 112 // if (result > 0) {
93 // // buf_ now contains 'result' number of bytes from the file. 113 // // buf_ now contains 'result' number of bytes from the file.
94 // ProcessBytes(buf_, result); 114 // ProcessBytes(buf_, result);
95 // offset_ += result; 115 // offset_ += result;
96 // ReadMore(); 116 // ReadMore();
97 // } else { 117 // } else {
98 // // Done reading (possibly with an error given by 'result'). 118 // // Done reading (possibly with an error given by 'result').
99 // } 119 // }
100 // } 120 // }
101 // 121 //
102 // void ReadMore() { 122 // void ReadMore() {
103 // CompletionCallback cc = factory_.NewCallback(&MyHandler::DidRead); 123 // CompletionCallback cc =
124 // factory_.NewOptionalCallback(&MyHandler::DidRead);
104 // int32_t rv = fio_.Read(offset_, buf_, sizeof(buf_), 125 // int32_t rv = fio_.Read(offset_, buf_, sizeof(buf_),
105 // cc.pp_completion_callback()); 126 // cc.pp_completion_callback());
106 // if (rv != PP_OK_COMPLETIONPENDING) 127 // if (rv != PP_OK_COMPLETIONPENDING)
107 // cc.Run(rv); 128 // cc.Run(rv);
108 // } 129 // }
109 // 130 //
110 // void ProcessBytes(const char* bytes, int32_t length) { 131 // void ProcessBytes(const char* bytes, int32_t length) {
111 // // Do work ... 132 // // Do work ...
112 // } 133 // }
113 // 134 //
(...skipping 24 matching lines...) Expand all
138 void Initialize(T* object) { 159 void Initialize(T* object) {
139 PP_DCHECK(object); 160 PP_DCHECK(object);
140 PP_DCHECK(!object_); // May only initialize once! 161 PP_DCHECK(!object_); // May only initialize once!
141 object_ = object; 162 object_ = object;
142 } 163 }
143 164
144 T* GetObject() { 165 T* GetObject() {
145 return object_; 166 return object_;
146 } 167 }
147 168
148 // Allocates a new, single-use CompletionCallback. The CompletionCallback 169 // Methods for allocating new, single-use CompletionCallbacks.
149 // must be run in order for the memory allocated by NewCallback to be freed. 170 // The CompletionCallback must be run in order for the memory
150 // If after passing the CompletionCallback to a PPAPI method, the method does 171 // allocated by NewCallback to be freed. NewCallback() creates callbacks that
151 // not return PP_OK_COMPLETIONPENDING, then you should manually call the 172 // will always run. NewOptionalCallback() creates callbacks that might
152 // CompletionCallback's Run method otherwise memory will be leaked. 173 // not run if the method taking them can complete synchronously.
174 // Thus, if after passing the CompletionCallback to a PPAPI method, the
175 // method does not return PP_OK_COMPLETIONPENDING, then you should manually
176 // call the CompletionCallback's Run method, or memory will be leaked.
153 177
154 template <typename Method> 178 template <typename Method>
155 CompletionCallback NewCallback(Method method) { 179 CompletionCallback NewCallback(Method method) {
156 PP_DCHECK(object_); 180 PP_DCHECK(object_);
157 return NewCallbackHelper(Dispatcher0<Method>(method)); 181 return NewCallbackHelper(Dispatcher0<Method>(method));
158 } 182 }
159 183
184 template <typename Method>
185 CompletionCallback NewOptionalCallback(Method method) {
186 CompletionCallback cc = NewCallback(method);
187 cc.set_flags(PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
188 return cc;
189 }
190
160 // A copy of "a" will be passed to "method" when the completion callback 191 // A copy of "a" will be passed to "method" when the completion callback
161 // runs. 192 // runs.
162 // 193 //
163 // Method should be of type: 194 // Method should be of type:
164 // void (T::*)(int32_t result, const A& a) 195 // void (T::*)(int32_t result, const A& a)
165 // 196 //
166 template <typename Method, typename A> 197 template <typename Method, typename A>
167 CompletionCallback NewCallback(Method method, const A& a) { 198 CompletionCallback NewCallback(Method method, const A& a) {
168 PP_DCHECK(object_); 199 PP_DCHECK(object_);
169 return NewCallbackHelper(Dispatcher1<Method, A>(method, a)); 200 return NewCallbackHelper(Dispatcher1<Method, A>(method, a));
170 } 201 }
171 202
203 template <typename Method, typename A>
204 CompletionCallback NewOptionalCallback(Method method, const A& a) {
205 CompletionCallback cc = NewCallback(method, a);
206 cc.set_flags(PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
207 return cc;
208 }
209
172 // A copy of "a" and "b" will be passed to "method" when the completion 210 // A copy of "a" and "b" will be passed to "method" when the completion
173 // callback runs. 211 // callback runs.
174 // 212 //
175 // Method should be of type: 213 // Method should be of type:
176 // void (T::*)(int32_t result, const A& a, const B& b) 214 // void (T::*)(int32_t result, const A& a, const B& b)
177 // 215 //
178 template <typename Method, typename A, typename B> 216 template <typename Method, typename A, typename B>
179 CompletionCallback NewCallback(Method method, const A& a, const B& b) { 217 CompletionCallback NewCallback(Method method, const A& a, const B& b) {
180 PP_DCHECK(object_); 218 PP_DCHECK(object_);
181 return NewCallbackHelper(Dispatcher2<Method, A, B>(method, a, b)); 219 return NewCallbackHelper(Dispatcher2<Method, A, B>(method, a, b));
182 } 220 }
183 221
222 template <typename Method, typename A, typename B>
223 CompletionCallback NewOptionalCallback(Method method, const A& a,
224 const B& b) {
225 CompletionCallback cc = NewCallback(method, a, b);
226 cc.set_flags(PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
227 return cc;
228 }
229
184 private: 230 private:
185 class BackPointer { 231 class BackPointer {
186 public: 232 public:
187 typedef CompletionCallbackFactory<T, RefCount> FactoryType; 233 typedef CompletionCallbackFactory<T, RefCount> FactoryType;
188 234
189 BackPointer(FactoryType* factory) 235 BackPointer(FactoryType* factory)
190 : factory_(factory) { 236 : factory_(factory) {
191 } 237 }
192 238
193 void AddRef() { 239 void AddRef() {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 CompletionCallbackFactory(const CompletionCallbackFactory&); 351 CompletionCallbackFactory(const CompletionCallbackFactory&);
306 CompletionCallbackFactory& operator=(const CompletionCallbackFactory&); 352 CompletionCallbackFactory& operator=(const CompletionCallbackFactory&);
307 353
308 T* object_; 354 T* object_;
309 BackPointer* back_pointer_; 355 BackPointer* back_pointer_;
310 }; 356 };
311 357
312 } // namespace pp 358 } // namespace pp
313 359
314 #endif // PPAPI_CPP_COMPLETION_CALLBACK_H_ 360 #endif // PPAPI_CPP_COMPLETION_CALLBACK_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698