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" |
| 10 #include "base/callback.h" |
9 | 11 |
10 #include "ppapi/shared_impl/ppapi_shared_export.h" | 12 #include "ppapi/shared_impl/ppapi_shared_export.h" |
11 | 13 |
12 namespace base { | 14 namespace base { |
13 class Lock; | 15 class Lock; |
14 } | 16 } |
15 | 17 |
16 namespace ppapi { | 18 namespace ppapi { |
17 | 19 |
18 // This is the one lock to rule them all for the ppapi proxy. All PPB interface | 20 // This is the one lock to rule them all for the ppapi proxy. All PPB interface |
19 // functions that need to be synchronized should lock this lock on entry. This | 21 // functions that need to be synchronized should lock this lock on entry. This |
20 // is normally accomplished by using an appropriate Enter RAII object at the | 22 // is normally accomplished by using an appropriate Enter RAII object at the |
21 // beginning of each thunk function. | 23 // beginning of each thunk function. |
22 // | 24 // |
23 // TODO(dmichael): If this turns out to be too slow and contentious, we'll want | 25 // TODO(dmichael): If this turns out to be too slow and contentious, we'll want |
24 // to use multiple locks. E.g., one for the var tracker, one for the resource | 26 // to use multiple locks. E.g., one for the var tracker, one for the resource |
25 // tracker, etc. | 27 // tracker, etc. |
26 class PPAPI_SHARED_EXPORT ProxyLock { | 28 class PPAPI_SHARED_EXPORT ProxyLock { |
27 public: | 29 public: |
28 // Acquire the proxy lock. If it is currently held by another thread, block | 30 // Acquire the proxy lock. If it is currently held by another thread, block |
29 // until it is available. If the lock has not been set using the 'Set' method, | 31 // until it is available. If the lock has not been set using the 'Set' method, |
30 // this operation does nothing. That is the normal case for the host side; | 32 // this operation does nothing. That is the normal case for the host side; |
31 // see PluginResourceTracker for where the lock gets set for the out-of- | 33 // see PluginResourceTracker for where the lock gets set for the out-of- |
32 // process plugin case. | 34 // process plugin case. |
33 static void Acquire(); | 35 static void Acquire(); |
34 // Relinquish the proxy lock. If the lock has not been set, this does nothing. | 36 // Relinquish the proxy lock. If the lock has not been set, this does nothing. |
35 static void Release(); | 37 static void Release(); |
36 | 38 |
| 39 private: |
37 DISALLOW_IMPLICIT_CONSTRUCTORS(ProxyLock); | 40 DISALLOW_IMPLICIT_CONSTRUCTORS(ProxyLock); |
38 }; | 41 }; |
39 | 42 |
40 // A simple RAII class for locking the PPAPI proxy lock on entry and releasing | 43 // A simple RAII class for locking the PPAPI proxy lock on entry and releasing |
41 // on exit. This is for simple interfaces that don't use the 'thunk' system, | 44 // on exit. This is for simple interfaces that don't use the 'thunk' system, |
42 // such as PPB_Var and PPB_Core. | 45 // such as PPB_Var and PPB_Core. |
43 class ProxyAutoLock { | 46 class ProxyAutoLock { |
44 public: | 47 public: |
45 ProxyAutoLock() { | 48 ProxyAutoLock() { |
46 ProxyLock::Acquire(); | 49 ProxyLock::Acquire(); |
(...skipping 14 matching lines...) Expand all Loading... |
61 ProxyAutoUnlock() { | 64 ProxyAutoUnlock() { |
62 ProxyLock::Release(); | 65 ProxyLock::Release(); |
63 } | 66 } |
64 ~ProxyAutoUnlock() { | 67 ~ProxyAutoUnlock() { |
65 ProxyLock::Acquire(); | 68 ProxyLock::Acquire(); |
66 } | 69 } |
67 private: | 70 private: |
68 DISALLOW_COPY_AND_ASSIGN(ProxyAutoUnlock); | 71 DISALLOW_COPY_AND_ASSIGN(ProxyAutoUnlock); |
69 }; | 72 }; |
70 | 73 |
| 74 // A set of function template overloads for invoking a function pointer while |
| 75 // the ProxyLock is unlocked. This assumes that the luck is held. |
| 76 // CallWhileUnlocked unlocks the ProxyLock just before invoking the given |
| 77 // function. The lock is immediately re-acquired when the invoked function |
| 78 // function returns. CallWhileUnlocked returns whatever the given function |
| 79 // returned. |
| 80 // |
| 81 // Example usage: |
| 82 // *result = CallWhileUnlocked(ppp_input_event_impl_->HandleInputEvent, |
| 83 // instance, |
| 84 // resource->pp_resource()); |
| 85 template <class ReturnType> |
| 86 ReturnType CallWhileUnlocked(ReturnType (*function)()) { |
| 87 ProxyAutoUnlock unlock; |
| 88 return function(); |
| 89 } |
| 90 template <class ReturnType, class P1> |
| 91 ReturnType CallWhileUnlocked(ReturnType (*function)(P1), const P1& p1) { |
| 92 ProxyAutoUnlock unlock; |
| 93 return function(p1); |
| 94 } |
| 95 template <class ReturnType, class P1, class P2> |
| 96 ReturnType CallWhileUnlocked(ReturnType (*function)(P1, P2), |
| 97 const P1& p1, |
| 98 const P2& p2) { |
| 99 ProxyAutoUnlock unlock; |
| 100 return function(p1, p2); |
| 101 } |
| 102 template <class ReturnType, class P1, class P2, class P3> |
| 103 ReturnType CallWhileUnlocked(ReturnType (*function)(P1, P2, P3), |
| 104 const P1& p1, |
| 105 const P2& p2, |
| 106 const P3& p3) { |
| 107 ProxyAutoUnlock unlock; |
| 108 return function(p1, p2, p3); |
| 109 } |
| 110 template <class ReturnType, class P1, class P2, class P3, class P4> |
| 111 ReturnType CallWhileUnlocked(ReturnType (*function)(P1, P2, P3, P4), |
| 112 const P1& p1, |
| 113 const P2& p2, |
| 114 const P3& p3, |
| 115 const P4& p4) { |
| 116 ProxyAutoUnlock unlock; |
| 117 return function(p1, p2, p3, p4); |
| 118 } |
| 119 template <class ReturnType, class P1, class P2, class P3, class P4, class P5> |
| 120 ReturnType CallWhileUnlocked(ReturnType (*function)(P1, P2, P3, P4, P5), |
| 121 const P1& p1, |
| 122 const P2& p2, |
| 123 const P3& p3, |
| 124 const P4& p4, |
| 125 const P5& p5) { |
| 126 ProxyAutoUnlock unlock; |
| 127 return function(p1, p2, p3, p4, p5); |
| 128 } |
| 129 |
| 130 // CallWhileLocked locks the ProxyLock and runs the given closure immediately. |
| 131 // The lock is released when CallWhileLocked returns. This function assumes the |
| 132 // lock is not held. This is mostly for use in RunWhileLocked; see below. |
| 133 void CallWhileLocked(const base::Closure& closure); |
| 134 |
| 135 // RunWhileLocked binds the given closure with CallWhileLocked and returns the |
| 136 // new Closure. This is for cases where you want to run a task, but you want to |
| 137 // ensure that the ProxyLock is acquired for the duration of the task. |
| 138 // Example usage: |
| 139 // GetMainThreadMessageLoop()->PostDelayedTask( |
| 140 // FROM_HERE, |
| 141 // RunWhileLocked(base::Bind(&CallbackWrapper, callback, result)), |
| 142 // delay_in_ms); |
| 143 inline base::Closure RunWhileLocked(const base::Closure& closure) { |
| 144 return base::Bind(CallWhileLocked, closure); |
| 145 } |
71 | 146 |
72 } // namespace ppapi | 147 } // namespace ppapi |
73 | 148 |
74 #endif // PPAPI_SHARED_IMPL_PROXY_LOCK_H_ | 149 #endif // PPAPI_SHARED_IMPL_PROXY_LOCK_H_ |
OLD | NEW |