stdcxx-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From se...@apache.org
Subject svn commit: r567159 - in /incubator/stdcxx/trunk/src: once.cpp once.h
Date Fri, 17 Aug 2007 22:02:53 GMT
Author: sebor
Date: Fri Aug 17 15:02:52 2007
New Revision: 567159

URL: http://svn.apache.org/viewvc?view=rev&rev=567159
Log:
2007-08-17  Martin Sebor  <sebor@roguewave.com>

	* once.h (_RWSTD_ONCE_INIT): Defined to PTHREAD_ONCE_INIT.
	[_RWSTD_POSIX_THREADS, _RWSTD_NO_PTHREAD_ONCE] (__rw_once_t,
	_RWSTD_ONCE_INIT): Defined in terms of pthread_mutex_t and
	PTHREAD_MUTEX_INITIALIZER, respectively.
	* once.cpp [_RWSTD_POSIX_THREADS, _RWSTD_NO_PTHREAD_ONCE]
	(__rw_once_t): Defined in terms of pthread_mutex_lock()
	and pthread_mutex_unlock().
	(__rw_once_t): Consistently asserted both preconditions.

Modified:
    incubator/stdcxx/trunk/src/once.cpp
    incubator/stdcxx/trunk/src/once.h

Modified: incubator/stdcxx/trunk/src/once.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/src/once.cpp?view=diff&rev=567159&r1=567158&r2=567159
==============================================================================
--- incubator/stdcxx/trunk/src/once.cpp (original)
+++ incubator/stdcxx/trunk/src/once.cpp Fri Aug 17 15:02:52 2007
@@ -42,20 +42,79 @@
 #ifdef _RWSTD_THREAD_ONCE
 
 
+// implementation that relies on the system one-time initialization
+// mechanism such as pthread_once()
 _RWSTD_EXPORT int
 __rw_once (__rw_once_t *once, void (*func)())
 {
+    _RWSTD_ASSERT (0 != once && 0 != func);
+
     return _RWSTD_THREAD_ONCE (once, func);
 }
 
 
+#elif defined (_RWSTD_NO_ATOMIC_OPS) && defined (_RWSTD_POSIX_THREADS)
+
+
+// implementation that uses a mutex instead of pthread_once() or atomic
+// operations
+_RWSTD_EXPORT int
+__rw_once (__rw_once_t *once, void (*func)())
+{
+    _RWSTD_ASSERT (0 != once && 0 != func);
+
+    // _C_init may take on one of two valid values:
+    // -1 for a properly initialized __rw_once_t object whose initializer
+    //    hasn't run yet
+    // +1 for ar __rw_once_t object whose initializer has already been
+    //    executed
+    // Any other value (including 0, for __rw_once_t objects that haven't
+    // been properly initialized) is invalid.
+
+    if (-1 == once->_C_init) {
+
+        const int result = pthread_mutex_lock (&once->_C_mutex);
+        if (result)
+            return result;
+
+        if (-1 == once->_C_init) {
+
+            // entered by the first thread and only the first time around,
+            // unless the initialization function throws
+
+            _TRY {
+                func ();
+            }
+            _CATCH (...) {
+                pthread_mutex_unlock (&once->_C_mutex);
+                _RETHROW;
+            }
+
+            once->_C_init += 2;
+        }
+
+        pthread_mutex_unlock (&once->_C_mutex);
+    }
+
+    // verify that initialization took place exactly once and help detect
+    // uninitialized __rw_once_t objects to help catch problems on platforms
+    // such as HP-UX that require pthread_once_t objects to be explicitly
+    // initialized (i.e., not all bits tobe zeroed out) in order for
+    // pthread_once() to succeed
+    _RWSTD_ASSERT (1 == once->_C_init);
+
+    return 0;
+}
+
+
 #elif defined (_RWSTD_REENTRANT)
 
 
+// implementation that uses atomic operations
 _RWSTD_EXPORT int
 __rw_once (__rw_once_t *once, void (*func)())
 {
-    _RWSTD_ASSERT (0 != once);
+    _RWSTD_ASSERT (0 != once && 0 != func);
 
     volatile int &init = once->_C_init;
 
@@ -102,10 +161,11 @@
 #else   // if !defined (_RWSTD_THREAD_ONCE)
 
 
+// thread-unsafe implementation
 _RWSTD_EXPORT int
 __rw_once (__rw_once_t *once, void (*func)())
 {
-    _RWSTD_ASSERT (0 != once);
+    _RWSTD_ASSERT (0 != once && 0 != func);
 
     // detect uninitialized __rw_once_t objects to help reveal problems
     // in reentrant code on platforms such as HP-UX that require

Modified: incubator/stdcxx/trunk/src/once.h
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/src/once.h?view=diff&rev=567159&r1=567158&r2=567159
==============================================================================
--- incubator/stdcxx/trunk/src/once.h (original)
+++ incubator/stdcxx/trunk/src/once.h Fri Aug 17 15:02:52 2007
@@ -37,6 +37,7 @@
 
 #    define _RWSTD_THREAD_ONCE(once, func)   pthread_once (once, func)
 #    define _RWSTD_THREAD_YIELD()            thr_yield ()
+#    define _RWSTD_ONCE_INIT                 PTHREAD_ONCE_INIT
 
 typedef pthread_once_t __rw_once_t;
 
@@ -44,9 +45,27 @@
 
 #    include <pthread.h>
 
+#    ifndef _RWSTD_NO_PTHREAD_ONCE
+
 typedef pthread_once_t __rw_once_t;
 
-#    define _RWSTD_THREAD_ONCE(once, func)   pthread_once (once, func)
+#      define _RWSTD_THREAD_ONCE(once, func)   pthread_once (once, func)
+#      define _RWSTD_ONCE_INIT                 PTHREAD_ONCE_INIT
+
+#    else   // if defined (_RWSTD_NO_PTHREAD_ONCE)
+
+_RWSTD_NAMESPACE (__rw) {
+
+struct __rw_once_t {
+    pthread_mutex_t _C_mutex;
+    int             _C_init;
+};
+
+}   // namespace __rw
+
+#      define _RWSTD_ONCE_INIT   { PTHREAD_MUTEX_INITIALIZER, -1 }
+
+#    endif   // _RWSTD_NO_PTHREAD_ONCE
 
 #    ifndef _RWSTD_NO_SCHED_YIELD
 #      define _RWSTD_THREAD_YIELD()   sched_yield ()
@@ -59,35 +78,48 @@
 #      include <dce/pthread.h>
 #    endif
 
+_RWSTD_NAMESPACE (__rw) {
+
 typedef pthread_once_t __rw_once_t;
 
+}   // namespace __rw
+
 #    define _RWSTD_THREAD_ONCE(once, func)   pthread_once (once, func)
 #    define _RWSTD_THREAD_YIELD()            pthread_yield ()
+#    define _RWSTD_ONCE_INIT                 PTHREAD_ONCE_INIT
 
 #  elif defined (_WIN32)
 
 #    include <windows.h>
 
+_RWSTD_NAMESPACE (__rw) {
+
 struct __rw_once_t { int _C_init; };
 
+}   // namespace __rw
+
 #    define _RWSTD_THREAD_YIELD()   Sleep (0)
-#  endif   // _RWSTD_*_THREADS
+#  else   // !_WIN32
+
+_RWSTD_NAMESPACE (__rw) {
 
+struct __rw_once_t { int _C_init; };
 
-#  ifdef PTHREAD_ONCE_INIT
-#    define _RWSTD_ONCE_INIT   PTHREAD_ONCE_INIT
-#  endif   // PTHREAD_ONCE_INIT
+}   // namespace __rw
 
+#    define _RWSTD_ONCE_INIT   { 0 }
+#  endif   // _WIN32
 #else   // if !defined (_RWSTD_REENTRANT)
 
+_RWSTD_NAMESPACE (__rw) {
+
 struct __rw_once_t { int _C_init; };
 
+}   // namespace __rw
+
    // defined to a non-zero value to help detect uninitialized
    // __rw_once_t objects
 #  define _RWSTD_ONCE_INIT   { -1 }
-
-   // not defined
-#  undef  _RWSTD_THREAD_ONCE
 #endif   // _RWSTD_REENTRANT
 
 



Mime
View raw message