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/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 |