OLD | NEW |
---|---|
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 Loading... | |
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_ |
OLD | NEW |