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

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

Powered by Google App Engine
This is Rietveld 408576698