|
Boost-Commit : |
From: anthony_at_[hidden]
Date: 2007-10-05 05:52:11
Author: anthonyw
Date: 2007-10-05 05:52:08 EDT (Fri, 05 Oct 2007)
New Revision: 39695
URL: http://svn.boost.org/trac/boost/changeset/39695
Log:
header-only once for POSIX
Removed:
branches/thread_rewrite/boost/libs/thread/src/pthread/once.cpp
Text files modified:
branches/thread_rewrite/boost/boost/thread/condition.hpp | 59 +++++++++++++++++++++++++----
branches/thread_rewrite/boost/boost/thread/pthread/once.hpp | 79 ++++++++++++++++++++++++++++++++-------
branches/thread_rewrite/boost/boost/thread/win32/interlocked_read.hpp | 14 ++++--
branches/thread_rewrite/boost/boost/thread/win32/once.hpp | 30 +++++----------
branches/thread_rewrite/boost/boost/thread/win32/thread_primitives.hpp | 77 +++++++++++++++++++++++++++++++++++++-
branches/thread_rewrite/boost/libs/thread/build/Jamfile.v2 | 2 -
branches/thread_rewrite/boost/libs/thread/test/test_condition.cpp | 2
branches/thread_rewrite/boost/libs/thread/test/test_once.cpp | 4 +-
8 files changed, 211 insertions(+), 56 deletions(-)
Modified: branches/thread_rewrite/boost/boost/thread/condition.hpp
==============================================================================
--- branches/thread_rewrite/boost/boost/thread/condition.hpp (original)
+++ branches/thread_rewrite/boost/boost/thread/condition.hpp 2007-10-05 05:52:08 EDT (Fri, 05 Oct 2007)
@@ -1,16 +1,57 @@
-// Copyright 2006 Roland Schwarz.
+#ifndef BOOST_THREAD_CONDITION_HPP
+#define BOOST_THREAD_CONDITION_HPP
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-//
-// This work is a reimplementation along the design and ideas
-// of William E. Kempf.
-
-#ifndef BOOST_THREAD_RS06040706_HPP
-#define BOOST_THREAD_RS06040706_HPP
+// (C) Copyright 2007 Anthony Williams
#include <boost/thread/detail/platform.hpp>
-#include BOOST_THREAD_PLATFORM(condition.hpp)
+#include BOOST_THREAD_PLATFORM(condition_state.hpp)
+
+namespace boost
+{
+ template <class Mutex>
+ class condition:
+ private boost::detail::thread::condition_state<Mutex>
+ {
+ public:
+ typedef Mutex mutex_type;
+
+ condition();
+ explicit condition(mutex_type& m);
+ ~condition();
+
+#ifdef BOOST_HAS_DELETED_FUNCTIONS
+ condition(const condition&) = delete;
+ condition& operator=(const condition&) = delete;
+#endif
+
+ void notify_one();
+ void notify_all();
+
+ template <class Lock>
+ void wait(Lock& lock);
+
+ template <class Lock, class Predicate>
+ void wait(Lock& lock, Predicate pred);
+
+ template <class Lock>
+ bool timed_wait(Lock& lock, const utc_time& abs_time);
+
+ template <class Lock, class Predicate>
+ bool timed_wait(Lock& lock, const utc_time& abs_time, Predicate pred);
+
+#ifndef BOOST_HAS_DELETED_FUNCTIONS
+ private:
+ explicit condition(condition&);
+ condition& operator=(condition&);
+#endif
+
+ };
+}
+
+#include BOOST_THREAD_PLATFORM(condition_impl.hpp)
+#include <boost/thread/utc_time.hpp>
-#endif // BOOST_THREAD_RS06040706_HPP
+#endif
Modified: branches/thread_rewrite/boost/boost/thread/pthread/once.hpp
==============================================================================
--- branches/thread_rewrite/boost/boost/thread/pthread/once.hpp (original)
+++ branches/thread_rewrite/boost/boost/thread/pthread/once.hpp 2007-10-05 05:52:08 EDT (Fri, 05 Oct 2007)
@@ -1,25 +1,74 @@
-// Copyright (C) 2001-2003 William E. Kempf
-// Copyright (C) 2006 Roland Schwarz
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// This work is a reimplementation along the design and ideas
-// of William E. Kempf.
+#ifndef BOOST_THREAD_PTHREAD_ONCE_HPP
+#define BOOST_THREAD_PTHREAD_ONCE_HPP
-#ifndef BOOST_ONCE_RS06092301_HPP
-#define BOOST_ONCE_RS06092301_HPP
+// once.hpp
+//
+// (C) Copyright 2007 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/pthread/config.hpp>
#include <pthread.h>
+#include <boost/assert.hpp>
namespace boost {
-typedef pthread_once_t once_flag;
-#define BOOST_ONCE_INIT PTHREAD_ONCE_INIT
-
-void BOOST_THREAD_DECL call_once(void (*func)(), once_flag& flag);
+ struct once_flag
+ {
+ pthread_mutex_t mutex;
+ unsigned flag;
+ };
+
+#define BOOST_ONCE_INIT {PTHREAD_MUTEX_INITIALIZER,0}
+
+ namespace detail
+ {
+ struct pthread_mutex_scoped_lock
+ {
+ pthread_mutex_t * mutex;
+
+ explicit pthread_mutex_scoped_lock(pthread_mutex_t* mutex_):
+ mutex(mutex_)
+ {
+ int const res=pthread_mutex_lock(mutex);
+ BOOST_ASSERT(!res);
+ }
+ ~pthread_mutex_scoped_lock()
+ {
+ int const res=pthread_mutex_unlock(mutex);
+ BOOST_ASSERT(!res);
+ }
+ };
+ }
+
+ template<typename Function>
+ void call_once(once_flag& flag,Function f)
+ {
+ long const function_complete_flag_value=0xc15730e2;
+
+#ifdef BOOST_PTHREAD_HAS_ATOMICS
+ if(::boost::detail::interlocked_read_acquire(&flag.flag)!=function_complete_flag_value)
+ {
+#endif
+ detail::pthread_mutex_scoped_lock const lock(&flag.mutex);
+ if(flag.flag!=function_complete_flag_value)
+ {
+ f();
+#ifdef BOOST_PTHREAD_HAS_ATOMICS
+ ::boost::detail::interlocked_write_release(&flag.flag,function_complete_flag_value);
+#else
+ flag.flag=function_complete_flag_value;
+#endif
+ }
+#ifdef BOOST_PTHREAD_HAS_ATOMICS
+ }
+#endif
+ }
+
-} // namespace boost
+}
-#endif // BOOST_ONCE_RS06092301_HPP
+#endif
Modified: branches/thread_rewrite/boost/boost/thread/win32/interlocked_read.hpp
==============================================================================
--- branches/thread_rewrite/boost/boost/thread/win32/interlocked_read.hpp (original)
+++ branches/thread_rewrite/boost/boost/thread/win32/interlocked_read.hpp 2007-10-05 05:52:08 EDT (Fri, 05 Oct 2007)
@@ -3,7 +3,7 @@
// interlocked_read_win32.hpp
//
-// (C) Copyright 2005-6 Anthony Williams
+// (C) Copyright 2005-7 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -15,13 +15,17 @@
{
namespace detail
{
- inline long interlocked_read(long* x)
+ inline long interlocked_read_acquire(long volatile* x)
{
- return BOOST_INTERLOCKED_EXCHANGE_ADD(x,0);
+ long const res=*x;
+ _ReadWriteBarrier();
+ return res;
}
- inline void* interlocked_read(void** x)
+ inline void* interlocked_read_acquire(void* volatile* x)
{
- return BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(x,0,0);
+ void* const res=*x;
+ _ReadWriteBarrier();
+ return res;
}
}
}
Modified: branches/thread_rewrite/boost/boost/thread/win32/once.hpp
==============================================================================
--- branches/thread_rewrite/boost/boost/thread/win32/once.hpp (original)
+++ branches/thread_rewrite/boost/boost/thread/win32/once.hpp 2007-10-05 05:52:08 EDT (Fri, 05 Oct 2007)
@@ -3,7 +3,7 @@
// once.hpp
//
-// (C) Copyright 2005-6 Anthony Williams
+// (C) Copyright 2005-7 Anthony Williams
// (C) Copyright 2005 John Maddock
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -35,29 +35,19 @@
namespace detail
{
- struct handle_closer
- {
- void* const handle_to_close;
- handle_closer(void* handle_to_close_):
- handle_to_close(handle_to_close_)
- {}
- ~handle_closer()
- {
- win32::CloseHandle(handle_to_close);
- }
- };
-
struct win32_mutex_scoped_lock
{
void* const mutex_handle;
- win32_mutex_scoped_lock(void* mutex_handle_):
+ explicit win32_mutex_scoped_lock(void* mutex_handle_):
mutex_handle(mutex_handle_)
{
- win32::WaitForSingleObject(mutex_handle,win32::infinite);
+ unsigned long const res=win32::WaitForSingleObject(mutex_handle,win32::infinite);
+ BOOST_ASSERT(!res);
}
~win32_mutex_scoped_lock()
{
- win32::ReleaseMutex(mutex_handle);
+ bool const success=win32::ReleaseMutex(mutex_handle)!=0;
+ BOOST_ASSERT(success);
}
};
@@ -98,21 +88,21 @@
template<typename Function>
- void call_once(Function f,once_flag& flag)
+ void call_once(once_flag& flag,Function f)
{
// Try for a quick win: if the proceedure has already been called
// just skip through:
long const function_complete_flag_value=0xc15730e2;
- if(::boost::detail::interlocked_read(&flag)!=function_complete_flag_value)
+ if(::boost::detail::interlocked_read_acquire(&flag)!=function_complete_flag_value)
{
char mutex_name[::boost::detail::once_mutex_name_length];
void* const mutex_handle(::boost::detail::create_once_mutex(mutex_name,&flag));
BOOST_ASSERT(mutex_handle);
- detail::handle_closer const closer(mutex_handle);
+ detail::win32::handle_manager const closer(mutex_handle);
detail::win32_mutex_scoped_lock const lock(mutex_handle);
- if(::boost::detail::interlocked_read(&flag)!=function_complete_flag_value)
+ if(flag!=function_complete_flag_value)
{
f();
BOOST_INTERLOCKED_EXCHANGE(&flag,function_complete_flag_value);
Modified: branches/thread_rewrite/boost/boost/thread/win32/thread_primitives.hpp
==============================================================================
--- branches/thread_rewrite/boost/boost/thread/win32/thread_primitives.hpp (original)
+++ branches/thread_rewrite/boost/boost/thread/win32/thread_primitives.hpp 2007-10-05 05:52:08 EDT (Fri, 05 Oct 2007)
@@ -10,6 +10,8 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
+#include <boost/assert.hpp>
+#include <boost/thread/exceptions.hpp>
#if defined( BOOST_USE_WINDOWS_H )
# include <windows.h>
@@ -110,13 +112,84 @@
inline handle create_anonymous_event(event_type type,initial_event_state state)
{
- return CreateEventA(0,type,state,0);
+ handle const res=CreateEventA(0,type,state,0);
+ return res?res:throw thread_resource_error();
}
inline handle create_anonymous_semaphore(long initial_count,long max_count)
{
- return CreateSemaphoreA(NULL,initial_count,max_count,NULL);
+ handle const res=CreateSemaphoreA(NULL,initial_count,max_count,NULL);
+ return res?res:throw thread_resource_error();
}
+
+ inline handle duplicate_handle(handle source)
+ {
+ handle const current_process=GetCurrentProcess();
+ long const same_access_flag=2;
+ handle new_handle=0;
+ bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
+ return success?new_handle:throw thread_resource_error();
+ }
+
+ inline void release_semaphore(handle semaphore,long count)
+ {
+ bool const success=ReleaseSemaphore(semaphore,count,0);
+ BOOST_ASSERT(success);
+ }
+
+ class handle_manager
+ {
+ private:
+ handle handle_to_manage;
+ handle_manager(handle_manager&);
+ handle_manager& operator=(handle_manager&);
+
+ void cleanup()
+ {
+ if(handle_to_manage)
+ {
+ unsigned long result=CloseHandle(handle_to_manage);
+ BOOST_ASSERT(result);
+ }
+ }
+
+ public:
+ explicit handle_manager(handle handle_to_manage_):
+ handle_to_manage(handle_to_manage_)
+ {}
+ handle_manager():
+ handle_to_manage(0)
+ {}
+
+ handle_manager& operator=(handle new_handle)
+ {
+ cleanup();
+ handle_to_manage=new_handle;
+ }
+
+ operator handle() const
+ {
+ return handle_to_manage;
+ }
+
+ handle release()
+ {
+ handle const res=handle_to_manage;
+ handle_to_manage=0;
+ return res;
+ }
+
+ bool operator!() const
+ {
+ return !handle_to_manage;
+ }
+
+ ~handle_manager()
+ {
+ cleanup();
+ }
+ };
+
}
}
}
Modified: branches/thread_rewrite/boost/libs/thread/build/Jamfile.v2
==============================================================================
--- branches/thread_rewrite/boost/libs/thread/build/Jamfile.v2 (original)
+++ branches/thread_rewrite/boost/libs/thread/build/Jamfile.v2 2007-10-05 05:52:08 EDT (Fri, 05 Oct 2007)
@@ -25,7 +25,6 @@
pthread/condition.cpp
pthread/exceptions.cpp
pthread/xtime.cpp
- pthread/once.cpp
pthread/tss.cpp
: ## requirements ##
<define>BOOST_THREAD_POSIX
@@ -41,7 +40,6 @@
pthread/condition.cpp
pthread/exceptions.cpp
pthread/xtime.cpp
- pthread/once.cpp
pthread/tss.cpp
: ## requirements ##
<define>BOOST_THREAD_POSIX
Deleted: branches/thread_rewrite/boost/libs/thread/src/pthread/once.cpp
==============================================================================
--- branches/thread_rewrite/boost/libs/thread/src/pthread/once.cpp 2007-10-05 05:52:08 EDT (Fri, 05 Oct 2007)
+++ (empty file)
@@ -1,45 +0,0 @@
-// Copyright (C) 2001-2003 William E. Kempf
-// Copyright (C) 2006 Roland Schwarz
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// This work is a reimplementation along the design and ideas
-// of William E. Kempf.
-
-#include <boost/thread/pthread/config.hpp>
-
-#include <boost/thread/pthread/once.hpp>
-
-namespace {
-pthread_key_t key;
-pthread_once_t once = PTHREAD_ONCE_INIT;
-
-typedef void (*once_callback)();
-}
-
-extern "C" {
-
- static void key_init()
- {
- pthread_key_create(&key, 0);
- }
-
- static void do_once()
- {
- once_callback* cb = reinterpret_cast<once_callback*>(
- pthread_getspecific(key));
- (**cb)();
- }
-
-}
-
-namespace boost {
-
-void call_once(void (*func)(), once_flag& flag)
-{
- pthread_once(&once, &key_init);
- pthread_setspecific(key, &func);
- pthread_once(&flag, do_once);
-}
-
-}
Modified: branches/thread_rewrite/boost/libs/thread/test/test_condition.cpp
==============================================================================
--- branches/thread_rewrite/boost/libs/thread/test/test_condition.cpp (original)
+++ branches/thread_rewrite/boost/libs/thread/test/test_condition.cpp 2007-10-05 05:52:08 EDT (Fri, 05 Oct 2007)
@@ -22,7 +22,7 @@
condition_test_data() : notified(0), awoken(0) { }
boost::mutex mutex;
- boost::condition condition;
+ boost::condition<boost::mutex> condition;
int notified;
int awoken;
};
Modified: branches/thread_rewrite/boost/libs/thread/test/test_once.cpp
==============================================================================
--- branches/thread_rewrite/boost/libs/thread/test/test_once.cpp (original)
+++ branches/thread_rewrite/boost/libs/thread/test/test_once.cpp 2007-10-05 05:52:08 EDT (Fri, 05 Oct 2007)
@@ -1,4 +1,4 @@
-// (C) Copyright 2006 Anthony Williams
+// (C) Copyright 2006-7 Anthony Williams
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -25,7 +25,7 @@
int my_once_value=0;
for(unsigned i=0;i<loop_count;++i)
{
- boost::call_once(initialize_variable, flag);
+ boost::call_once(flag, initialize_variable);
my_once_value=var_to_init;
if(my_once_value!=1)
{
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk