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
3 // found in the LICENSE file.
5 #ifndef PPAPI_SHARED_IMPL_PROXY_LOCK_H_
6 #define PPAPI_SHARED_IMPL_PROXY_LOCK_H_
8 #include "base/basictypes.h"
10 #include "base/callback.h"
12 #include "ppapi/shared_impl/ppapi_shared_export.h"
20 // 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
22 // is normally accomplished by using an appropriate Enter RAII object at the
23 // beginning of each thunk function.
25 // 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
28 class PPAPI_SHARED_EXPORT ProxyLock
{
30 // 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,
32 // 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-
34 // process plugin case.
35 static void Acquire();
36 // Relinquish the proxy lock. If the lock has not been set, this does nothing.
37 static void Release();
39 // Assert that the lock is owned by the current thread (in the plugin
40 // process). Does nothing when running in-process (or in the host process).
41 static void AssertAcquired();
44 DISALLOW_IMPLICIT_CONSTRUCTORS(ProxyLock
);
47 // A simple RAII class for locking the PPAPI proxy lock on entry and releasing
48 // on exit. This is for simple interfaces that don't use the 'thunk' system,
49 // such as PPB_Var and PPB_Core.
59 DISALLOW_COPY_AND_ASSIGN(ProxyAutoLock
);
62 // The inverse of the above; unlock on construction, lock on destruction. This
63 // is useful for calling out to the plugin, when we need to unlock but ensure
64 // that we re-acquire the lock when the plugin is returns or raises an
66 class ProxyAutoUnlock
{
75 DISALLOW_COPY_AND_ASSIGN(ProxyAutoUnlock
);
78 // A set of function template overloads for invoking a function pointer while
79 // the ProxyLock is unlocked. This assumes that the luck is held.
80 // CallWhileUnlocked unlocks the ProxyLock just before invoking the given
81 // function. The lock is immediately re-acquired when the invoked function
82 // function returns. CallWhileUnlocked returns whatever the given function
86 // *result = CallWhileUnlocked(ppp_input_event_impl_->HandleInputEvent,
88 // resource->pp_resource());
89 template <class ReturnType
>
90 ReturnType
CallWhileUnlocked(ReturnType (*function
)()) {
91 ProxyAutoUnlock unlock
;
94 template <class ReturnType
, class P1
>
95 ReturnType
CallWhileUnlocked(ReturnType (*function
)(P1
), const P1
& p1
) {
96 ProxyAutoUnlock unlock
;
99 template <class ReturnType
, class P1
, class P2
>
100 ReturnType
CallWhileUnlocked(ReturnType (*function
)(P1
, P2
),
103 ProxyAutoUnlock unlock
;
104 return function(p1
, p2
);
106 template <class ReturnType
, class P1
, class P2
, class P3
>
107 ReturnType
CallWhileUnlocked(ReturnType (*function
)(P1
, P2
, P3
),
111 ProxyAutoUnlock unlock
;
112 return function(p1
, p2
, p3
);
114 template <class ReturnType
, class P1
, class P2
, class P3
, class P4
>
115 ReturnType
CallWhileUnlocked(ReturnType (*function
)(P1
, P2
, P3
, P4
),
120 ProxyAutoUnlock unlock
;
121 return function(p1
, p2
, p3
, p4
);
123 template <class ReturnType
, class P1
, class P2
, class P3
, class P4
, class P5
>
124 ReturnType
CallWhileUnlocked(ReturnType (*function
)(P1
, P2
, P3
, P4
, P5
),
130 ProxyAutoUnlock unlock
;
131 return function(p1
, p2
, p3
, p4
, p5
);
133 void PPAPI_SHARED_EXPORT
CallWhileUnlocked(const base::Closure
& closure
);
135 // CallWhileLocked locks the ProxyLock and runs the given closure immediately.
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
);
140 // RunWhileLocked binds the given closure with CallWhileLocked and returns the
141 // new Closure. This is for cases where you want to run a task, but you want to
142 // ensure that the ProxyLock is acquired for the duration of the task.
144 // GetMainThreadMessageLoop()->PostDelayedTask(
146 // RunWhileLocked(base::Bind(&CallbackWrapper, callback, result)),
148 inline base::Closure
RunWhileLocked(const base::Closure
& closure
) {
149 return base::Bind(CallWhileLocked
, closure
);
154 #endif // PPAPI_SHARED_IMPL_PROXY_LOCK_H_