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" | |
11 | 9 |
12 #include "ppapi/shared_impl/ppapi_shared_export.h" | 10 #include "ppapi/shared_impl/ppapi_shared_export.h" |
13 | 11 |
14 namespace base { | 12 namespace base { |
15 class Lock; | 13 class Lock; |
16 } | 14 } |
17 | 15 |
18 namespace ppapi { | 16 namespace ppapi { |
19 | 17 |
20 // This is the one lock to rule them all for the ppapi proxy. All PPB interface | 18 // This is the one lock to rule them all for the ppapi proxy. All PPB interface |
21 // functions that need to be synchronized should lock this lock on entry. This | 19 // functions that need to be synchronized should lock this lock on entry. This |
22 // is normally accomplished by using an appropriate Enter RAII object at the | 20 // is normally accomplished by using an appropriate Enter RAII object at the |
23 // beginning of each thunk function. | 21 // beginning of each thunk function. |
24 // | 22 // |
25 // TODO(dmichael): If this turns out to be too slow and contentious, we'll want | 23 // TODO(dmichael): If this turns out to be too slow and contentious, we'll want |
26 // to use multiple locks. E.g., one for the var tracker, one for the resource | 24 // to use multiple locks. E.g., one for the var tracker, one for the resource |
27 // tracker, etc. | 25 // tracker, etc. |
28 class PPAPI_SHARED_EXPORT ProxyLock { | 26 class PPAPI_SHARED_EXPORT ProxyLock { |
29 public: | 27 public: |
30 // Acquire the proxy lock. If it is currently held by another thread, block | 28 // Acquire the proxy lock. If it is currently held by another thread, block |
31 // until it is available. If the lock has not been set using the 'Set' method, | 29 // until it is available. If the lock has not been set using the 'Set' method, |
32 // this operation does nothing. That is the normal case for the host side; | 30 // this operation does nothing. That is the normal case for the host side; |
33 // see PluginResourceTracker for where the lock gets set for the out-of- | 31 // see PluginResourceTracker for where the lock gets set for the out-of- |
34 // process plugin case. | 32 // process plugin case. |
35 static void Acquire(); | 33 static void Acquire(); |
36 // Relinquish the proxy lock. If the lock has not been set, this does nothing. | 34 // Relinquish the proxy lock. If the lock has not been set, this does nothing. |
37 static void Release(); | 35 static void Release(); |
38 | 36 |
39 private: | |
40 DISALLOW_IMPLICIT_CONSTRUCTORS(ProxyLock); | 37 DISALLOW_IMPLICIT_CONSTRUCTORS(ProxyLock); |
41 }; | 38 }; |
42 | 39 |
43 // A simple RAII class for locking the PPAPI proxy lock on entry and releasing | 40 // A simple RAII class for locking the PPAPI proxy lock on entry and releasing |
44 // on exit. This is for simple interfaces that don't use the 'thunk' system, | 41 // on exit. This is for simple interfaces that don't use the 'thunk' system, |
45 // such as PPB_Var and PPB_Core. | 42 // such as PPB_Var and PPB_Core. |
46 class ProxyAutoLock { | 43 class ProxyAutoLock { |
47 public: | 44 public: |
48 ProxyAutoLock() { | 45 ProxyAutoLock() { |
49 ProxyLock::Acquire(); | 46 ProxyLock::Acquire(); |
(...skipping 14 matching lines...) Expand all Loading... |
64 ProxyAutoUnlock() { | 61 ProxyAutoUnlock() { |
65 ProxyLock::Release(); | 62 ProxyLock::Release(); |
66 } | 63 } |
67 ~ProxyAutoUnlock() { | 64 ~ProxyAutoUnlock() { |
68 ProxyLock::Acquire(); | 65 ProxyLock::Acquire(); |
69 } | 66 } |
70 private: | 67 private: |
71 DISALLOW_COPY_AND_ASSIGN(ProxyAutoUnlock); | 68 DISALLOW_COPY_AND_ASSIGN(ProxyAutoUnlock); |
72 }; | 69 }; |
73 | 70 |
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 } | |
146 | 71 |
147 } // namespace ppapi | 72 } // namespace ppapi |
148 | 73 |
149 #endif // PPAPI_SHARED_IMPL_PROXY_LOCK_H_ | 74 #endif // PPAPI_SHARED_IMPL_PROXY_LOCK_H_ |
OLD | NEW |