Blink roll 172110:172126
[chromium-blink-merge.git] / ppapi / shared_impl / proxy_lock.cc
blob6598379ca8b74f8b5f72ce47b7f121dcc3d583eb
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 #include "ppapi/shared_impl/proxy_lock.h"
7 #include "base/lazy_instance.h"
8 #include "base/synchronization/lock.h"
9 #include "base/threading/thread_local.h"
10 #include "ppapi/shared_impl/ppapi_globals.h"
12 namespace ppapi {
14 base::LazyInstance<base::Lock>::Leaky g_proxy_lock = LAZY_INSTANCE_INITIALIZER;
16 bool g_disable_locking = false;
17 base::LazyInstance<base::ThreadLocalBoolean>::Leaky
18 g_disable_locking_for_thread = LAZY_INSTANCE_INITIALIZER;
20 // Simple single-thread deadlock detector for the proxy lock.
21 // |true| when the current thread has the lock.
22 base::LazyInstance<base::ThreadLocalBoolean>::Leaky g_proxy_locked_on_thread =
23 LAZY_INSTANCE_INITIALIZER;
25 // static
26 base::Lock* ProxyLock::Get() {
27 if (g_disable_locking || g_disable_locking_for_thread.Get().Get())
28 return NULL;
29 return &g_proxy_lock.Get();
32 // Functions below should only access the lock via Get to ensure that they don't
33 // try to use the lock on the host side of the proxy, where locking is
34 // unnecessary and wrong (because we haven't coded the host side to account for
35 // locking).
37 // static
38 void ProxyLock::Acquire() {
39 base::Lock* lock = Get();
40 if (lock) {
41 // This thread does not already hold the lock.
42 const bool deadlock = g_proxy_locked_on_thread.Get().Get();
43 CHECK(!deadlock);
45 lock->Acquire();
46 g_proxy_locked_on_thread.Get().Set(true);
50 // static
51 void ProxyLock::Release() {
52 base::Lock* lock = Get();
53 if (lock) {
54 // This thread currently holds the lock.
55 const bool locked = g_proxy_locked_on_thread.Get().Get();
56 CHECK(locked);
58 g_proxy_locked_on_thread.Get().Set(false);
59 lock->Release();
63 // static
64 void ProxyLock::AssertAcquired() {
65 base::Lock* lock = Get();
66 if (lock) {
67 // This thread currently holds the lock.
68 const bool locked = g_proxy_locked_on_thread.Get().Get();
69 CHECK(locked);
71 lock->AssertAcquired();
75 // static
76 void ProxyLock::DisableLocking() {
77 // Note, we don't DCHECK that this flag isn't already set, because multiple
78 // unit tests may run in succession and all set it.
79 g_disable_locking = true;
82 // static
83 void ProxyLock::DisableLockingOnThreadForTest() {
84 // Note, we don't DCHECK that this flag isn't already set, because multiple
85 // unit tests may run in succession and all set it.
86 g_disable_locking_for_thread.Get().Set(true);
89 // static
90 void ProxyLock::EnableLockingOnThreadForTest() {
91 g_disable_locking_for_thread.Get().Set(false);
94 void CallWhileUnlocked(const base::Closure& closure) {
95 ProxyAutoUnlock lock;
96 closure.Run();
99 } // namespace ppapi