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

Side by Side Diff: ppapi/thunk/enter.h

Issue 10081020: PPAPI: Make blocking completion callbacks work. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: try again Created 8 years, 7 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_THUNK_ENTER_H_ 5 #ifndef PPAPI_THUNK_ENTER_H_
6 #define PPAPI_THUNK_ENTER_H_ 6 #define PPAPI_THUNK_ENTER_H_
7 7
8 #include <string>
9
8 #include "base/basictypes.h" 10 #include "base/basictypes.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/synchronization/lock.h"
13 #include "ppapi/c/pp_errors.h"
9 #include "ppapi/c/pp_resource.h" 14 #include "ppapi/c/pp_resource.h"
10 #include "ppapi/shared_impl/api_id.h" 15 #include "ppapi/shared_impl/api_id.h"
11 #include "ppapi/shared_impl/ppapi_globals.h" 16 #include "ppapi/shared_impl/ppapi_globals.h"
12 #include "ppapi/shared_impl/proxy_lock.h" 17 #include "ppapi/shared_impl/proxy_lock.h"
13 #include "ppapi/shared_impl/resource.h" 18 #include "ppapi/shared_impl/resource.h"
14 #include "ppapi/shared_impl/resource_tracker.h" 19 #include "ppapi/shared_impl/resource_tracker.h"
20 #include "ppapi/shared_impl/tracked_callback.h"
15 #include "ppapi/thunk/ppapi_thunk_export.h" 21 #include "ppapi/thunk/ppapi_thunk_export.h"
16 #include "ppapi/thunk/ppb_instance_api.h" 22 #include "ppapi/thunk/ppb_instance_api.h"
17 #include "ppapi/thunk/resource_creation_api.h" 23 #include "ppapi/thunk/resource_creation_api.h"
18 24
19 namespace ppapi { 25 namespace ppapi {
20 namespace thunk { 26 namespace thunk {
21 27
22 // Enter* helper objects: These objects wrap a call from the C PPAPI into 28 // Enter* helper objects: These objects wrap a call from the C PPAPI into
23 // the internal implementation. They make sure the lock is acquired and will 29 // the internal implementation. They make sure the lock is acquired and will
24 // automatically set up some stuff for you. 30 // automatically set up some stuff for you.
(...skipping 16 matching lines...) Expand all
41 // This helps us define our RAII Enter classes easily. To make an RAII class 47 // This helps us define our RAII Enter classes easily. To make an RAII class
42 // which locks the proxy lock on construction and unlocks on destruction, 48 // which locks the proxy lock on construction and unlocks on destruction,
43 // inherit from |LockOnEntry<true>|. For cases where you don't want to lock, 49 // inherit from |LockOnEntry<true>|. For cases where you don't want to lock,
44 // inherit from |LockOnEntry<false>|. This allows us to share more code between 50 // inherit from |LockOnEntry<false>|. This allows us to share more code between
45 // Enter* and Enter*NoLock classes. 51 // Enter* and Enter*NoLock classes.
46 template <bool lock_on_entry> 52 template <bool lock_on_entry>
47 struct LockOnEntry; 53 struct LockOnEntry;
48 54
49 template <> 55 template <>
50 struct LockOnEntry<false> { 56 struct LockOnEntry<false> {
51 // TODO(dmichael) assert the lock is held. 57 #if (!NDEBUG)
58 LockOnEntry() {
59 // You must already hold the lock to use Enter*NoLock.
60 AssertLockHeld();
61 }
62 ~LockOnEntry() {
63 // You must not release the lock before leaving the scope of the
64 // Enter*NoLock.
65 AssertLockHeld();
66 }
67 private:
68 static void AssertLockHeld() {
brettw 2012/05/20 17:46:46 It would be nice to make this non-inline & remove
dmichael (off chromium) 2012/06/22 18:14:05 Good idea, done.
69 base::Lock* proxy_lock = PpapiGlobals::Get()->GetProxyLock();
70 if (proxy_lock)
71 proxy_lock->AssertAcquired();
72 }
73 #endif
52 }; 74 };
53 75
54 template <> 76 template <>
55 struct LockOnEntry<true> { 77 struct LockOnEntry<true> {
56 LockOnEntry() { 78 LockOnEntry() {
57 ppapi::ProxyLock::Acquire(); 79 ppapi::ProxyLock::Acquire();
58 } 80 }
59 ~LockOnEntry() { 81 ~LockOnEntry() {
60 ppapi::ProxyLock::Release(); 82 ppapi::ProxyLock::Release();
61 } 83 }
62 }; 84 };
63 85
64 // Keep non-templatized since we need non-inline functions here. 86 // Keep non-templatized since we need non-inline functions here.
65 class PPAPI_THUNK_EXPORT EnterBase { 87 class PPAPI_THUNK_EXPORT EnterBase {
66 public: 88 public:
67 EnterBase(); 89 EnterBase();
68 explicit EnterBase(const PP_CompletionCallback& callback); 90 explicit EnterBase(PP_Resource resource);
91 EnterBase(PP_Resource resource, const PP_CompletionCallback& callback);
69 virtual ~EnterBase(); 92 virtual ~EnterBase();
70 93
71 // Sets the result. 94 // Sets the result for calls that use a completion callback. It handles making
95 // sure that "Required" callbacks are scheduled to run asynchronously and
96 // "Blocking" callbacks cause the caller to block. (Interface implementations,
97 // therefore, should not do any special casing based on the type of the
98 // callback.)
72 // 99 //
73 // Returns the "retval()". This is to support the typical usage of 100 // Returns the "retval()". This is to support the typical usage of
74 // return enter.SetResult(...); 101 // return enter.SetResult(...);
75 // without having to write a separate "return enter.retval();" line. 102 // without having to write a separate "return enter.retval();" line.
76 int32_t SetResult(int32_t result); 103 int32_t SetResult(int32_t result);
77 104
78 // Use this value as the return value for the function. 105 // Use this value as the return value for the function.
79 int32_t retval() const { return retval_; } 106 int32_t retval() const { return retval_; }
80 107
108 // All failure conditions cause retval_ to be set to an appropriate error
109 // code.
110 bool succeeded() const { return retval_ == PP_OK; }
111 bool failed() const { return !succeeded(); }
112
113 const scoped_refptr<TrackedCallback>& callback() { return callback_; }
114
81 protected: 115 protected:
82 // Helper function to return a Resource from a PP_Resource. Having this 116 // Helper function to return a Resource from a PP_Resource. Having this
83 // code be in the non-templatized base keeps us from having to instantiate 117 // code be in the non-templatized base keeps us from having to instantiate
84 // it in every template. 118 // it in every template.
85 Resource* GetResource(PP_Resource resource) const; 119 static Resource* GetResource(PP_Resource resource);
120
121 void ClearCallback();
86 122
87 // Does error handling associated with entering a resource. The resource_base 123 // Does error handling associated with entering a resource. The resource_base
88 // is the result of looking up the given pp_resource. The object is the 124 // is the result of looking up the given pp_resource. The object is the
89 // result of converting the base to the desired object (converted back to a 125 // result of converting the base to the desired object (converted to a void*
90 // Resource* so this function doesn't have to be templatized). The reason for 126 // so this function doesn't have to be templatized). The reason for passing
91 // passing both resource_base and object is that we can differentiate "bad 127 // both resource_base and object is that we can differentiate "bad resource
92 // resource ID" from "valid resource ID not of the currect type." 128 // ID" from "valid resource ID not of the correct type."
93 // 129 //
94 // This will set retval_ = PP_ERROR_BADRESOURCE if the object is invalid, and 130 // This will set retval_ = PP_ERROR_BADRESOURCE if the object is invalid, and
95 // if report_error is set, log a message to the programmer. 131 // if report_error is set, log a message to the programmer.
96 void SetStateForResourceError(PP_Resource pp_resource, 132 void SetStateForResourceError(PP_Resource pp_resource,
97 Resource* resource_base, 133 Resource* resource_base,
98 void* object, 134 void* object,
99 bool report_error); 135 bool report_error);
100 136
101 // Same as SetStateForResourceError except for function API. 137 // Same as SetStateForResourceError except for function API.
102 void SetStateForFunctionError(PP_Instance pp_instance, 138 void SetStateForFunctionError(PP_Instance pp_instance,
103 void* object, 139 void* object,
104 bool report_error); 140 bool report_error);
105 141
142 // For Enter objects that need a resource, we'll store a pointer to the
143 // Resource object so that we don't need to look it up more than once. For
144 // Enter objects with no resource, this will be NULL.
145 Resource* resource_;
146
106 private: 147 private:
107 // Holds the callback. The function will only be non-NULL when the 148 bool CallbackIsValid() const;
108 // callback is requried. Optional callbacks don't require any special 149
109 // handling from us at this layer. 150 // Checks whether the callback is valid (i.e., if it is either non-blocking,
110 PP_CompletionCallback callback_; 151 // or blocking and we're on a background thread). If the callback is invalid,
152 // this will set retval_ = PP_ERROR_BLOCKS_MAIN_THREAD, and if report_error is
153 // set, it will log a message to the programmer.
154 void SetStateForCallbackError(bool report_error);
155
156 // Holds the callback. For Enter objects that aren't given a callback, this
157 // will be NULL.
158 scoped_refptr<TrackedCallback> callback_;
111 159
112 int32_t retval_; 160 int32_t retval_;
113 }; 161 };
114 162
115 } // namespace subtle 163 } // namespace subtle
116 164
117 // EnterResource --------------------------------------------------------------- 165 // EnterResource ---------------------------------------------------------------
118 166
119 template<typename ResourceT, bool lock_on_entry = true> 167 template<typename ResourceT, bool lock_on_entry = true>
120 class EnterResource : public subtle::EnterBase, 168 class EnterResource : public subtle::EnterBase,
121 public subtle::LockOnEntry<lock_on_entry> { 169 public subtle::LockOnEntry<lock_on_entry> {
122 public: 170 public:
123 EnterResource(PP_Resource resource, bool report_error) 171 EnterResource(PP_Resource resource, bool report_error)
124 : EnterBase() { 172 : EnterBase(resource) {
125 Init(resource, report_error); 173 Init(resource, report_error);
126 } 174 }
127 EnterResource(PP_Resource resource, 175 EnterResource(PP_Resource resource, const PP_CompletionCallback& callback,
128 const PP_CompletionCallback& callback,
129 bool report_error) 176 bool report_error)
130 : EnterBase(callback) { 177 : EnterBase(resource, callback) {
131 Init(resource, report_error); 178 Init(resource, report_error);
132 } 179 }
133 ~EnterResource() {} 180 ~EnterResource() {}
134 181
135 bool succeeded() const { return !!object_; }
136 bool failed() const { return !object_; }
137
138 ResourceT* object() { return object_; } 182 ResourceT* object() { return object_; }
139 Resource* resource() { return resource_; } 183 Resource* resource() { return resource_; }
140 184
141 private: 185 private:
142 void Init(PP_Resource resource, bool report_error) { 186 void Init(PP_Resource resource, bool report_error) {
143 resource_ = GetResource(resource);
144 if (resource_) 187 if (resource_)
145 object_ = resource_->GetAs<ResourceT>(); 188 object_ = resource_->GetAs<ResourceT>();
146 else 189 else
147 object_ = NULL; 190 object_ = NULL;
191 // Validate the resource (note, if both are wrong, we will return
192 // PP_ERROR_BADRESOURCE; last in wins).
148 SetStateForResourceError(resource, resource_, object_, report_error); 193 SetStateForResourceError(resource, resource_, object_, report_error);
149 } 194 }
150 195
151 Resource* resource_;
152 ResourceT* object_; 196 ResourceT* object_;
153 197
154 DISALLOW_COPY_AND_ASSIGN(EnterResource); 198 DISALLOW_COPY_AND_ASSIGN(EnterResource);
155 }; 199 };
156 200
157 // ---------------------------------------------------------------------------- 201 // ----------------------------------------------------------------------------
158 202
159 // Like EnterResource but assumes the lock is already held. 203 // Like EnterResource but assumes the lock is already held.
160 template<typename ResourceT> 204 template<typename ResourceT>
161 class EnterResourceNoLock : public EnterResource<ResourceT, false> { 205 class EnterResourceNoLock : public EnterResource<ResourceT, false> {
162 public: 206 public:
163 EnterResourceNoLock(PP_Resource resource, bool report_error) 207 EnterResourceNoLock(PP_Resource resource, bool report_error)
164 : EnterResource<ResourceT, false>(resource, report_error) { 208 : EnterResource<ResourceT, false>(resource, report_error) {
165 } 209 }
210 EnterResourceNoLock(PP_Resource resource, PP_CompletionCallback callback,
211 bool report_error)
212 : EnterResource<ResourceT, false>(resource, callback, report_error) {
213 }
166 }; 214 };
167 215
168 // EnterInstance --------------------------------------------------------------- 216 // EnterInstance ---------------------------------------------------------------
169 217
170 class PPAPI_THUNK_EXPORT EnterInstance 218 class PPAPI_THUNK_EXPORT EnterInstance
171 : public subtle::EnterBase, 219 : public subtle::EnterBase,
172 public subtle::LockOnEntry<true> { 220 public subtle::LockOnEntry<true> {
173 public: 221 public:
174 EnterInstance(PP_Instance instance); 222 EnterInstance(PP_Instance instance);
175 EnterInstance(PP_Instance instance, 223 EnterInstance(PP_Instance instance,
176 const PP_CompletionCallback& callback); 224 const PP_CompletionCallback& callback);
177 ~EnterInstance(); 225 ~EnterInstance();
178 226
179 bool succeeded() const { return !!functions_; } 227 bool succeeded() const { return !!functions_; }
180 bool failed() const { return !functions_; } 228 bool failed() const { return !functions_; }
181 229
182 PPB_Instance_API* functions() { return functions_; } 230 PPB_Instance_API* functions() { return functions_; }
183 231
184 private: 232 private:
185 PPB_Instance_API* functions_; 233 PPB_Instance_API* functions_;
186 }; 234 };
187 235
188 class PPAPI_THUNK_EXPORT EnterInstanceNoLock 236 class PPAPI_THUNK_EXPORT EnterInstanceNoLock
189 : public subtle::EnterBase, 237 : public subtle::EnterBase,
190 public subtle::LockOnEntry<false> { 238 public subtle::LockOnEntry<false> {
191 public: 239 public:
192 EnterInstanceNoLock(PP_Instance instance); 240 EnterInstanceNoLock(PP_Instance instance);
193 //EnterInstanceNoLock(PP_Instance instance, 241 EnterInstanceNoLock(PP_Instance instance,
194 // const PP_CompletionCallback& callback); 242 const PP_CompletionCallback& callback);
195 ~EnterInstanceNoLock(); 243 ~EnterInstanceNoLock();
196 244
197 bool succeeded() const { return !!functions_; }
198 bool failed() const { return !functions_; }
199
200 PPB_Instance_API* functions() { return functions_; } 245 PPB_Instance_API* functions() { return functions_; }
201 246
202 private: 247 private:
203 PPB_Instance_API* functions_; 248 PPB_Instance_API* functions_;
204 }; 249 };
205 250
206 // EnterResourceCreation ------------------------------------------------------- 251 // EnterResourceCreation -------------------------------------------------------
207 252
208 class PPAPI_THUNK_EXPORT EnterResourceCreation 253 class PPAPI_THUNK_EXPORT EnterResourceCreation
209 : public subtle::EnterBase, 254 : public subtle::EnterBase,
210 public subtle::LockOnEntry<true> { 255 public subtle::LockOnEntry<true> {
211 public: 256 public:
212 EnterResourceCreation(PP_Instance instance); 257 EnterResourceCreation(PP_Instance instance);
213 ~EnterResourceCreation(); 258 ~EnterResourceCreation();
214 259
215 bool succeeded() const { return !!functions_; }
216 bool failed() const { return !functions_; }
217
218 ResourceCreationAPI* functions() { return functions_; } 260 ResourceCreationAPI* functions() { return functions_; }
219 261
220 private: 262 private:
221 ResourceCreationAPI* functions_; 263 ResourceCreationAPI* functions_;
222 }; 264 };
223 265
224 class PPAPI_THUNK_EXPORT EnterResourceCreationNoLock 266 class PPAPI_THUNK_EXPORT EnterResourceCreationNoLock
225 : public subtle::EnterBase, 267 : public subtle::EnterBase,
226 public subtle::LockOnEntry<false> { 268 public subtle::LockOnEntry<false> {
227 public: 269 public:
228 EnterResourceCreationNoLock(PP_Instance instance); 270 EnterResourceCreationNoLock(PP_Instance instance);
229 ~EnterResourceCreationNoLock(); 271 ~EnterResourceCreationNoLock();
230 272
231 bool succeeded() const { return !!functions_; }
232 bool failed() const { return !functions_; }
233
234 ResourceCreationAPI* functions() { return functions_; } 273 ResourceCreationAPI* functions() { return functions_; }
235 274
236 private: 275 private:
237 ResourceCreationAPI* functions_; 276 ResourceCreationAPI* functions_;
238 }; 277 };
239 278
279
brettw 2012/05/20 17:46:46 Got extra line.
dmichael (off chromium) 2012/06/22 18:14:05 Done.
240 } // namespace thunk 280 } // namespace thunk
241 } // namespace ppapi 281 } // namespace ppapi
242 282
243 #endif // PPAPI_THUNK_ENTER_H_ 283 #endif // PPAPI_THUNK_ENTER_H_
OLDNEW
« no previous file with comments | « ppapi/tests/test_utils.cc ('k') | ppapi/thunk/enter.cc » ('j') | ppapi/thunk/enter.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698