* 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 */
* Destructor for the Object class.
*/
Object::~Object(void)
-{ }
+{
+ delete reinterpret_cast<boost::recursive_mutex *>(m_Mutex);
+}
/**
* Returns a string representation for the object.
Object(const Object& other);
Object& operator=(const Object& rhs);
- uintptr_t m_References;
- mutable boost::recursive_mutex m_Mutex;
+ intptr_t m_References;
+ mutable uintptr_t m_Mutex;
#ifdef I2_DEBUG
# ifndef _WIN32
inline void intrusive_ptr_release(Object *object)
{
- uintptr_t refs;
+ intptr_t refs;
#ifdef _WIN32
refs = InterlockedDecrement(&object->m_References);
#else /* _WIN32 */
refs = __sync_sub_and_fetch(&object->m_References, 1);
#endif /* _WIN32 */
+ ASSERT(refs >= 0);
+
if (refs == 0) {
#ifdef I2_DEBUG
TypeRemoveObject(object);
#include "base/object.hpp"
+#define I2MUTEX_UNLOCKED 0
+#define I2MUTEX_LOCKED 1
+
namespace icinga
{
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
#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
#endif /* I2_DEBUG */
if (m_Locked) {
- m_Object->m_Mutex.unlock();
+ reinterpret_cast<boost::recursive_mutex *>(m_Object->m_Mutex)->unlock();
m_Locked = false;
}
}