Author: sebor
Date: Tue Aug 7 15:24:10 2007
New Revision: 563682
URL: http://svn.apache.org/viewvc?view=rev&rev=563682
Log:
2007-08-07 Martin Sebor <[EMAIL PROTECTED]>
* once.h: New implementation-private header. Declares __rw_once_t
and __rw_once() for portable, thread-safe one-time initialization.
* once.cpp: New. Defines the above.
Added:
incubator/stdcxx/trunk/src/once.cpp (with props)
incubator/stdcxx/trunk/src/once.h (with props)
Added: incubator/stdcxx/trunk/src/once.cpp
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/src/once.cpp?view=auto&rev=563682
==============================================================================
--- incubator/stdcxx/trunk/src/once.cpp (added)
+++ incubator/stdcxx/trunk/src/once.cpp Tue Aug 7 15:24:10 2007
@@ -0,0 +1,130 @@
+/***************************************************************************
+ *
+ * once.cpp - one time initialization
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the License); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * Copyright 2007 Rogue Wave Software.
+ *
+ **************************************************************************/
+
+#define _RWSTD_LIB_SRC
+#include <rw/_defs.h>
+#include <rw/_mutex.h>
+
+#include "once.h"
+
+
+_RWSTD_NAMESPACE (__rw) {
+
+
+extern "C" {
+
+
+#ifdef _RWSTD_THREAD_ONCE
+
+
+_RWSTD_EXPORT int
+__rw_once (__rw_once_t *once, void (*func)())
+{
+ return _RWSTD_THREAD_ONCE (once, func);
+}
+
+
+#elif defined (_RWSTD_REENTRANT)
+
+
+_RWSTD_EXPORT int
+__rw_once (__rw_once_t *once, void (*func)())
+{
+ _RWSTD_ASSERT (0 != once);
+
+ volatile int &init = once->_C_init;
+
+restart:
+
+ if (init == 0 && 1 == _RWSTD_ATOMIC_PREINCREMENT (init, false)) {
+
+ // entered by the first thread and only the first time around,
+ // unless the initialization function throws
+
+ _TRY {
+ func ();
+ }
+ _CATCH (...) {
+ _RWSTD_ATOMIC_PREDECREMENT (init, false);
+ _RETHROW;
+ }
+
+ init = 1000;
+ }
+ else {
+ // entered by the second and subsequent threads or on the second
+ // and subsequent calls by the first thread after (or duing)
+ // a successful initialization
+
+ for (int loop = 0; init < 1000; ++loop) {
+ if (0 == init) {
+ // first time initialization failed via an exception,
+ // try again
+ goto restart;
+ }
+
+ if (32 < loop) {
+ // avoid wasting too many CPU cycles
+ _RWSTD_THREAD_YIELD ();
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+#else // if !defined (_RWSTD_THREAD_ONCE)
+
+
+_RWSTD_EXPORT int
+__rw_once (__rw_once_t *once, void (*func)())
+{
+ _RWSTD_ASSERT (0 != once);
+
+ // detect uninitialized __rw_once_t objects to help reveal problems
+ // in reentrant code 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 || 1 == once->_C_init);
+
+ if (once->_C_init == -1) {
+
+ func ();
+
+ once->_C_init = 1;
+ }
+
+ return 0;
+}
+
+#endif // _RWSTD_THREAD_ONCE
+
+} // extern "C"
+
+} // namespace __rw
Propchange: incubator/stdcxx/trunk/src/once.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/stdcxx/trunk/src/once.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Added: incubator/stdcxx/trunk/src/once.h
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/src/once.h?view=auto&rev=563682
==============================================================================
--- incubator/stdcxx/trunk/src/once.h (added)
+++ incubator/stdcxx/trunk/src/once.h Tue Aug 7 15:24:10 2007
@@ -0,0 +1,109 @@
+/***************************************************************************
+ *
+ * once.h - one time initialization helpers
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the License); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * Copyright 2007 Rogue Wave Software, Inc.
+ *
+ **************************************************************************/
+
+#include <rw/_defs.h>
+
+
+#ifdef _RWSTD_REENTRANT
+# ifdef _RWSTD_OS_SUNOS
+
+# include <pthread.h>
+# include <thread.h>
+
+# define _RWSTD_THREAD_ONCE(once, func) pthread_once (once, func)
+# define _RWSTD_THREAD_YIELD() thr_yield ()
+
+typedef pthread_once_t __rw_once_t;
+
+# elif defined (_RWSTD_POSIX_THREADS)
+
+# include <pthread.h>
+
+typedef pthread_once_t __rw_once_t;
+
+# define _RWSTD_THREAD_ONCE(once, func) pthread_once (once, func)
+
+# ifndef _RWSTD_NO_SCHED_YIELD
+# define _RWSTD_THREAD_YIELD() sched_yield ()
+# endif // _RWSTD_NO_SCHED_YIELD
+# elif defined (_RWSTD_DCE_THREADS)
+
+# if defined (_RWSTD_NO_DCE_PTHREAD_H)
+# include <pthread.h>
+# else
+# include <dce/pthread.h>
+# endif
+
+typedef pthread_once_t __rw_once_t;
+
+# define _RWSTD_THREAD_ONCE(once, func) pthread_once (once, func)
+# define _RWSTD_THREAD_YIELD() pthread_yield ()
+
+# elif defined (_WIN32)
+
+# include <windows.h>
+
+struct __rw_once_t { int _C_init; };
+
+# define _RWSTD_THREAD_YIELD() Sleep (0)
+# endif // _RWSTD_*_THREADS
+
+
+# ifdef PTHREAD_ONCE_INIT
+# define _RWSTD_ONCE_INIT PTHREAD_ONCE_INIT
+# endif // PTHREAD_ONCE_INIT
+
+#else // if !defined (_RWSTD_REENTRANT)
+
+struct __rw_once_t { int _C_init; };
+
+ // 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
+
+
+#ifndef _RWSTD_THREAD_YIELD
+# define _RWSTD_THREAD_YIELD() (void)0
+#endif // _RWSTD_THREAD_YIELD
+
+
+_RWSTD_NAMESPACE (__rw) {
+
+extern "C" {
+
+_RWSTD_EXPORT int
+__rw_once (__rw_once_t*, void (*)());
+
+} // extern "C"
+
+
+} // namespace __rw
Propchange: incubator/stdcxx/trunk/src/once.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/stdcxx/trunk/src/once.h
------------------------------------------------------------------------------
svn:keywords = Id