mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-24 06:05:01 +02:00
parent
d50c8e1085
commit
b1aa6cc98a
@ -40,7 +40,7 @@ static Timer::Ptr l_ObjectCountTimer;
|
|||||||
* Default constructor for the Object class.
|
* Default constructor for the Object class.
|
||||||
*/
|
*/
|
||||||
Object::Object(void)
|
Object::Object(void)
|
||||||
: m_References(0)
|
: m_References(0), m_Mutex(0)
|
||||||
#ifdef I2_DEBUG
|
#ifdef I2_DEBUG
|
||||||
, m_LockOwner(0)
|
, m_LockOwner(0)
|
||||||
#endif /* I2_DEBUG */
|
#endif /* I2_DEBUG */
|
||||||
@ -50,7 +50,9 @@ Object::Object(void)
|
|||||||
* Destructor for the Object class.
|
* Destructor for the Object class.
|
||||||
*/
|
*/
|
||||||
Object::~Object(void)
|
Object::~Object(void)
|
||||||
{ }
|
{
|
||||||
|
delete reinterpret_cast<boost::recursive_mutex *>(m_Mutex);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a string representation for the object.
|
* Returns a string representation for the object.
|
||||||
|
@ -117,8 +117,8 @@ private:
|
|||||||
Object(const Object& other);
|
Object(const Object& other);
|
||||||
Object& operator=(const Object& rhs);
|
Object& operator=(const Object& rhs);
|
||||||
|
|
||||||
uintptr_t m_References;
|
intptr_t m_References;
|
||||||
mutable boost::recursive_mutex m_Mutex;
|
mutable uintptr_t m_Mutex;
|
||||||
|
|
||||||
#ifdef I2_DEBUG
|
#ifdef I2_DEBUG
|
||||||
# ifndef _WIN32
|
# ifndef _WIN32
|
||||||
@ -153,13 +153,15 @@ inline void intrusive_ptr_add_ref(Object *object)
|
|||||||
|
|
||||||
inline void intrusive_ptr_release(Object *object)
|
inline void intrusive_ptr_release(Object *object)
|
||||||
{
|
{
|
||||||
uintptr_t refs;
|
intptr_t refs;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
refs = InterlockedDecrement(&object->m_References);
|
refs = InterlockedDecrement(&object->m_References);
|
||||||
#else /* _WIN32 */
|
#else /* _WIN32 */
|
||||||
refs = __sync_sub_and_fetch(&object->m_References, 1);
|
refs = __sync_sub_and_fetch(&object->m_References, 1);
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
ASSERT(refs >= 0);
|
||||||
|
|
||||||
if (refs == 0) {
|
if (refs == 0) {
|
||||||
#ifdef I2_DEBUG
|
#ifdef I2_DEBUG
|
||||||
TypeRemoveObject(object);
|
TypeRemoveObject(object);
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
|
|
||||||
#include "base/object.hpp"
|
#include "base/object.hpp"
|
||||||
|
|
||||||
|
#define I2MUTEX_UNLOCKED 0
|
||||||
|
#define I2MUTEX_LOCKED 1
|
||||||
|
|
||||||
namespace icinga
|
namespace icinga
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -53,11 +56,49 @@ public:
|
|||||||
Lock();
|
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)
|
inline void Lock(void)
|
||||||
{
|
{
|
||||||
ASSERT(!m_Locked && m_Object != NULL);
|
ASSERT(!m_Locked && m_Object != NULL);
|
||||||
|
|
||||||
m_Object->m_Mutex.lock();
|
LockMutex(m_Object);
|
||||||
|
|
||||||
m_Locked = true;
|
m_Locked = true;
|
||||||
|
|
||||||
#ifdef I2_DEBUG
|
#ifdef I2_DEBUG
|
||||||
@ -69,6 +110,25 @@ public:
|
|||||||
#endif /* I2_DEBUG */
|
#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)
|
inline void Unlock(void)
|
||||||
{
|
{
|
||||||
#ifdef I2_DEBUG
|
#ifdef I2_DEBUG
|
||||||
@ -82,7 +142,7 @@ public:
|
|||||||
#endif /* I2_DEBUG */
|
#endif /* I2_DEBUG */
|
||||||
|
|
||||||
if (m_Locked) {
|
if (m_Locked) {
|
||||||
m_Object->m_Mutex.unlock();
|
reinterpret_cast<boost::recursive_mutex *>(m_Object->m_Mutex)->unlock();
|
||||||
m_Locked = false;
|
m_Locked = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user