]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/atomic.h
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / include / wx / atomic.h
index 9918f63ecc61afc83a432bcb8bc6c5d5bb539a6a..1439d29484d78ecd86a6434f4569b7f9e8b4afe2 100644 (file)
@@ -3,7 +3,6 @@
 // Purpose:     functions to manipulate atomically integers and pointers
 // Author:      Armel Asselin
 // Created:     12/13/2006
 // Purpose:     functions to manipulate atomically integers and pointers
 // Author:      Armel Asselin
 // Created:     12/13/2006
-// RCS-ID:      $Id$
 // Copyright:   (c) Armel Asselin
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 // Copyright:   (c) Armel Asselin
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #if wxUSE_THREADS
 
 
 #if wxUSE_THREADS
 
-#if defined(__WXMSW__)
+#if defined(HAVE_GCC_ATOMIC_BUILTINS)
 
 
-// include standard Windows headers
-#include "wx/msw/wrapwin.h"
+// NB: we intentionally don't use Linux's asm/atomic.h header, because it's
+//     an internal kernel header that doesn't always work in userspace:
+//     http://bugs.mysql.com/bug.php?id=28456
+//     http://golubenco.org/blog/atomic-operations/
 
 inline void wxAtomicInc (wxUint32 &value)
 {
 
 inline void wxAtomicInc (wxUint32 &value)
 {
-    InterlockedIncrement ((LONG*)&value);
+    __sync_fetch_and_add(&value, 1);
 }
 
 inline wxUint32 wxAtomicDec (wxUint32 &value)
 {
 }
 
 inline wxUint32 wxAtomicDec (wxUint32 &value)
 {
-    return InterlockedDecrement ((LONG*)&value);
+    return __sync_sub_and_fetch(&value, 1);
 }
 
 }
 
-#elif defined(__WXMAC__) || defined(__DARWIN__)
 
 
-#include "libkern/OSAtomic.h"
+#elif defined(__WINDOWS__)
+
+// include standard Windows headers
+#include "wx/msw/wrapwin.h"
+
 inline void wxAtomicInc (wxUint32 &value)
 {
 inline void wxAtomicInc (wxUint32 &value)
 {
-    OSAtomicIncrement32 ((int32_t*)&value);
+    InterlockedIncrement ((LONG*)&value);
 }
 
 inline wxUint32 wxAtomicDec (wxUint32 &value)
 {
 }
 
 inline wxUint32 wxAtomicDec (wxUint32 &value)
 {
-    return OSAtomicDecrement32 ((int32_t*)&value);
+    return InterlockedDecrement ((LONG*)&value);
 }
 
 }
 
-#elif defined(__LINUX__)
-
-#include <asm/atomic.h>
+#elif defined(__WXMAC__) || defined(__DARWIN__)
 
 
+#include "libkern/OSAtomic.h"
 inline void wxAtomicInc (wxUint32 &value)
 {
 inline void wxAtomicInc (wxUint32 &value)
 {
-    atomic_inc ((atomic_t*)&value);
+    OSAtomicIncrement32 ((int32_t*)&value);
 }
 
 inline wxUint32 wxAtomicDec (wxUint32 &value)
 {
 }
 
 inline wxUint32 wxAtomicDec (wxUint32 &value)
 {
-    return atomic_dec_and_test ((atomic_t*)&value) ? 0 : 1;
+    return OSAtomicDecrement32 ((int32_t*)&value);
 }
 
 #elif defined (__SOLARIS__)
 }
 
 #elif defined (__SOLARIS__)
@@ -84,7 +87,7 @@ inline wxUint32 wxAtomicDec (wxUint32 &value)
 #else // unknown platform
 
 // it will result in inclusion if the generic implementation code a bit later in this page
 #else // unknown platform
 
 // it will result in inclusion if the generic implementation code a bit later in this page
-#define wxHAS_GENERIC_ATOMIC_OPS 1
+#define wxNEEDS_GENERIC_ATOMIC_OPS
 
 #endif // unknown platform
 
 
 #endif // unknown platform
 
@@ -101,23 +104,21 @@ inline wxUint32 wxAtomicDec (wxUint32 &value) { return --value; }
 //  behaviour
 // ----------------------------------------------------------------------------
 
 //  behaviour
 // ----------------------------------------------------------------------------
 
-#if !defined(wxHAS_GENERIC_ATOMIC_OPS)
-#define wxHAS_GENERIC_ATOMIC_OPS 0
-#endif
+#ifdef wxNEEDS_GENERIC_ATOMIC_OPS
 
 
-#if wxHAS_GENERIC_ATOMIC_OPS
 #include "wx/thread.h" // for wxCriticalSection
 
 class wxAtomicInt32
 {
 public:
 #include "wx/thread.h" // for wxCriticalSection
 
 class wxAtomicInt32
 {
 public:
-    wxAtomicInt() { } // non initialized for consistency with basic int type
-    wxAtomicInt(wxInt32 v) : m_value(v) { }
+    wxAtomicInt32() { } // non initialized for consistency with basic int type
+    wxAtomicInt32(wxInt32 v) : m_value(v) { }
+    wxAtomicInt32(const wxAtomicInt32& a) : m_value(a.m_value) {}
 
     operator wxInt32() const { return m_value; }
 
     operator wxInt32() const { return m_value; }
-    operator wxInt32&() { return m_value; }
+    operator volatile wxInt32&() { return m_value; }
 
 
-    wxAtomicInt& operator=(wxInt32 v) { m_value = v; return *this; }
+    wxAtomicInt32& operator=(wxInt32 v) { m_value = v; return *this; }
 
     void Inc()
     {
 
     void Inc()
     {
@@ -136,17 +137,19 @@ private:
     wxCriticalSection m_locker;
 };
 
     wxCriticalSection m_locker;
 };
 
-inline void wxAtomicInc(wxAtomicInt &value) { value.Inc(); }
-inline wxInt32 wxAtomicDec(wxAtomicInt &value) { return value.Dec(); }
+inline void wxAtomicInc(wxAtomicInt32 &value) { value.Inc(); }
+inline wxInt32 wxAtomicDec(wxAtomicInt32 &value) { return value.Dec(); }
+
+#else // !wxNEEDS_GENERIC_ATOMIC_OPS
 
 
-#else // !wxHAS_GENERIC_ATOMIC_OPS
+#define wxHAS_ATOMIC_OPS
 
 inline void wxAtomicInc(wxInt32 &value) { wxAtomicInc((wxUint32&)value); }
 inline wxInt32 wxAtomicDec(wxInt32 &value) { return wxAtomicDec((wxUint32&)value); }
 
 typedef wxInt32 wxAtomicInt32;
 
 
 inline void wxAtomicInc(wxInt32 &value) { wxAtomicInc((wxUint32&)value); }
 inline wxInt32 wxAtomicDec(wxInt32 &value) { return wxAtomicDec((wxUint32&)value); }
 
 typedef wxInt32 wxAtomicInt32;
 
-#endif // wxHAS_GENERIC_ATOMIC_OPS
+#endif // wxNEEDS_GENERIC_ATOMIC_OPS
 
 // all the native implementations use 32 bits currently
 // for a 64 bits implementation we could use (a future) wxAtomicInt64 as
 
 // all the native implementations use 32 bits currently
 // for a 64 bits implementation we could use (a future) wxAtomicInt64 as