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_SHARED_IMPL_PROXY_LOCK_H_ | 5 #ifndef PPAPI_SHARED_IMPL_PROXY_LOCK_H_ |
| 6 #define PPAPI_SHARED_IMPL_PROXY_LOCK_H_ | 6 #define PPAPI_SHARED_IMPL_PROXY_LOCK_H_ |
| 7 | 7 |
| 8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 const P1& p1, | 125 const P1& p1, |
| 126 const P2& p2, | 126 const P2& p2, |
| 127 const P3& p3, | 127 const P3& p3, |
| 128 const P4& p4, | 128 const P4& p4, |
| 129 const P5& p5) { | 129 const P5& p5) { |
| 130 ProxyAutoUnlock unlock; | 130 ProxyAutoUnlock unlock; |
| 131 return function(p1, p2, p3, p4, p5); | 131 return function(p1, p2, p3, p4, p5); |
| 132 } | 132 } |
| 133 void PPAPI_SHARED_EXPORT CallWhileUnlocked(const base::Closure& closure); | 133 void PPAPI_SHARED_EXPORT CallWhileUnlocked(const base::Closure& closure); |
| 134 | 134 |
| 135 // CallWhileLocked locks the ProxyLock and runs the given closure immediately. | 135 namespace internal { |
| 136 // The lock is released when CallWhileLocked returns. This function assumes the | |
| 137 // lock is not held. This is mostly for use in RunWhileLocked; see below. | |
| 138 void PPAPI_SHARED_EXPORT CallWhileLocked(const base::Closure& closure); | |
| 139 | 136 |
| 140 // RunWhileLocked binds the given closure with CallWhileLocked and returns the | 137 template <typename RunType> |
| 141 // new Closure. This is for cases where you want to run a task, but you want to | 138 struct RunWhleLockedHelper; |
| 142 // ensure that the ProxyLock is acquired for the duration of the task. | 139 |
| 140 template <> | |
| 141 struct RunWhleLockedHelper<void ()> { | |
|
bbudge
2013/07/20 14:01:24
sp. RunWhileLockedHelper
| |
| 142 typedef base::Callback<void()> CallbackType; | |
| 143 explicit RunWhleLockedHelper(const CallbackType& callback) | |
| 144 : callback_(new CallbackType(callback)) { | |
| 145 } | |
| 146 void CallWhileLocked() { | |
| 147 ProxyAutoLock lock; | |
| 148 { | |
| 149 // Use a scope and local Callback to ensure that the callback is cleared | |
| 150 // before the lock is released, even in the unlikely event that Run() | |
| 151 // throws an exception. | |
| 152 scoped_ptr<CallbackType> temp_callback(callback_.Pass()); | |
| 153 temp_callback->Run(); | |
| 154 } | |
| 155 } | |
| 156 private: | |
| 157 scoped_ptr<CallbackType> callback_; | |
| 158 }; | |
| 159 template <typename P1> | |
| 160 struct RunWhleLockedHelper<void (P1)> { | |
| 161 typedef base::Callback<void(P1)> CallbackType; | |
| 162 explicit RunWhleLockedHelper(const CallbackType& callback) | |
| 163 : callback_(new CallbackType(callback)) { | |
| 164 } | |
| 165 void CallWhileLocked(P1 p1) { | |
| 166 ProxyAutoLock lock; | |
| 167 { | |
| 168 scoped_ptr<CallbackType> temp_callback(callback_.Pass()); | |
| 169 temp_callback->Run(p1); | |
| 170 } | |
| 171 } | |
| 172 private: | |
| 173 scoped_ptr<CallbackType> callback_; | |
| 174 }; | |
| 175 template <typename P1, typename P2> | |
| 176 struct RunWhleLockedHelper<void (P1, P2)> { | |
| 177 typedef base::Callback<void(P1, P2)> CallbackType; | |
| 178 explicit RunWhleLockedHelper(const CallbackType& callback) | |
| 179 : callback_(new CallbackType(callback)) { | |
| 180 } | |
| 181 void CallWhileLocked(P1 p1, P2 p2) { | |
| 182 ProxyAutoLock lock; | |
| 183 { | |
| 184 scoped_ptr<CallbackType> temp_callback(callback_.Pass()); | |
| 185 temp_callback->Run(p1, p2); | |
| 186 } | |
| 187 } | |
| 188 private: | |
| 189 scoped_ptr<CallbackType> callback_; | |
| 190 }; | |
| 191 template <typename P1, typename P2, typename P3> | |
| 192 struct RunWhleLockedHelper<void (P1, P2, P3)> { | |
| 193 typedef base::Callback<void(P1, P2, P3)> CallbackType; | |
| 194 explicit RunWhleLockedHelper(const CallbackType& callback) | |
| 195 : callback_(new CallbackType(callback)) { | |
| 196 } | |
| 197 void CallWhileLocked(P1 p1, P2 p2, P3 p3) { | |
| 198 ProxyAutoLock lock; | |
| 199 { | |
| 200 scoped_ptr<CallbackType> temp_callback(callback_.Pass()); | |
| 201 temp_callback->Run(p1, p2, p3); | |
| 202 } | |
| 203 } | |
| 204 private: | |
| 205 scoped_ptr<CallbackType> callback_; | |
| 206 }; | |
| 207 | |
| 208 } // namespace internal | |
| 209 | |
| 210 // RunWhileLocked wraps the given Callback in a new Callback that, when invoked: | |
| 211 // 1) Locks the ProxyLock. | |
| 212 // 2) Runs the original Callback (forwarding arguments, if any). | |
| 213 // 3) Clears the original Callback (while the lock is held). | |
| 214 // 4) Unlocks the ProxyLock. | |
| 215 // Note that it's important that the callback is cleared in step (3), in case | |
| 216 // clearing the Callback causes a destructor (e.g., for a Resource) to run, | |
| 217 // which should hold the ProxyLock to avoid data races. | |
| 218 // | |
| 219 // This is for cases where you want to run a task or store a Callback, but you | |
| 220 // want to ensure that the ProxyLock is acquired for the duration of the task. | |
| 143 // Example usage: | 221 // Example usage: |
| 144 // GetMainThreadMessageLoop()->PostDelayedTask( | 222 // GetMainThreadMessageLoop()->PostDelayedTask( |
| 145 // FROM_HERE, | 223 // FROM_HERE, |
| 146 // RunWhileLocked(base::Bind(&CallbackWrapper, callback, result)), | 224 // RunWhileLocked(base::Bind(&CallbackWrapper, callback, result)), |
| 147 // delay_in_ms); | 225 // delay_in_ms); |
| 148 inline base::Closure RunWhileLocked(const base::Closure& closure) { | 226 template <class FunctionType> |
| 149 return base::Bind(CallWhileLocked, closure); | 227 inline base::Callback<FunctionType> |
| 228 RunWhileLocked(const base::Callback<FunctionType>& callback) { | |
| 229 internal::RunWhleLockedHelper<FunctionType>* helper = | |
| 230 new internal::RunWhleLockedHelper<FunctionType>(callback); | |
| 231 return base::Bind( | |
| 232 &internal::RunWhleLockedHelper<FunctionType>::CallWhileLocked, | |
| 233 base::Owned(helper)); | |
| 150 } | 234 } |
| 151 | 235 |
| 152 } // namespace ppapi | 236 } // namespace ppapi |
| 153 | 237 |
| 154 #endif // PPAPI_SHARED_IMPL_PROXY_LOCK_H_ | 238 #endif // PPAPI_SHARED_IMPL_PROXY_LOCK_H_ |
| OLD | NEW |