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..ba063f2ffc678e58a8721e20260894b0189c1f34 100644 |
--- a/ppapi/shared_impl/proxy_lock.cc |
+++ b/ppapi/shared_impl/proxy_lock.cc |
@@ -9,25 +9,66 @@ |
namespace ppapi { |
+// Simple single-thread deadlock detector for the proxy lock. |
+// |own_lock| protects |owned_by_thread| and |owning_thread_id|. |
+// |owning_thread_id| is the thread owning the proxy lock, and is only |
+// valid when |owned_by_thread| is true. |
+base::Lock own_lock; |
brettw
2012/11/29 23:44:33
Can we just use TLS to hold a bool? I think this w
Scott Hess - ex-Googler
2012/11/30 00:49:51
I think this must be why you get paid the big buck
|
+bool owned_by_thread = false; |
+base::PlatformThreadId owning_thread_id; |
+ |
// static |
void ProxyLock::Acquire() { |
base::Lock* lock(PpapiGlobals::Get()->GetProxyLock()); |
- if (lock) |
+ |
+ // The lock is unheld, or another thread holds it. |
+ if (lock) { |
+ base::AutoLock pin(own_lock); |
+ bool deadlock = owned_by_thread && |
+ owning_thread_id == base::PlatformThread::CurrentId(); |
+ CHECK(!deadlock); |
+ } |
+ |
+ if (lock) { |
lock->Acquire(); |
+ |
+ base::AutoLock pin(own_lock); |
+ CHECK(!owned_by_thread); |
+ owned_by_thread = true; |
+ owning_thread_id = base::PlatformThread::CurrentId(); |
+ } |
} |
// static |
void ProxyLock::Release() { |
base::Lock* lock(PpapiGlobals::Get()->GetProxyLock()); |
- if (lock) |
+ |
+ if (lock) { |
+ base::AutoLock pin(own_lock); |
+ |
+ // Current thread still holds the lock. |
+ CHECK(owned_by_thread); |
+ CHECK_EQ(owning_thread_id, base::PlatformThread::CurrentId()); |
+ |
+ owned_by_thread = false; |
+ owning_thread_id = static_cast<base::PlatformThreadId>(0); |
+ |
lock->Release(); |
+ } |
} |
// static |
void ProxyLock::AssertAcquired() { |
base::Lock* lock(PpapiGlobals::Get()->GetProxyLock()); |
- if (lock) |
+ if (lock) { |
+ base::AutoLock pin(own_lock); |
+ |
+ // Current thread holds the lock. |
+ CHECK(owned_by_thread); |
+ CHECK_EQ(owning_thread_id, base::PlatformThread::CurrentId()); |
+ |
lock->AssertAcquired(); |
+ } |
} |
void CallWhileUnlocked(const base::Closure& closure) { |