|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r56992 - in branches/release: boost boost/thread boost/thread/detail boost/thread/pthread libs/thread libs/thread/build libs/thread/example libs/thread/src/pthread libs/thread/src/win32 libs/thread/test
From: anthony_at_[hidden]
Date: 2009-10-19 05:18:16
Author: anthonyw
Date: 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
New Revision: 56992
URL: http://svn.boost.org/trac/boost/changeset/56992
Log:
Merged thread changes from trunk
Added:
branches/release/libs/thread/test/test_thread_move_return.cpp
- copied unchanged from r56991, /trunk/libs/thread/test/test_thread_move_return.cpp
branches/release/libs/thread/test/test_thread_return_local.cpp
- copied unchanged from r56991, /trunk/libs/thread/test/test_thread_return_local.cpp
Removed:
branches/release/libs/thread/src/pthread/exceptions.cpp
branches/release/libs/thread/src/win32/exceptions.cpp
Properties modified:
branches/release/boost/thread/ (props changed)
branches/release/boost/thread.hpp (props changed)
branches/release/libs/thread/ (props changed)
Text files modified:
branches/release/boost/thread/detail/move.hpp | 4
branches/release/boost/thread/detail/thread.hpp | 18 ++
branches/release/boost/thread/exceptions.hpp | 190 +++++++++++++++++++++++----------
branches/release/boost/thread/locks.hpp | 11 +
branches/release/boost/thread/pthread/thread_data.hpp | 17 ++
branches/release/boost/thread/tss.hpp | 222 ++++++++++++++++++++--------------------
branches/release/libs/thread/build/Jamfile.v2 | 2
branches/release/libs/thread/example/condition.cpp | 9 +
branches/release/libs/thread/example/tennis.cpp | 2
branches/release/libs/thread/src/pthread/thread.cpp | 164 ++++++++---------------------
branches/release/libs/thread/src/win32/thread.cpp | 2
branches/release/libs/thread/test/Jamfile.v2 | 2
branches/release/libs/thread/test/test_thread_move.cpp | 18 ---
branches/release/libs/thread/test/test_tss.cpp | 35 ++++++
14 files changed, 375 insertions(+), 321 deletions(-)
Modified: branches/release/boost/thread/detail/move.hpp
==============================================================================
--- branches/release/boost/thread/detail/move.hpp (original)
+++ branches/release/boost/thread/detail/move.hpp 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
@@ -41,9 +41,9 @@
#ifndef BOOST_NO_SFINAE
template<typename T>
- typename enable_if<boost::is_convertible<T&,detail::thread_move_t<T> >, T >::type move(T& t)
+ typename enable_if<boost::is_convertible<T&,detail::thread_move_t<T> >, detail::thread_move_t<T> >::type move(T& t)
{
- return T(detail::thread_move_t<T>(t));
+ return detail::thread_move_t<T>(t);
}
#endif
Modified: branches/release/boost/thread/detail/thread.hpp
==============================================================================
--- branches/release/boost/thread/detail/thread.hpp (original)
+++ branches/release/boost/thread/detail/thread.hpp 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
@@ -144,6 +144,9 @@
struct dummy;
#endif
public:
+#ifdef __SUNPRO_CC
+ thread(const volatile thread&);
+#endif
thread();
~thread();
@@ -201,14 +204,21 @@
thread_info=x->thread_info;
x->thread_info.reset();
}
-
+
+#ifdef __SUNPRO_CC
+ thread& operator=(thread x)
+ {
+ swap(x);
+ return *this;
+ }
+#else
thread& operator=(detail::thread_move_t<thread> x)
{
thread new_thread(x);
swap(new_thread);
return *this;
}
-
+#endif
operator detail::thread_move_t<thread>()
{
return move();
@@ -339,9 +349,9 @@
return t;
}
#else
- inline thread move(detail::thread_move_t<thread> t)
+ inline detail::thread_move_t<thread> move(detail::thread_move_t<thread> t)
{
- return thread(t);
+ return t;
}
#endif
Modified: branches/release/boost/thread/exceptions.hpp
==============================================================================
--- branches/release/boost/thread/exceptions.hpp (original)
+++ branches/release/boost/thread/exceptions.hpp 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
@@ -1,6 +1,6 @@
// Copyright (C) 2001-2003
// William E. Kempf
-// Copyright (C) 2007-8 Anthony Williams
+// Copyright (C) 2007-9 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)
@@ -24,23 +24,36 @@
namespace boost
{
- class BOOST_THREAD_DECL thread_interrupted
+ class thread_interrupted
{};
-class BOOST_THREAD_DECL thread_exception : public std::exception
-{
-protected:
- thread_exception();
- thread_exception(int sys_err_code);
-
-public:
- ~thread_exception() throw();
-
- int native_error() const;
-
-private:
- int m_sys_err;
-};
+ class thread_exception:
+ public std::exception
+ {
+ protected:
+ thread_exception():
+ m_sys_err(0)
+ {}
+
+ thread_exception(int sys_err_code):
+ m_sys_err(sys_err_code)
+ {}
+
+
+ public:
+ ~thread_exception() throw()
+ {}
+
+
+ int native_error() const
+ {
+ return m_sys_err;
+ }
+
+
+ private:
+ int m_sys_err;
+ };
class condition_error:
public std::exception
@@ -53,62 +66,117 @@
};
-class BOOST_THREAD_DECL lock_error : public thread_exception
-{
-public:
- lock_error();
- lock_error(int sys_err_code);
- ~lock_error() throw();
+ class lock_error:
+ public thread_exception
+ {
+ public:
+ lock_error()
+ {}
+
+ lock_error(int sys_err_code):
+ thread_exception(sys_err_code)
+ {}
+
+ ~lock_error() throw()
+ {}
+
- virtual const char* what() const throw();
-};
+ virtual const char* what() const throw()
+ {
+ return "boost::lock_error";
+ }
+ };
-class BOOST_THREAD_DECL thread_resource_error : public thread_exception
-{
-public:
- thread_resource_error();
- thread_resource_error(int sys_err_code);
- ~thread_resource_error() throw();
+ class thread_resource_error:
+ public thread_exception
+ {
+ public:
+ thread_resource_error()
+ {}
+
+ thread_resource_error(int sys_err_code):
+ thread_exception(sys_err_code)
+ {}
+
+ ~thread_resource_error() throw()
+ {}
+
- virtual const char* what() const throw();
-};
+ virtual const char* what() const throw()
+ {
+ return "boost::thread_resource_error";
+ }
+
+ };
-class BOOST_THREAD_DECL unsupported_thread_option : public thread_exception
-{
-public:
- unsupported_thread_option();
- unsupported_thread_option(int sys_err_code);
- ~unsupported_thread_option() throw();
+ class unsupported_thread_option:
+ public thread_exception
+ {
+ public:
+ unsupported_thread_option()
+ {}
+
+ unsupported_thread_option(int sys_err_code):
+ thread_exception(sys_err_code)
+ {}
+
+ ~unsupported_thread_option() throw()
+ {}
+
- virtual const char* what() const throw();
-};
+ virtual const char* what() const throw()
+ {
+ return "boost::unsupported_thread_option";
+ }
+
+ };
-class BOOST_THREAD_DECL invalid_thread_argument : public thread_exception
-{
-public:
- invalid_thread_argument();
- invalid_thread_argument(int sys_err_code);
- ~invalid_thread_argument() throw();
+ class invalid_thread_argument:
+ public thread_exception
+ {
+ public:
+ invalid_thread_argument()
+ {}
+
+ invalid_thread_argument(int sys_err_code):
+ thread_exception(sys_err_code)
+ {}
+
+ ~invalid_thread_argument() throw()
+ {}
+
- virtual const char* what() const throw();
-};
+ virtual const char* what() const throw()
+ {
+ return "boost::invalid_thread_argument";
+ }
+
+ };
-class BOOST_THREAD_DECL thread_permission_error : public thread_exception
-{
-public:
- thread_permission_error();
- thread_permission_error(int sys_err_code);
- ~thread_permission_error() throw();
+ class thread_permission_error:
+ public thread_exception
+ {
+ public:
+ thread_permission_error()
+ {}
+
+ thread_permission_error(int sys_err_code):
+ thread_exception(sys_err_code)
+ {}
+
+ ~thread_permission_error() throw()
+ {}
+
- virtual const char* what() const throw();
-};
+ virtual const char* what() const throw()
+ {
+ return "boost::thread_permission_error";
+ }
+
+ };
} // namespace boost
#include <boost/config/abi_suffix.hpp>
-#endif // BOOST_THREAD_CONFIG_PDM070801_H
-
-// Change log:
-// 3 Jan 03 WEKEMPF Modified for DLL implementation.
-
+#endif
Modified: branches/release/boost/thread/locks.hpp
==============================================================================
--- branches/release/boost/thread/locks.hpp (original)
+++ branches/release/boost/thread/locks.hpp 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
@@ -214,6 +214,9 @@
unique_lock& operator=(unique_lock&);
unique_lock& operator=(upgrade_lock<Mutex>& other);
public:
+#ifdef __SUNPRO_CC
+ unique_lock(const volatile unique_lock&);
+#endif
unique_lock():
m(0),is_locked(false)
{}
@@ -297,12 +300,20 @@
return detail::thread_move_t<unique_lock<Mutex> >(*this);
}
+#ifdef __SUNPRO_CC
+ unique_lock& operator=(unique_lock<Mutex> other)
+ {
+ swap(other);
+ return *this;
+ }
+#else
unique_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other)
{
unique_lock temp(other);
swap(temp);
return *this;
}
+#endif
unique_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other)
{
Modified: branches/release/boost/thread/pthread/thread_data.hpp
==============================================================================
--- branches/release/boost/thread/pthread/thread_data.hpp (original)
+++ branches/release/boost/thread/pthread/thread_data.hpp 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
@@ -13,6 +13,7 @@
#include <boost/optional.hpp>
#include <pthread.h>
#include "condition_variable_fwd.hpp"
+#include <map>
#include <boost/config/abi_prefix.hpp>
@@ -22,8 +23,18 @@
namespace detail
{
+ struct tss_cleanup_function;
struct thread_exit_callback_node;
- struct tss_data_node;
+ struct tss_data_node
+ {
+ boost::shared_ptr<boost::detail::tss_cleanup_function> func;
+ void* value;
+
+ tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_,
+ void* value_):
+ func(func_),value(value_)
+ {}
+ };
struct thread_data_base;
typedef boost::shared_ptr<thread_data_base> thread_data_ptr;
@@ -41,14 +52,14 @@
bool join_started;
bool joined;
boost::detail::thread_exit_callback_node* thread_exit_callbacks;
- boost::detail::tss_data_node* tss_data;
+ std::map<void const*,boost::detail::tss_data_node> tss_data;
bool interrupt_enabled;
bool interrupt_requested;
pthread_cond_t* current_cond;
thread_data_base():
done(false),join_started(false),joined(false),
- thread_exit_callbacks(0),tss_data(0),
+ thread_exit_callbacks(0),
interrupt_enabled(true),
interrupt_requested(false),
current_cond(0)
Modified: branches/release/boost/thread/tss.hpp
==============================================================================
--- branches/release/boost/thread/tss.hpp (original)
+++ branches/release/boost/thread/tss.hpp 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
@@ -1,111 +1,111 @@
-#ifndef BOOST_THREAD_TSS_HPP
-#define BOOST_THREAD_TSS_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)
-// (C) Copyright 2007-8 Anthony Williams
-
-#include <boost/thread/detail/config.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/thread/detail/thread_heap_alloc.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-namespace boost
-{
- namespace detail
- {
- struct tss_cleanup_function
- {
- virtual ~tss_cleanup_function()
- {}
-
- virtual void operator()(void* data)=0;
- };
-
- BOOST_THREAD_DECL void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing);
- BOOST_THREAD_DECL void* get_tss_data(void const* key);
- }
-
- template <typename T>
- class thread_specific_ptr
- {
- private:
- thread_specific_ptr(thread_specific_ptr&);
- thread_specific_ptr& operator=(thread_specific_ptr&);
-
- struct delete_data:
- detail::tss_cleanup_function
- {
- void operator()(void* data)
- {
- delete static_cast<T*>(data);
- }
- };
-
- struct run_custom_cleanup_function:
- detail::tss_cleanup_function
- {
- void (*cleanup_function)(T*);
-
- explicit run_custom_cleanup_function(void (*cleanup_function_)(T*)):
- cleanup_function(cleanup_function_)
- {}
-
- void operator()(void* data)
- {
- cleanup_function(static_cast<T*>(data));
- }
- };
-
-
- boost::shared_ptr<detail::tss_cleanup_function> cleanup;
-
- public:
- thread_specific_ptr():
- cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>())
- {}
- explicit thread_specific_ptr(void (*func_)(T*))
- {
- if(func_)
- {
- cleanup.reset(detail::heap_new<run_custom_cleanup_function>(func_),detail::do_heap_delete<run_custom_cleanup_function>());
- }
- }
- ~thread_specific_ptr()
- {
- reset();
- }
-
- T* get() const
- {
- return static_cast<T*>(detail::get_tss_data(this));
- }
- T* operator->() const
- {
- return get();
- }
- T& operator*() const
- {
- return *get();
- }
- T* release()
- {
- T* const temp=get();
- detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false);
- return temp;
- }
- void reset(T* new_value=0)
- {
- T* const current_value=get();
- if(current_value!=new_value)
- {
- detail::set_tss_data(this,cleanup,new_value,true);
- }
- }
- };
-}
-
-#include <boost/config/abi_suffix.hpp>
-
-#endif
+#ifndef BOOST_THREAD_TSS_HPP
+#define BOOST_THREAD_TSS_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)
+// (C) Copyright 2007-8 Anthony Williams
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/detail/thread_heap_alloc.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ struct tss_cleanup_function
+ {
+ virtual ~tss_cleanup_function()
+ {}
+
+ virtual void operator()(void* data)=0;
+ };
+
+ BOOST_THREAD_DECL void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing);
+ BOOST_THREAD_DECL void* get_tss_data(void const* key);
+ }
+
+ template <typename T>
+ class thread_specific_ptr
+ {
+ private:
+ thread_specific_ptr(thread_specific_ptr&);
+ thread_specific_ptr& operator=(thread_specific_ptr&);
+
+ struct delete_data:
+ detail::tss_cleanup_function
+ {
+ void operator()(void* data)
+ {
+ delete static_cast<T*>(data);
+ }
+ };
+
+ struct run_custom_cleanup_function:
+ detail::tss_cleanup_function
+ {
+ void (*cleanup_function)(T*);
+
+ explicit run_custom_cleanup_function(void (*cleanup_function_)(T*)):
+ cleanup_function(cleanup_function_)
+ {}
+
+ void operator()(void* data)
+ {
+ cleanup_function(static_cast<T*>(data));
+ }
+ };
+
+
+ boost::shared_ptr<detail::tss_cleanup_function> cleanup;
+
+ public:
+ thread_specific_ptr():
+ cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>())
+ {}
+ explicit thread_specific_ptr(void (*func_)(T*))
+ {
+ if(func_)
+ {
+ cleanup.reset(detail::heap_new<run_custom_cleanup_function>(func_),detail::do_heap_delete<run_custom_cleanup_function>());
+ }
+ }
+ ~thread_specific_ptr()
+ {
+ detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,true);
+ }
+
+ T* get() const
+ {
+ return static_cast<T*>(detail::get_tss_data(this));
+ }
+ T* operator->() const
+ {
+ return get();
+ }
+ T& operator*() const
+ {
+ return *get();
+ }
+ T* release()
+ {
+ T* const temp=get();
+ detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false);
+ return temp;
+ }
+ void reset(T* new_value=0)
+ {
+ T* const current_value=get();
+ if(current_value!=new_value)
+ {
+ detail::set_tss_data(this,cleanup,new_value,true);
+ }
+ }
+ };
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
Modified: branches/release/libs/thread/build/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/build/Jamfile.v2 (original)
+++ branches/release/libs/thread/build/Jamfile.v2 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
@@ -180,7 +180,6 @@
alias thread_sources
: ## win32 sources ##
win32/thread.cpp
- win32/exceptions.cpp
win32/tss_dll.cpp
win32/tss_pe.cpp
: ## requirements ##
@@ -190,7 +189,6 @@
alias thread_sources
: ## pthread sources ##
pthread/thread.cpp
- pthread/exceptions.cpp
pthread/once.cpp
: ## requirements ##
<threadapi>pthread
Modified: branches/release/libs/thread/example/condition.cpp
==============================================================================
--- branches/release/libs/thread/example/condition.cpp (original)
+++ branches/release/libs/thread/example/condition.cpp 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
@@ -50,8 +50,9 @@
void sender() {
int n = 0;
- while (n < 100) {
+ while (n < 1000000) {
buf.send(n);
+ if(!(n%10000))
{
boost::mutex::scoped_lock io_lock(io_mutex);
std::cout << "sent: " << n << std::endl;
@@ -65,18 +66,24 @@
int n;
do {
n = buf.receive();
+ if(!(n%10000))
{
boost::mutex::scoped_lock io_lock(io_mutex);
std::cout << "received: " << n << std::endl;
}
} while (n != -1); // -1 indicates end of buffer
+ buf.send(-1);
}
int main(int, char*[])
{
boost::thread thrd1(&sender);
boost::thread thrd2(&receiver);
+ boost::thread thrd3(&receiver);
+ boost::thread thrd4(&receiver);
thrd1.join();
thrd2.join();
+ thrd3.join();
+ thrd4.join();
return 0;
}
Modified: branches/release/libs/thread/example/tennis.cpp
==============================================================================
--- branches/release/libs/thread/example/tennis.cpp (original)
+++ branches/release/libs/thread/example/tennis.cpp 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
@@ -112,7 +112,7 @@
std::cout << "---Noise ON..." << std::endl;
}
- for (int i = 0; i < 1000000; ++i)
+ for (int i = 0; i < 1000000000; ++i)
cond.notify_all();
{
Deleted: branches/release/libs/thread/src/pthread/exceptions.cpp
==============================================================================
--- branches/release/libs/thread/src/pthread/exceptions.cpp 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
+++ (empty file)
@@ -1,124 +0,0 @@
-// Copyright (C) 2001-2003
-// William E. Kempf
-//
-// 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/detail/config.hpp>
-
-#include <boost/thread/exceptions.hpp>
-#include <cstring>
-#include <string>
-
-namespace boost {
-
-thread_exception::thread_exception()
- : m_sys_err(0)
-{
-}
-
-thread_exception::thread_exception(int sys_err_code)
- : m_sys_err(sys_err_code)
-{
-}
-
-thread_exception::~thread_exception() throw()
-{
-}
-
-int thread_exception::native_error() const
-{
- return m_sys_err;
-}
-
-lock_error::lock_error()
-{
-}
-
-lock_error::lock_error(int sys_err_code)
- : thread_exception(sys_err_code)
-{
-}
-
-lock_error::~lock_error() throw()
-{
-}
-
-const char* lock_error::what() const throw()
-{
- return "boost::lock_error";
-}
-
-thread_resource_error::thread_resource_error()
-{
-}
-
-thread_resource_error::thread_resource_error(int sys_err_code)
- : thread_exception(sys_err_code)
-{
-}
-
-thread_resource_error::~thread_resource_error() throw()
-{
-}
-
-const char* thread_resource_error::what() const throw()
-{
- return "boost::thread_resource_error";
-}
-
-unsupported_thread_option::unsupported_thread_option()
-{
-}
-
-unsupported_thread_option::unsupported_thread_option(int sys_err_code)
- : thread_exception(sys_err_code)
-{
-}
-
-unsupported_thread_option::~unsupported_thread_option() throw()
-{
-}
-
-const char* unsupported_thread_option::what() const throw()
-{
- return "boost::unsupported_thread_option";
-}
-
-invalid_thread_argument::invalid_thread_argument()
-{
-}
-
-invalid_thread_argument::invalid_thread_argument(int sys_err_code)
- : thread_exception(sys_err_code)
-{
-}
-
-invalid_thread_argument::~invalid_thread_argument() throw()
-{
-}
-
-const char* invalid_thread_argument::what() const throw()
-{
- return "boost::invalid_thread_argument";
-}
-
-thread_permission_error::thread_permission_error()
-{
-}
-
-thread_permission_error::thread_permission_error(int sys_err_code)
- : thread_exception(sys_err_code)
-{
-}
-
-thread_permission_error::~thread_permission_error() throw()
-{
-}
-
-const char* thread_permission_error::what() const throw()
-{
- return "boost::thread_permission_error";
-}
-
-} // namespace boost
Modified: branches/release/libs/thread/src/pthread/thread.cpp
==============================================================================
--- branches/release/libs/thread/src/pthread/thread.cpp (original)
+++ branches/release/libs/thread/src/pthread/thread.cpp 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
@@ -42,19 +42,6 @@
{}
};
- struct tss_data_node
- {
- void const* key;
- boost::shared_ptr<boost::detail::tss_cleanup_function> func;
- void* value;
- tss_data_node* next;
-
- tss_data_node(void const* key_,boost::shared_ptr<boost::detail::tss_cleanup_function> func_,void* value_,
- tss_data_node* next_):
- key(key_),func(func_),value(value_),next(next_)
- {}
- };
-
namespace
{
boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT;
@@ -67,7 +54,7 @@
boost::detail::thread_data_base* thread_info=static_cast<boost::detail::thread_data_base*>(data);
if(thread_info)
{
- while(thread_info->tss_data || thread_info->thread_exit_callbacks)
+ while(!thread_info->tss_data.empty() || thread_info->thread_exit_callbacks)
{
while(thread_info->thread_exit_callbacks)
{
@@ -80,15 +67,18 @@
}
delete current_node;
}
- while(thread_info->tss_data)
+ for(std::map<void const*,tss_data_node>::iterator next=thread_info->tss_data.begin(),
+ current,
+ end=thread_info->tss_data.end();
+ next!=end;)
{
- detail::tss_data_node* const current_node=thread_info->tss_data;
- thread_info->tss_data=current_node->next;
- if(current_node->func)
+ current=next;
+ ++next;
+ if(current->second.func && current->second.value)
{
- (*current_node->func)(current_node->value);
+ (*current->second.func)(current->second.value);
}
- delete current_node;
+ thread_info->tss_data.erase(current);
}
}
thread_info->self.reset();
@@ -390,7 +380,7 @@
{
#if defined(PTW32_VERSION) || defined(__hpux)
return pthread_num_processors_np();
-#elif defined(__linux__)
+#elif defined(_GNU_SOURCE)
return get_nprocs();
#elif defined(__APPLE__) || defined(__FreeBSD__)
int count;
@@ -552,14 +542,11 @@
detail::thread_data_base* const current_thread_data(get_current_thread_data());
if(current_thread_data)
{
- detail::tss_data_node* current_node=current_thread_data->tss_data;
- while(current_node)
+ std::map<void const*,tss_data_node>::iterator current_node=
+ current_thread_data->tss_data.find(key);
+ if(current_node!=current_thread_data->tss_data.end())
{
- if(current_node->key==key)
- {
- return current_node;
- }
- current_node=current_node->next;
+ return ¤t_node->second;
}
}
return NULL;
@@ -573,106 +560,47 @@
}
return NULL;
}
+
+ void add_new_tss_node(void const* key,
+ boost::shared_ptr<tss_cleanup_function> func,
+ void* tss_data)
+ {
+ detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
+ current_thread_data->tss_data.insert(std::make_pair(key,tss_data_node(func,tss_data)));
+ }
+
+ void erase_tss_node(void const* key)
+ {
+ detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
+ current_thread_data->tss_data.erase(key);
+ }
- void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing)
+ void set_tss_data(void const* key,
+ boost::shared_ptr<tss_cleanup_function> func,
+ void* tss_data,bool cleanup_existing)
{
if(tss_data_node* const current_node=find_tss_data(key))
{
- if(cleanup_existing && current_node->func)
+ if(cleanup_existing && current_node->func && current_node->value)
{
(*current_node->func)(current_node->value);
}
- current_node->func=func;
- current_node->value=tss_data;
+ if(func || tss_data)
+ {
+ current_node->func=func;
+ current_node->value=tss_data;
+ }
+ else
+ {
+ erase_tss_node(key);
+ }
}
else
{
- detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
- tss_data_node* const new_node=new tss_data_node(key,func,tss_data,current_thread_data->tss_data);
- current_thread_data->tss_data=new_node;
- }
- }
- }
-
-// thread_group::thread_group()
-// {
-// }
-
-// thread_group::~thread_group()
-// {
-// // We shouldn't have to scoped_lock here, since referencing this object
-// // from another thread while we're deleting it in the current thread is
-// // going to lead to undefined behavior any way.
-// for (std::list<thread*>::iterator it = m_threads.begin();
-// it != m_threads.end(); ++it)
-// {
-// delete (*it);
-// }
-// }
-
-// thread* thread_group::create_thread(const function0<void>& threadfunc)
-// {
-// // No scoped_lock required here since the only "shared data" that's
-// // modified here occurs inside add_thread which does scoped_lock.
-// std::auto_ptr<thread> thrd(new thread(threadfunc));
-// add_thread(thrd.get());
-// return thrd.release();
-// }
-
-// void thread_group::add_thread(thread* thrd)
-// {
-// mutex::scoped_lock scoped_lock(m_mutex);
-
-// // For now we'll simply ignore requests to add a thread object multiple
-// // times. Should we consider this an error and either throw or return an
-// // error value?
-// std::list<thread*>::iterator it = std::find(m_threads.begin(),
-// m_threads.end(), thrd);
-// BOOST_ASSERT(it == m_threads.end());
-// if (it == m_threads.end())
-// m_threads.push_back(thrd);
-// }
-
-// void thread_group::remove_thread(thread* thrd)
-// {
-// mutex::scoped_lock scoped_lock(m_mutex);
-
-// // For now we'll simply ignore requests to remove a thread object that's
-// // not in the group. Should we consider this an error and either throw or
-// // return an error value?
-// std::list<thread*>::iterator it = std::find(m_threads.begin(),
-// m_threads.end(), thrd);
-// BOOST_ASSERT(it != m_threads.end());
-// if (it != m_threads.end())
-// m_threads.erase(it);
-// }
-
-// void thread_group::join_all()
-// {
-// mutex::scoped_lock scoped_lock(m_mutex);
-// for (std::list<thread*>::iterator it = m_threads.begin();
-// it != m_threads.end(); ++it)
-// {
-// (*it)->join();
-// }
-// }
-
-// void thread_group::interrupt_all()
-// {
-// boost::lock_guard<mutex> guard(m_mutex);
-
-// for(std::list<thread*>::iterator it=m_threads.begin(),end=m_threads.end();
-// it!=end;
-// ++it)
-// {
-// (*it)->interrupt();
-// }
-// }
-
+ add_new_tss_node(key,func,tss_data);
+ }
+ }
+ }
-// size_t thread_group::size() const
-// {
-// return m_threads.size();
-// }
}
Deleted: branches/release/libs/thread/src/win32/exceptions.cpp
==============================================================================
--- branches/release/libs/thread/src/win32/exceptions.cpp 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
+++ (empty file)
@@ -1,124 +0,0 @@
-// Copyright (C) 2001-2003
-// William E. Kempf
-//
-// 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/detail/config.hpp>
-
-#include <boost/thread/exceptions.hpp>
-#include <cstring>
-#include <string>
-
-namespace boost {
-
-thread_exception::thread_exception()
- : m_sys_err(0)
-{
-}
-
-thread_exception::thread_exception(int sys_err_code)
- : m_sys_err(sys_err_code)
-{
-}
-
-thread_exception::~thread_exception() throw()
-{
-}
-
-int thread_exception::native_error() const
-{
- return m_sys_err;
-}
-
-lock_error::lock_error()
-{
-}
-
-lock_error::lock_error(int sys_err_code)
- : thread_exception(sys_err_code)
-{
-}
-
-lock_error::~lock_error() throw()
-{
-}
-
-const char* lock_error::what() const throw()
-{
- return "boost::lock_error";
-}
-
-thread_resource_error::thread_resource_error()
-{
-}
-
-thread_resource_error::thread_resource_error(int sys_err_code)
- : thread_exception(sys_err_code)
-{
-}
-
-thread_resource_error::~thread_resource_error() throw()
-{
-}
-
-const char* thread_resource_error::what() const throw()
-{
- return "boost::thread_resource_error";
-}
-
-unsupported_thread_option::unsupported_thread_option()
-{
-}
-
-unsupported_thread_option::unsupported_thread_option(int sys_err_code)
- : thread_exception(sys_err_code)
-{
-}
-
-unsupported_thread_option::~unsupported_thread_option() throw()
-{
-}
-
-const char* unsupported_thread_option::what() const throw()
-{
- return "boost::unsupported_thread_option";
-}
-
-invalid_thread_argument::invalid_thread_argument()
-{
-}
-
-invalid_thread_argument::invalid_thread_argument(int sys_err_code)
- : thread_exception(sys_err_code)
-{
-}
-
-invalid_thread_argument::~invalid_thread_argument() throw()
-{
-}
-
-const char* invalid_thread_argument::what() const throw()
-{
- return "boost::invalid_thread_argument";
-}
-
-thread_permission_error::thread_permission_error()
-{
-}
-
-thread_permission_error::thread_permission_error(int sys_err_code)
- : thread_exception(sys_err_code)
-{
-}
-
-thread_permission_error::~thread_permission_error() throw()
-{
-}
-
-const char* thread_permission_error::what() const throw()
-{
- return "boost::thread_permission_error";
-}
-
-} // namespace boost
Modified: branches/release/libs/thread/src/win32/thread.cpp
==============================================================================
--- branches/release/libs/thread/src/win32/thread.cpp (original)
+++ branches/release/libs/thread/src/win32/thread.cpp 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
@@ -561,7 +561,7 @@
{
if(tss_data_node* const current_node=find_tss_data(key))
{
- if(cleanup_existing && current_node->func.get())
+ if(cleanup_existing && current_node->func.get() && current_node->value)
{
(*current_node->func)(current_node->value);
}
Modified: branches/release/libs/thread/test/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/test/Jamfile.v2 (original)
+++ branches/release/libs/thread/test/Jamfile.v2 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
@@ -38,6 +38,8 @@
[ thread-run test_thread_id.cpp ]
[ thread-run test_hardware_concurrency.cpp ]
[ thread-run test_thread_move.cpp ]
+ [ thread-run test_thread_return_local.cpp ]
+ [ thread-run test_thread_move_return.cpp ]
[ thread-run test_thread_launching.cpp ]
[ thread-run test_thread_mf.cpp ]
[ thread-run test_move_function.cpp ]
Modified: branches/release/libs/thread/test/test_thread_move.cpp
==============================================================================
--- branches/release/libs/thread/test/test_thread_move.cpp (original)
+++ branches/release/libs/thread/test/test_thread_move.cpp 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 Anthony Williams
+// Copyright (C) 2007-9 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)
@@ -33,21 +33,6 @@
BOOST_CHECK_EQUAL(the_id,x_id);
}
-boost::thread make_thread_return_lvalue(boost::thread::id* the_id)
-{
- boost::thread t(do_nothing,the_id);
- return boost::move(t);
-}
-
-void test_move_from_function_return_lvalue()
-{
- boost::thread::id the_id;
- boost::thread x=make_thread_return_lvalue(&the_id);
- boost::thread::id x_id=x.get_id();
- x.join();
- BOOST_CHECK_EQUAL(the_id,x_id);
-}
-
void test_move_assign()
{
boost::thread::id the_id;
@@ -66,7 +51,6 @@
test->add(BOOST_TEST_CASE(test_move_on_construction));
test->add(BOOST_TEST_CASE(test_move_from_function_return));
- test->add(BOOST_TEST_CASE(test_move_from_function_return_lvalue));
test->add(BOOST_TEST_CASE(test_move_assign));
return test;
}
Modified: branches/release/libs/thread/test/test_tss.cpp
==============================================================================
--- branches/release/libs/thread/test/test_tss.cpp (original)
+++ branches/release/libs/thread/test/test_tss.cpp 2009-10-19 05:18:13 EDT (Mon, 19 Oct 2009)
@@ -310,6 +310,39 @@
timed_test(&do_test_tss_does_no_cleanup_with_null_cleanup_function, 2);
}
+void thread_with_local_tss_ptr()
+{
+ {
+ boost::thread_specific_ptr<Dummy> local_tss(tss_custom_cleanup);
+
+ local_tss.reset(new Dummy);
+ }
+ BOOST_CHECK(tss_cleanup_called);
+ tss_cleanup_called=false;
+}
+
+
+void test_tss_does_not_call_cleanup_after_ptr_destroyed()
+{
+ boost::thread t(thread_with_local_tss_ptr);
+ t.join();
+ BOOST_CHECK(!tss_cleanup_called);
+}
+
+void test_tss_cleanup_not_called_for_null_pointer()
+{
+ boost::thread_specific_ptr<Dummy> local_tss(tss_custom_cleanup);
+ local_tss.reset(new Dummy);
+ tss_cleanup_called=false;
+ local_tss.reset(0);
+ BOOST_CHECK(tss_cleanup_called);
+ tss_cleanup_called=false;
+ local_tss.reset(new Dummy);
+ BOOST_CHECK(!tss_cleanup_called);
+}
+
+
+
boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
{
boost::unit_test_framework::test_suite* test =
@@ -319,6 +352,8 @@
test->add(BOOST_TEST_CASE(test_tss_with_custom_cleanup));
test->add(BOOST_TEST_CASE(test_tss_does_no_cleanup_after_release));
test->add(BOOST_TEST_CASE(test_tss_does_no_cleanup_with_null_cleanup_function));
+ test->add(BOOST_TEST_CASE(test_tss_does_not_call_cleanup_after_ptr_destroyed));
+ test->add(BOOST_TEST_CASE(test_tss_cleanup_not_called_for_null_pointer));
return test;
}
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