]> granicus.if.org Git - icinga2/commitdiff
ObjectLock#Unlock(): don't reset m_Object->m_LockOwner too early 6408/head
authorAlexander A. Klimov <alexander.klimov@icinga.com>
Fri, 22 Jun 2018 12:13:09 +0000 (14:13 +0200)
committerAlexander A. Klimov <alexander.klimov@icinga.com>
Fri, 22 Jun 2018 12:13:09 +0000 (14:13 +0200)
lib/base/object.hpp
lib/base/objectlock.cpp

index a29e4f73b308eb74575cfdb5d56593dec62ba728..7836d2644362902adc0ab221a4de68244a9067bd 100644 (file)
@@ -23,6 +23,7 @@
 #include "base/i2-base.hpp"
 #include "base/debug.hpp"
 #include <boost/smart_ptr/intrusive_ptr.hpp>
+#include <cstddef>
 #include <vector>
 
 using boost::intrusive_ptr;
@@ -212,6 +213,7 @@ private:
 #      else /* _WIN32 */
        mutable DWORD m_LockOwner;
 #      endif /* _WIN32 */
+       mutable size_t m_LockCount = 0;
 #endif /* I2_DEBUG */
 
        friend struct ObjectLock;
index 2abb43fba5404a90cff9590a6e79eb4e2ffe10e3..c3d3f05229de1dd2e82271ccde1730c1c2abb7f0 100644 (file)
@@ -90,11 +90,13 @@ void ObjectLock::Lock()
        m_Locked = true;
 
 #ifdef I2_DEBUG
+       if (++m_Object->m_LockCount == 1u) {
 #      ifdef _WIN32
-       InterlockedExchange(&m_Object->m_LockOwner, GetCurrentThreadId());
+               InterlockedExchange(&m_Object->m_LockOwner, GetCurrentThreadId());
 #      else /* _WIN32 */
-       __sync_lock_test_and_set(&m_Object->m_LockOwner, pthread_self());
+               __sync_lock_test_and_set(&m_Object->m_LockOwner, pthread_self());
 #      endif /* _WIN32 */
+       }
 #endif /* I2_DEBUG */
 }
 
@@ -120,7 +122,7 @@ void ObjectLock::Spin(unsigned int it)
 void ObjectLock::Unlock()
 {
 #ifdef I2_DEBUG
-       if (m_Locked) {
+       if (m_Locked && !--m_Object->m_LockCount) {
 #      ifdef _WIN32
                InterlockedExchange(&m_Object->m_LockOwner, 0);
 #      else /* _WIN32 */