Return-Path: Delivered-To: apmail-incubator-stdcxx-commits-archive@www.apache.org Received: (qmail 54939 invoked from network); 7 Aug 2007 22:24:32 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 7 Aug 2007 22:24:32 -0000 Received: (qmail 36712 invoked by uid 500); 7 Aug 2007 22:24:31 -0000 Delivered-To: apmail-incubator-stdcxx-commits-archive@incubator.apache.org Received: (qmail 36688 invoked by uid 500); 7 Aug 2007 22:24:31 -0000 Mailing-List: contact stdcxx-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: stdcxx-dev@incubator.apache.org Delivered-To: mailing list stdcxx-commits@incubator.apache.org Received: (qmail 36677 invoked by uid 99); 7 Aug 2007 22:24:31 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 07 Aug 2007 15:24:31 -0700 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 07 Aug 2007 22:24:31 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 3E1C81A981A; Tue, 7 Aug 2007 15:24:11 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r563682 - in /incubator/stdcxx/trunk/src: once.cpp once.h Date: Tue, 07 Aug 2007 22:24:11 -0000 To: stdcxx-commits@incubator.apache.org From: sebor@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070807222411.3E1C81A981A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 * 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 +#include + +#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 + + +#ifdef _RWSTD_REENTRANT +# ifdef _RWSTD_OS_SUNOS + +# include +# include + +# 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 + +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 +# else +# include +# 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 + +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