Index: ppapi/shared_impl/proxy_lock.cc |
diff --git a/ppapi/shared_impl/proxy_lock.cc b/ppapi/shared_impl/proxy_lock.cc |
index 990130a19c6b127344875f256127c5b21481adcf..f9f937f2e2681753cff8ff2c253ab7bf5ede8c1e 100644 |
--- a/ppapi/shared_impl/proxy_lock.cc |
+++ b/ppapi/shared_impl/proxy_lock.cc |
@@ -4,30 +4,54 @@ |
#include "ppapi/shared_impl/proxy_lock.h" |
+#include "base/lazy_instance.h" |
#include "base/synchronization/lock.h" |
+#include "base/threading/thread_local.h" |
#include "ppapi/shared_impl/ppapi_globals.h" |
namespace ppapi { |
+// Simple single-thread deadlock detector for the proxy lock. |
+// |true| when the current thread has the lock. |
+base::LazyInstance<base::ThreadLocalBoolean>::Leaky |
+ g_proxy_locked_on_thread = LAZY_INSTANCE_INITIALIZER; |
+ |
// static |
void ProxyLock::Acquire() { |
base::Lock* lock(PpapiGlobals::Get()->GetProxyLock()); |
- if (lock) |
+ if (lock) { |
+ // This thread does not already hold the lock. |
+ const bool deadlock = g_proxy_locked_on_thread.Get().Get(); |
+ CHECK(!deadlock); |
+ |
lock->Acquire(); |
+ g_proxy_locked_on_thread.Get().Set(true); |
+ } |
} |
// static |
void ProxyLock::Release() { |
base::Lock* lock(PpapiGlobals::Get()->GetProxyLock()); |
- if (lock) |
+ if (lock) { |
+ // This thread currently holds the lock. |
+ const bool locked = g_proxy_locked_on_thread.Get().Get(); |
+ CHECK(locked); |
+ |
+ g_proxy_locked_on_thread.Get().Set(false); |
lock->Release(); |
+ } |
} |
// static |
void ProxyLock::AssertAcquired() { |
base::Lock* lock(PpapiGlobals::Get()->GetProxyLock()); |
- if (lock) |
+ if (lock) { |
+ // This thread currently holds the lock. |
+ const bool locked = g_proxy_locked_on_thread.Get().Get(); |
+ CHECK(locked); |
+ |
lock->AssertAcquired(); |
+ } |
} |
void CallWhileUnlocked(const base::Closure& closure) { |