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 |