Chromium Code Reviews| 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/function_group_base.h" | 16 #include "ppapi/shared_impl/function_group_base.h" |
| 12 #include "ppapi/shared_impl/ppapi_globals.h" | 17 #include "ppapi/shared_impl/ppapi_globals.h" |
| 13 #include "ppapi/shared_impl/proxy_lock.h" | 18 #include "ppapi/shared_impl/proxy_lock.h" |
| 14 #include "ppapi/shared_impl/resource.h" | 19 #include "ppapi/shared_impl/resource.h" |
| 15 #include "ppapi/shared_impl/resource_tracker.h" | 20 #include "ppapi/shared_impl/resource_tracker.h" |
| 16 #include "ppapi/thunk/ppapi_thunk_export.h" | 21 #include "ppapi/thunk/ppapi_thunk_export.h" |
| 17 #include "ppapi/thunk/ppb_instance_api.h" | 22 #include "ppapi/thunk/ppb_instance_api.h" |
| 18 #include "ppapi/thunk/resource_creation_api.h" | 23 #include "ppapi/thunk/resource_creation_api.h" |
| 19 | 24 |
| 20 namespace ppapi { | 25 namespace ppapi { |
| 26 class TrackedCallback; | |
| 27 | |
| 21 namespace thunk { | 28 namespace thunk { |
| 22 | 29 |
| 23 // Enter* helper objects: These objects wrap a call from the C PPAPI into | 30 // Enter* helper objects: These objects wrap a call from the C PPAPI into |
| 24 // the internal implementation. They make sure the lock is acquired and will | 31 // the internal implementation. They make sure the lock is acquired and will |
| 25 // automatically set up some stuff for you. | 32 // automatically set up some stuff for you. |
| 26 // | 33 // |
| 27 // You should always check whether the enter succeeded before using the object. | 34 // You should always check whether the enter succeeded before using the object. |
| 28 // If this fails, then the instance or resource ID supplied was invalid. | 35 // If this fails, then the instance or resource ID supplied was invalid. |
| 29 // | 36 // |
| 30 // The |report_error| arguments to the constructor should indicate if errors | 37 // The |report_error| arguments to the constructor should indicate if errors |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 46 // This helps us define our RAII Enter classes easily. To make an RAII class | 53 // This helps us define our RAII Enter classes easily. To make an RAII class |
| 47 // which locks the proxy lock on construction and unlocks on destruction, | 54 // which locks the proxy lock on construction and unlocks on destruction, |
| 48 // inherit from |LockOnEntry<true>|. For cases where you don't want to lock, | 55 // inherit from |LockOnEntry<true>|. For cases where you don't want to lock, |
| 49 // inherit from |LockOnEntry<false>|. This allows us to share more code between | 56 // inherit from |LockOnEntry<false>|. This allows us to share more code between |
| 50 // Enter* and Enter*NoLock classes. | 57 // Enter* and Enter*NoLock classes. |
| 51 template <bool lock_on_entry> | 58 template <bool lock_on_entry> |
| 52 struct LockOnEntry; | 59 struct LockOnEntry; |
| 53 | 60 |
| 54 template <> | 61 template <> |
| 55 struct LockOnEntry<false> { | 62 struct LockOnEntry<false> { |
| 56 // TODO(dmichael) assert the lock is held. | 63 #if (!NDEBUG) |
| 64 LockOnEntry() { | |
| 65 // You must already hold the lock to use Enter*NoLock. | |
| 66 AssertLockHeld(); | |
| 67 } | |
| 68 ~LockOnEntry() { | |
| 69 // You must not release the lock before leaving the scope of the | |
| 70 // Enter*NoLock. | |
| 71 AssertLockHeld(); | |
| 72 } | |
| 73 private: | |
| 74 static void AssertLockHeld() { | |
| 75 base::Lock* proxy_lock = PpapiGlobals::Get()->GetProxyLock(); | |
| 76 if (proxy_lock) | |
| 77 proxy_lock->AssertAcquired(); | |
| 78 } | |
| 79 #endif | |
| 57 }; | 80 }; |
| 58 | 81 |
| 59 template <> | 82 template <> |
| 60 struct LockOnEntry<true> { | 83 struct LockOnEntry<true> { |
| 61 LockOnEntry() { | 84 LockOnEntry() { |
| 62 ppapi::ProxyLock::Acquire(); | 85 ppapi::ProxyLock::Acquire(); |
| 63 } | 86 } |
| 64 ~LockOnEntry() { | 87 ~LockOnEntry() { |
| 65 ppapi::ProxyLock::Release(); | 88 ppapi::ProxyLock::Release(); |
| 66 } | 89 } |
| 67 }; | 90 }; |
| 68 | 91 |
| 69 // Keep non-templatized since we need non-inline functions here. | 92 // Keep non-templatized since we need non-inline functions here. |
| 70 class PPAPI_THUNK_EXPORT EnterBase { | 93 class PPAPI_THUNK_EXPORT EnterBase { |
| 71 public: | 94 public: |
| 72 EnterBase(); | 95 EnterBase(); |
| 73 explicit EnterBase(const PP_CompletionCallback& callback); | 96 explicit EnterBase(PP_Resource resource); |
| 97 EnterBase(PP_Resource resource, const PP_CompletionCallback& callback); | |
| 74 virtual ~EnterBase(); | 98 virtual ~EnterBase(); |
| 75 | 99 |
| 76 // Sets the result. | 100 // Sets the result for calls that use a completion callback. It handles making |
| 101 // sure that "Required" callbacks are scheduled to run asynchronously and | |
| 102 // "Blocking" callbacks cause the caller to block. (Interface implementations, | |
| 103 // therefore, should not do any special casing based on the type of the | |
| 104 // callback.) | |
| 77 // | 105 // |
| 78 // Returns the "retval()". This is to support the typical usage of | 106 // Returns the "retval()". This is to support the typical usage of |
| 79 // return enter.SetResult(...); | 107 // return enter.SetResult(...); |
| 80 // without having to write a separate "return enter.retval();" line. | 108 // without having to write a separate "return enter.retval();" line. |
| 81 int32_t SetResult(int32_t result); | 109 int32_t SetResult(int32_t result); |
| 82 | 110 |
| 83 // Use this value as the return value for the function. | 111 // Use this value as the return value for the function. |
| 84 int32_t retval() const { return retval_; } | 112 int32_t retval() const { return retval_; } |
| 85 | 113 |
| 114 bool succeeded() const { return retval_ == PP_OK; } | |
| 115 bool failed() const { return !succeeded(); } | |
| 116 | |
| 117 const scoped_refptr<TrackedCallback>& callback() { return callback_; } | |
| 118 | |
| 86 protected: | 119 protected: |
| 87 // Helper function to return a function group from a PP_Instance. Having this | 120 // Helper function to return a function group from a PP_Instance. Having this |
| 88 // code be in the non-templatized base keeps us from having to instantiate | 121 // code be in the non-templatized base keeps us from having to instantiate |
| 89 // it in every template. | 122 // it in every template. |
| 90 FunctionGroupBase* GetFunctions(PP_Instance instance, ApiID id) const; | 123 FunctionGroupBase* GetFunctions(PP_Instance instance, ApiID id) const; |
| 91 | 124 |
| 92 // Helper function to return a Resource from a PP_Resource. Having this | 125 // Helper function to return a Resource from a PP_Resource. Having this |
| 93 // code be in the non-templatized base keeps us from having to instantiate | 126 // code be in the non-templatized base keeps us from having to instantiate |
| 94 // it in every template. | 127 // it in every template. |
| 95 Resource* GetResource(PP_Resource resource) const; | 128 static Resource* GetResource(PP_Resource resource); |
| 129 | |
| 130 // Checks whether the callback is valid (i.e., if it is either non-blocking, | |
| 131 // or blocking and we're on a background thread). If the callback is invalid, | |
| 132 // this will set retval_ = PP_ERROR_BLOCKS_MAIN_THREAD, and if report_error is | |
| 133 // set, it will log a message to the programmer. | |
| 134 void SetStateForCallbackError(bool report_error); | |
| 135 bool CallbackIsValid() const; | |
| 96 | 136 |
| 97 // Does error handling associated with entering a resource. The resource_base | 137 // Does error handling associated with entering a resource. The resource_base |
| 98 // is the result of looking up the given pp_resource. The object is the | 138 // is the result of looking up the given pp_resource. The object is the |
| 99 // result of converting the base to the desired object (converted back to a | 139 // result of converting the base to the desired object (converted to a void* |
| 100 // Resource* so this function doesn't have to be templatized). The reason for | 140 // so this function doesn't have to be templatized). The reason for passing |
| 101 // passing both resource_base and object is that we can differentiate "bad | 141 // both resource_base and object is that we can differentiate "bad resource |
| 102 // resource ID" from "valid resource ID not of the currect type." | 142 // ID" from "valid resource ID not of the correct type." |
| 103 // | 143 // |
| 104 // This will set retval_ = PP_ERROR_BADRESOURCE if the object is invalid, and | 144 // This will set retval_ = PP_ERROR_BADRESOURCE if the object is invalid, and |
| 105 // if report_error is set, log a message to the programmer. | 145 // if report_error is set, log a message to the programmer. |
| 106 void SetStateForResourceError(PP_Resource pp_resource, | 146 void SetStateForResourceError(PP_Resource pp_resource, |
| 107 Resource* resource_base, | 147 Resource* resource_base, |
| 108 void* object, | 148 void* object, |
| 109 bool report_error); | 149 bool report_error); |
| 110 | 150 |
| 111 // Same as SetStateForResourceError except for function API. | 151 // Same as SetStateForResourceError except for function API. |
| 112 void SetStateForFunctionError(PP_Instance pp_instance, | 152 void SetStateForFunctionError(PP_Instance pp_instance, |
| 113 void* object, | 153 void* object, |
| 114 bool report_error); | 154 bool report_error); |
| 115 | 155 |
| 156 // For Enter objects that need a resource, we'll store a pointer to the | |
| 157 // Resource object so that we don't need to look it up more than once. For | |
| 158 // Enter objects with no resource, this will be NULL. | |
| 159 Resource* resource_; | |
| 160 | |
| 116 private: | 161 private: |
| 117 // Holds the callback. The function will only be non-NULL when the | 162 // Holds the callback. For Enter objects that aren't given a callback, this |
| 118 // callback is requried. Optional callbacks don't require any special | 163 // will be NULL. |
| 119 // handling from us at this layer. | 164 scoped_refptr<TrackedCallback> callback_; |
| 120 PP_CompletionCallback callback_; | |
| 121 | 165 |
| 122 int32_t retval_; | 166 int32_t retval_; |
| 123 }; | 167 }; |
| 124 | 168 |
| 125 } // namespace subtle | 169 } // namespace subtle |
| 126 | 170 |
| 127 // EnterFunction -------------------------------------------------------------- | 171 // EnterFunction -------------------------------------------------------------- |
| 128 | 172 |
| 129 template<typename FunctionsT, bool lock_on_entry = true> | 173 template<typename FunctionsT, bool lock_on_entry = true> |
| 130 class EnterFunction : public subtle::EnterBase, | 174 class EnterFunction : public subtle::EnterBase, |
| 131 public subtle::LockOnEntry<lock_on_entry> { | 175 public subtle::LockOnEntry<lock_on_entry> { |
| 132 public: | 176 public: |
| 133 EnterFunction(PP_Instance instance, bool report_error) | 177 EnterFunction(PP_Instance instance, bool report_error) |
| 134 : EnterBase() { | 178 : EnterBase(instance) { |
| 135 Init(instance, report_error); | 179 Init(instance, report_error); |
| 136 } | 180 } |
| 137 EnterFunction(PP_Instance instance, | 181 EnterFunction(PP_Instance instance, |
| 138 const PP_CompletionCallback& callback, | 182 const PP_CompletionCallback& callback, |
| 139 bool report_error) | 183 bool report_error) |
| 140 : EnterBase(callback) { | 184 : EnterBase(0 /* resource */, callback) { |
| 185 // TODO(dmichael): This means that the callback_ we get is not associated | |
| 186 // even with the instance, but we need to handle that for | |
| 187 // MouseLock (maybe others?). | |
| 141 Init(instance, report_error); | 188 Init(instance, report_error); |
| 142 } | 189 } |
| 143 | 190 |
| 144 ~EnterFunction() {} | 191 ~EnterFunction() {} |
| 145 | 192 |
| 146 bool succeeded() const { return !!functions_; } | 193 /* bool succeeded() const { return !!functions_ && CallbackIsValid(); } |
| 147 bool failed() const { return !functions_; } | 194 bool failed() const { return !succeeded(); }*/ |
| 148 | 195 |
| 149 FunctionsT* functions() { return functions_; } | 196 FunctionsT* functions() { return functions_; } |
| 150 | 197 |
| 151 private: | 198 private: |
| 152 void Init(PP_Instance instance, bool report_error) { | 199 void Init(PP_Instance instance, bool report_error) { |
| 153 FunctionGroupBase* base = GetFunctions(instance, FunctionsT::kApiID); | 200 FunctionGroupBase* base = GetFunctions(instance, FunctionsT::kApiID); |
| 154 if (base) | 201 if (base) |
| 155 functions_ = base->GetAs<FunctionsT>(); | 202 functions_ = base->GetAs<FunctionsT>(); |
| 156 else | 203 else |
| 157 functions_ = NULL; | 204 functions_ = NULL; |
| 205 // Validate the callback. | |
| 206 SetStateForCallbackError(report_error); | |
| 207 // Validate the resource (note, if both are wrong, we will return | |
| 208 // PP_ERROR_BADARGUMENT; last in wins). | |
| 158 SetStateForFunctionError(instance, functions_, report_error); | 209 SetStateForFunctionError(instance, functions_, report_error); |
| 159 } | 210 } |
| 160 | 211 |
| 161 FunctionsT* functions_; | 212 FunctionsT* functions_; |
| 162 | 213 |
| 163 DISALLOW_COPY_AND_ASSIGN(EnterFunction); | 214 DISALLOW_COPY_AND_ASSIGN(EnterFunction); |
| 164 }; | 215 }; |
| 165 | 216 |
| 166 // Like EnterFunction but assumes the lock is already held. | 217 // Like EnterFunction but assumes the lock is already held. |
| 167 template<typename FunctionsT> | 218 template<typename FunctionsT> |
| 168 class EnterFunctionNoLock : public EnterFunction<FunctionsT, false> { | 219 class EnterFunctionNoLock : public EnterFunction<FunctionsT, false> { |
| 169 public: | 220 public: |
| 170 EnterFunctionNoLock(PP_Instance instance, bool report_error) | 221 EnterFunctionNoLock(PP_Instance instance, bool report_error) |
| 171 : EnterFunction<FunctionsT, false>(instance, report_error) { | 222 : EnterFunction<FunctionsT, false>(instance, report_error) { |
| 172 } | 223 } |
| 173 }; | 224 }; |
| 174 | 225 |
| 175 // Used when a caller has a resource, and wants to do EnterFunction for the | 226 // Used when a caller has a resource, and wants to do EnterFunction for the |
| 176 // instance corresponding to that resource. | 227 // instance corresponding to that resource. |
| 177 template<typename FunctionsT> | 228 template<typename FunctionsT> |
| 178 class EnterFunctionGivenResource : public EnterFunction<FunctionsT> { | 229 class EnterFunctionGivenResource : public EnterFunction<FunctionsT> { |
| 179 public: | 230 public: |
| 180 EnterFunctionGivenResource(PP_Resource resource, bool report_error) | 231 EnterFunctionGivenResource(PP_Resource resource, bool report_error) |
| 181 : EnterFunction<FunctionsT>(GetInstanceForResource(resource), | 232 : EnterFunction<FunctionsT>(GetInstanceForResource(resource), |
| 182 report_error) { | 233 report_error) { |
| 183 } | 234 } |
| 184 | 235 |
| 185 private: | 236 private: |
| 186 static PP_Instance GetInstanceForResource(PP_Resource resource) { | 237 static PP_Instance GetInstanceForResource(PP_Resource resource) { |
| 187 Resource* object = | 238 Resource* object = subtle::EnterBase::GetResource(resource); |
| 188 PpapiGlobals::Get()->GetResourceTracker()->GetResource(resource); | |
| 189 return object ? object->pp_instance() : 0; | 239 return object ? object->pp_instance() : 0; |
| 190 } | 240 } |
| 191 }; | 241 }; |
| 192 | 242 |
| 193 // EnterResource --------------------------------------------------------------- | 243 // EnterResource --------------------------------------------------------------- |
| 194 | 244 |
| 195 template<typename ResourceT, bool lock_on_entry = true> | 245 template<typename ResourceT, bool lock_on_entry = true> |
| 196 class EnterResource : public subtle::EnterBase, | 246 class EnterResource : public subtle::EnterBase, |
| 197 public subtle::LockOnEntry<lock_on_entry> { | 247 public subtle::LockOnEntry<lock_on_entry> { |
| 198 public: | 248 public: |
| 199 EnterResource(PP_Resource resource, bool report_error) | 249 EnterResource(PP_Resource resource, bool report_error) |
| 200 : EnterBase() { | 250 : EnterBase(resource) { |
| 201 Init(resource, report_error); | 251 Init(resource, report_error); |
| 202 } | 252 } |
| 203 EnterResource(PP_Resource resource, | 253 EnterResource(PP_Resource resource, const PP_CompletionCallback& callback, |
| 204 const PP_CompletionCallback& callback, | |
| 205 bool report_error) | 254 bool report_error) |
| 206 : EnterBase(callback) { | 255 : EnterBase(resource, callback) { |
| 207 Init(resource, report_error); | 256 Init(resource, report_error); |
| 208 } | 257 } |
| 209 ~EnterResource() {} | 258 ~EnterResource() {} |
| 210 | 259 |
| 211 bool succeeded() const { return !!object_; } | 260 /* bool succeeded() const { return !!object_ && CallbackIsValid(); } |
| 212 bool failed() const { return !object_; } | 261 bool failed() const { return !succeeded(); }*/ |
| 213 | 262 |
| 214 ResourceT* object() { return object_; } | 263 ResourceT* object() { return object_; } |
| 215 Resource* resource() { return resource_; } | 264 Resource* resource() { return resource_; } |
| 216 | 265 |
| 217 private: | 266 private: |
| 218 void Init(PP_Resource resource, bool report_error) { | 267 void Init(PP_Resource resource, bool report_error) { |
| 219 resource_ = GetResource(resource); | |
| 220 if (resource_) | 268 if (resource_) |
| 221 object_ = resource_->GetAs<ResourceT>(); | 269 object_ = resource_->GetAs<ResourceT>(); |
| 222 else | 270 else |
| 223 object_ = NULL; | 271 object_ = NULL; |
| 272 // Validate the callback. | |
| 273 SetStateForCallbackError(report_error); | |
| 274 // Validate the resource (note, if both are wrong, we will return | |
| 275 // PP_ERROR_BADRESOURCE; last in wins). | |
| 224 SetStateForResourceError(resource, resource_, object_, report_error); | 276 SetStateForResourceError(resource, resource_, object_, report_error); |
| 225 } | 277 } |
| 226 | 278 |
| 227 Resource* resource_; | |
| 228 ResourceT* object_; | 279 ResourceT* object_; |
| 229 | 280 |
| 230 DISALLOW_COPY_AND_ASSIGN(EnterResource); | 281 DISALLOW_COPY_AND_ASSIGN(EnterResource); |
| 231 }; | 282 }; |
| 232 | 283 |
| 233 // ---------------------------------------------------------------------------- | 284 // ---------------------------------------------------------------------------- |
| 234 | 285 |
| 235 // Like EnterResource but assumes the lock is already held. | 286 // Like EnterResource but assumes the lock is already held. |
| 236 template<typename ResourceT> | 287 template<typename ResourceT> |
| 237 class EnterResourceNoLock : public EnterResource<ResourceT, false> { | 288 class EnterResourceNoLock : public EnterResource<ResourceT, false> { |
| 238 public: | 289 public: |
| 239 EnterResourceNoLock(PP_Resource resource, bool report_error) | 290 EnterResourceNoLock(PP_Resource resource, bool report_error) |
| 240 : EnterResource<ResourceT, false>(resource, report_error) { | 291 : EnterResource<ResourceT, false>(resource, report_error) { |
| 241 } | 292 } |
| 293 EnterResourceNoLock(PP_Resource resource, PP_CompletionCallback callback, | |
| 294 bool report_error) | |
| 295 : EnterResource<ResourceT, false>(resource, callback, report_error) { | |
| 296 } | |
| 242 }; | 297 }; |
| 243 | 298 |
| 244 // Simpler wrapper to enter the resource creation API. This is used for every | 299 // Simpler wrapper to enter the resource creation API. This is used for every |
| 245 // class so we have this helper function to save template instantiations and | 300 // class so we have this helper function to save template instantiations and |
| 246 // typing. | 301 // typing. |
| 247 class PPAPI_THUNK_EXPORT EnterResourceCreation | 302 class PPAPI_THUNK_EXPORT EnterResourceCreation |
| 248 : public EnterFunction<ResourceCreationAPI> { | 303 : public EnterFunction<ResourceCreationAPI> { |
| 249 public: | 304 public: |
| 250 EnterResourceCreation(PP_Instance instance); | 305 EnterResourceCreation(PP_Instance instance); |
| 251 ~EnterResourceCreation(); | 306 ~EnterResourceCreation(); |
| 252 }; | 307 }; |
| 253 | 308 |
| 254 // Simpler wrapper to enter the instance API from proxy code. This is used for | 309 // Simpler wrapper to enter the instance API from proxy code. This is used for |
| 255 // many interfaces so we have this helper function to save template | 310 // many interfaces so we have this helper function to save template |
| 256 // instantiations and typing. | 311 // instantiations and typing. |
| 257 class PPAPI_THUNK_EXPORT EnterInstance | 312 class PPAPI_THUNK_EXPORT EnterInstance |
| 258 : public EnterFunction<PPB_Instance_FunctionAPI> { | 313 : public EnterFunction<PPB_Instance_FunctionAPI> { |
| 259 public: | 314 public: |
| 260 EnterInstance(PP_Instance instance); | 315 EnterInstance(PP_Instance instance); |
| 261 EnterInstance(PP_Instance instance, const PP_CompletionCallback& callback); | 316 EnterInstance(PP_Instance instance, const PP_CompletionCallback& callback); |
| 262 ~EnterInstance(); | 317 ~EnterInstance(); |
| 263 }; | 318 }; |
|
dmichael (off chromium)
2012/04/19 20:02:00
I needed EnterInstanceNoLock to make AudioConfigSh
| |
| 264 | 319 |
| 320 class PPAPI_THUNK_EXPORT EnterInstanceNoLock | |
| 321 : public EnterFunctionNoLock<PPB_Instance_FunctionAPI> { | |
| 322 public: | |
| 323 EnterInstanceNoLock(PP_Instance instance); | |
| 324 EnterInstanceNoLock(PP_Instance instance, | |
| 325 const PP_CompletionCallback& callback); | |
| 326 ~EnterInstanceNoLock(); | |
| 327 }; | |
| 328 | |
| 329 | |
| 265 } // namespace thunk | 330 } // namespace thunk |
| 266 } // namespace ppapi | 331 } // namespace ppapi |
| 267 | 332 |
| 268 #endif // PPAPI_THUNK_ENTER_H_ | 333 #endif // PPAPI_THUNK_ENTER_H_ |
| OLD | NEW |