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. 4 5 #include "ppapi/shared_impl/proxy_lock.h" 6 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" 11 12 namespace ppapi { 13 14 // Simple single-thread deadlock detector for the proxy lock. 15 // |true| when the current thread has the lock. 16 base::LazyInstance<base::ThreadLocalBoolean>::Leaky 17 g_proxy_locked_on_thread = LAZY_INSTANCE_INITIALIZER; 18 19 // static 20 void ProxyLock::Acquire() { 21 base::Lock* lock(PpapiGlobals::Get()->GetProxyLock()); 22 if (lock) { 23 // This thread does not already hold the lock. 24 const bool deadlock = g_proxy_locked_on_thread.Get().Get(); 25 CHECK(!deadlock); 26 27 lock->Acquire(); 28 g_proxy_locked_on_thread.Get().Set(true); 29 } 30 } 31 32 // static 33 void ProxyLock::Release() { 34 base::Lock* lock(PpapiGlobals::Get()->GetProxyLock()); 35 if (lock) { 36 // This thread currently holds the lock. 37 const bool locked = g_proxy_locked_on_thread.Get().Get(); 38 CHECK(locked); 39 40 g_proxy_locked_on_thread.Get().Set(false); 41 lock->Release(); 42 } 43 } 44 45 // static 46 void ProxyLock::AssertAcquired() { 47 base::Lock* lock(PpapiGlobals::Get()->GetProxyLock()); 48 if (lock) { 49 // This thread currently holds the lock. 50 const bool locked = g_proxy_locked_on_thread.Get().Get(); 51 CHECK(locked); 52 53 lock->AssertAcquired(); 54 } 55 } 56 57 void CallWhileUnlocked(const base::Closure& closure) { 58 ProxyAutoUnlock lock; 59 closure.Run(); 60 } 61 62 } // namespace ppapi 63