mirror of https://github.com/Icinga/icinga2.git
parent
abfacd9e56
commit
badeea7604
|
@ -40,7 +40,7 @@ static Timer::Ptr l_ObjectCountTimer;
|
|||
* Default constructor for the Object class.
|
||||
*/
|
||||
Object::Object(void)
|
||||
: m_References(0)
|
||||
: m_References(0), m_Mutex(0)
|
||||
#ifdef I2_DEBUG
|
||||
, m_LockOwner(0)
|
||||
#endif /* I2_DEBUG */
|
||||
|
@ -50,7 +50,9 @@ Object::Object(void)
|
|||
* Destructor for the Object class.
|
||||
*/
|
||||
Object::~Object(void)
|
||||
{ }
|
||||
{
|
||||
delete reinterpret_cast<boost::recursive_mutex *>(m_Mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation for the object.
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
|
||||
#include "base/object.hpp"
|
||||
|
||||
#define I2MUTEX_UNLOCKED 0
|
||||
#define I2MUTEX_LOCKED 1
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
|
@ -53,11 +56,49 @@ public:
|
|||
Lock();
|
||||
}
|
||||
|
||||
inline static void LockMutex(const Object *object)
|
||||
{
|
||||
unsigned int it = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef _WIN64
|
||||
while (InterlockedCompareExchange64(&object->m_Mutex, I2MUTEX_LOCKED, I2MUTEX_UNLOCKED) != I2MUTEX_UNLOCKED) {
|
||||
# else /* _WIN64 */
|
||||
while (InterlockedCompareExchange(&object->m_Mutex, I2MUTEX_LOCKED, I2MUTEX_UNLOCKED) != I2MUTEX_UNLOCKED) {
|
||||
# endif /* _WIN64 */
|
||||
#else /* _WIN32 */
|
||||
while (!__sync_bool_compare_and_swap(&object->m_Mutex, I2MUTEX_UNLOCKED, I2MUTEX_LOCKED)) {
|
||||
#endif /* _WIN32 */
|
||||
if (object->m_Mutex > I2MUTEX_LOCKED) {
|
||||
boost::recursive_mutex *mtx = reinterpret_cast<boost::recursive_mutex *>(object->m_Mutex);
|
||||
mtx->lock();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Spin(it);
|
||||
it++;
|
||||
}
|
||||
|
||||
boost::recursive_mutex *mtx = new boost::recursive_mutex();
|
||||
mtx->lock();
|
||||
#ifdef _WIN32
|
||||
# ifdef _WIN64
|
||||
InterlockedCompareExchange64(&object->m_Mutex, reinterpret_cast<LONGLONG>(mtx), I2MUTEX_LOCKED);
|
||||
# else /* _WIN64 */
|
||||
InterlockedCompareExchange(&object->m_Mutex, reinterpret_cast<LONG>(mtx), I2MUTEX_LOCKED);
|
||||
# endif /* _WIN64 */
|
||||
#else /* _WIN32 */
|
||||
__sync_bool_compare_and_swap(&object->m_Mutex, I2MUTEX_LOCKED, reinterpret_cast<uintptr_t>(mtx));
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
inline void Lock(void)
|
||||
{
|
||||
ASSERT(!m_Locked && m_Object != NULL);
|
||||
|
||||
m_Object->m_Mutex.lock();
|
||||
LockMutex(m_Object);
|
||||
|
||||
m_Locked = true;
|
||||
|
||||
#ifdef I2_DEBUG
|
||||
|
@ -69,6 +110,25 @@ public:
|
|||
#endif /* I2_DEBUG */
|
||||
}
|
||||
|
||||
inline static void Spin(unsigned int it)
|
||||
{
|
||||
if (it < 8) {
|
||||
/* Do nothing. */
|
||||
}
|
||||
#ifdef SPIN_PAUSE
|
||||
else if (it < 16) {
|
||||
SPIN_PAUSE();
|
||||
}
|
||||
#endif /* SPIN_PAUSE */
|
||||
else {
|
||||
#ifdef _WIN32
|
||||
Sleep(0);
|
||||
#else /* _WIN32 */
|
||||
sched_yield();
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
}
|
||||
|
||||
inline void Unlock(void)
|
||||
{
|
||||
#ifdef I2_DEBUG
|
||||
|
@ -82,7 +142,7 @@ public:
|
|||
#endif /* I2_DEBUG */
|
||||
|
||||
if (m_Locked) {
|
||||
m_Object->m_Mutex.unlock();
|
||||
reinterpret_cast<boost::recursive_mutex *>(m_Object->m_Mutex)->unlock();
|
||||
m_Locked = false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue