summaryrefslogtreecommitdiff
path: root/cpp/include/IceUtil/Shared.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/include/IceUtil/Shared.h')
-rw-r--r--cpp/include/IceUtil/Shared.h97
1 files changed, 46 insertions, 51 deletions
diff --git a/cpp/include/IceUtil/Shared.h b/cpp/include/IceUtil/Shared.h
index aae20dc017a..7666f999dbd 100644
--- a/cpp/include/IceUtil/Shared.h
+++ b/cpp/include/IceUtil/Shared.h
@@ -17,19 +17,10 @@
#include <IceUtil/Config.h>
-//
-// The inline assembler causes problems with shared libraries.
-//
-#if (defined(__ICC) && !defined(_WIN32)) || defined (__sun)
-# define ICE_USE_MUTEX_SHARED
-#endif
-
-#ifdef ICE_USE_MUTEX_SHARED
-# include <IceUtil/Mutex.h>
-#endif
-
-#if !defined(_WIN32) && !defined(ICE_USE_MUTEX_SHARED)
+#if (defined(__linux) || defined(__FreeBSD__)) && defined(__i386) && !defined(__ICC)
+# define ICE_HAS_ATOMIC_FUNCTIONS
+// __ICC: The inline assembler causes problems with shared libraries.
//
// Linux only. Unfortunately, asm/atomic.h builds non-SMP safe code
// with non-SMP kernels. This means that executables compiled with a
@@ -116,6 +107,11 @@ inline int ice_atomic_exchange_add(int i, ice_atomic_t* v)
return tmp + i;
}
+#elif defined(_WIN32)
+// Nothing to include
+#else
+// Use a simple mutex
+# include <IceUtil/Mutex.h>
#endif
//
@@ -203,13 +199,13 @@ public:
private:
-#ifdef ICE_USE_MUTEX_SHARED
- int _ref;
- Mutex _mutex;
-#elif defined(_WIN32)
+#if defined(_WIN32)
LONG _ref;
-#else
+#elif defined(ICE_HAS_ATOMIC_FUNCTIONS)
ice_atomic_t _ref;
+#else
+ int _ref;
+ Mutex _mutex;
#endif
bool _noDelete;
};
@@ -219,7 +215,7 @@ private:
// all of them should be inlined.
//
-#ifdef ICE_USE_MUTEX_SHARED
+#if defined(_WIN32)
inline
Shared::Shared() :
@@ -236,26 +232,17 @@ Shared::~Shared()
inline void
Shared::__incRef()
{
- _mutex.lock();
- assert(_ref >= 0);
- ++_ref;
- _mutex.unlock();
+ assert(InterlockedExchangeAdd(&_ref, 0) >= 0);
+ InterlockedIncrement(&_ref);
}
inline void
Shared::__decRef()
{
- _mutex.lock();
- bool doDelete = false;
- assert(_ref > 0);
- if(--_ref == 0)
+ assert(InterlockedExchangeAdd(&_ref, 0) > 0);
+ if(InterlockedDecrement(&_ref) == 0 && !_noDelete)
{
- doDelete = !_noDelete;
_noDelete = true;
- }
- _mutex.unlock();
- if(doDelete)
- {
delete this;
}
}
@@ -263,27 +250,22 @@ Shared::__decRef()
inline int
Shared::__getRef() const
{
- _mutex.lock();
- int ref = _ref;
- _mutex.unlock();
- return ref;
+ return InterlockedExchangeAdd(const_cast<LONG*>(&_ref), 0);
}
inline void
Shared::__setNoDelete(bool b)
{
- _mutex.lock();
_noDelete = b;
- _mutex.unlock();
}
-#elif defined(_WIN32)
+#elif defined(ICE_HAS_ATOMIC_FUNCTIONS)
inline
Shared::Shared() :
- _ref(0),
_noDelete(false)
{
+ ice_atomic_set(&_ref, 0);
}
inline
@@ -294,15 +276,15 @@ Shared::~Shared()
inline void
Shared::__incRef()
{
- assert(InterlockedExchangeAdd(&_ref, 0) >= 0);
- InterlockedIncrement(&_ref);
+ assert(ice_atomic_exchange_add(0, &_ref) >= 0);
+ ice_atomic_inc(&_ref);
}
inline void
Shared::__decRef()
{
- assert(InterlockedExchangeAdd(&_ref, 0) > 0);
- if(InterlockedDecrement(&_ref) == 0 && !_noDelete)
+ assert(ice_atomic_exchange_add(0, &_ref) > 0);
+ if(ice_atomic_dec_and_test(&_ref) && !_noDelete)
{
_noDelete = true;
delete this;
@@ -312,7 +294,7 @@ Shared::__decRef()
inline int
Shared::__getRef() const
{
- return InterlockedExchangeAdd(const_cast<LONG*>(&_ref), 0);
+ return ice_atomic_exchange_add(0, const_cast<ice_atomic_t*>(&_ref));
}
inline void
@@ -325,9 +307,9 @@ Shared::__setNoDelete(bool b)
inline
Shared::Shared() :
+ _ref(0),
_noDelete(false)
{
- ice_atomic_set(&_ref, 0);
}
inline
@@ -338,17 +320,26 @@ Shared::~Shared()
inline void
Shared::__incRef()
{
- assert(ice_atomic_exchange_add(0, &_ref) >= 0);
- ice_atomic_inc(&_ref);
+ _mutex.lock();
+ assert(_ref >= 0);
+ ++_ref;
+ _mutex.unlock();
}
inline void
Shared::__decRef()
{
- assert(ice_atomic_exchange_add(0, &_ref) > 0);
- if(ice_atomic_dec_and_test(&_ref) && !_noDelete)
+ _mutex.lock();
+ bool doDelete = false;
+ assert(_ref > 0);
+ if(--_ref == 0)
{
+ doDelete = !_noDelete;
_noDelete = true;
+ }
+ _mutex.unlock();
+ if(doDelete)
+ {
delete this;
}
}
@@ -356,17 +347,21 @@ Shared::__decRef()
inline int
Shared::__getRef() const
{
- return ice_atomic_exchange_add(0, const_cast<ice_atomic_t*>(&_ref));
+ _mutex.lock();
+ int ref = _ref;
+ _mutex.unlock();
+ return ref;
}
inline void
Shared::__setNoDelete(bool b)
{
+ _mutex.lock();
_noDelete = b;
+ _mutex.unlock();
}
#endif
}
-
#endif