| 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 "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_ |
| OLD | NEW |