mirror of
https://github.com/boostorg/thread.git
synced 2026-02-05 10:12:09 +00:00
Compare commits
7 Commits
boost-1.45
...
boost-1.48
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29f6f419ec | ||
|
|
b991c9a8a0 | ||
|
|
ab665c8c56 | ||
|
|
7ec9804540 | ||
|
|
7c9116af2e | ||
|
|
70584af9c0 | ||
|
|
381554f8bc |
@@ -41,6 +41,11 @@ order. If a cleanup routine sets the value of associated with an instance of `bo
|
||||
cleaned up, that value is added to the cleanup list. Cleanup finishes when there are no outstanding instances of
|
||||
`boost::thread_specific_ptr` with values.
|
||||
|
||||
Note: on some platforms, cleanup of thread-specific data is not
|
||||
performed for threads created with the platform's native API. On those
|
||||
platforms such cleanup is only done for threads that are started with
|
||||
`boost::thread` unless `boost::on_thread_exit()` is called manually
|
||||
from that thread.
|
||||
|
||||
[section:thread_specific_ptr Class `thread_specific_ptr`]
|
||||
|
||||
|
||||
@@ -47,27 +47,39 @@ namespace boost
|
||||
|
||||
inline void condition_variable::wait(unique_lock<mutex>& m)
|
||||
{
|
||||
thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
|
||||
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
|
||||
guard.activate(m);
|
||||
int const res=pthread_cond_wait(&cond,&internal_mutex);
|
||||
BOOST_ASSERT(!res);
|
||||
int res=0;
|
||||
{
|
||||
thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
|
||||
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
|
||||
guard.activate(m);
|
||||
res=pthread_cond_wait(&cond,&internal_mutex);
|
||||
}
|
||||
this_thread::interruption_point();
|
||||
if(res)
|
||||
{
|
||||
boost::throw_exception(condition_error());
|
||||
}
|
||||
}
|
||||
|
||||
inline bool condition_variable::timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until)
|
||||
{
|
||||
thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
|
||||
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
|
||||
guard.activate(m);
|
||||
struct timespec const timeout=detail::get_timespec(wait_until);
|
||||
int const cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
|
||||
int cond_res;
|
||||
{
|
||||
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
|
||||
guard.activate(m);
|
||||
struct timespec const timeout=detail::get_timespec(wait_until);
|
||||
cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
|
||||
}
|
||||
this_thread::interruption_point();
|
||||
if(cond_res==ETIMEDOUT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
BOOST_ASSERT(!cond_res);
|
||||
if(cond_res)
|
||||
{
|
||||
boost::throw_exception(condition_error());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -121,8 +133,8 @@ namespace boost
|
||||
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
|
||||
guard.activate(m);
|
||||
res=pthread_cond_wait(&cond,&internal_mutex);
|
||||
this_thread::interruption_point();
|
||||
}
|
||||
this_thread::interruption_point();
|
||||
if(res)
|
||||
{
|
||||
boost::throw_exception(condition_error());
|
||||
@@ -145,8 +157,8 @@ namespace boost
|
||||
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
|
||||
guard.activate(m);
|
||||
res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
|
||||
this_thread::interruption_point();
|
||||
}
|
||||
this_thread::interruption_point();
|
||||
if(res==ETIMEDOUT)
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -145,9 +145,9 @@ namespace boost
|
||||
{}
|
||||
};
|
||||
|
||||
inline unsigned long pin_to_zero(long value)
|
||||
inline uintmax_t pin_to_zero(intmax_t value)
|
||||
{
|
||||
return (value<0)?0u:(unsigned long)value;
|
||||
return (value<0)?0u:(uintmax_t)value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace boost
|
||||
void BOOST_THREAD_DECL yield();
|
||||
|
||||
bool BOOST_THREAD_DECL interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time);
|
||||
inline void interruptible_wait(unsigned long milliseconds)
|
||||
inline void interruptible_wait(uintmax_t milliseconds)
|
||||
{
|
||||
interruptible_wait(detail::win32::invalid_handle_value,milliseconds);
|
||||
}
|
||||
|
||||
16
src/pthread/once.cpp
Executable file → Normal file
16
src/pthread/once.cpp
Executable file → Normal file
@@ -22,16 +22,18 @@ namespace boost
|
||||
pthread_key_t epoch_tss_key;
|
||||
pthread_once_t epoch_tss_key_flag=PTHREAD_ONCE_INIT;
|
||||
|
||||
extern "C" void delete_epoch_tss_data(void* data)
|
||||
extern "C"
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
static void delete_epoch_tss_data(void* data)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
extern "C" void create_epoch_tss_key()
|
||||
{
|
||||
BOOST_VERIFY(!pthread_key_create(&epoch_tss_key,delete_epoch_tss_data));
|
||||
static void create_epoch_tss_key()
|
||||
{
|
||||
BOOST_VERIFY(!pthread_key_create(&epoch_tss_key,delete_epoch_tss_data));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boost::uintmax_t& get_once_per_thread_epoch()
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace boost
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void tls_destructor(void* data)
|
||||
static void tls_destructor(void* data)
|
||||
{
|
||||
boost::detail::thread_data_base* thread_info=static_cast<boost::detail::thread_data_base*>(data);
|
||||
if(thread_info)
|
||||
@@ -111,7 +111,7 @@ namespace boost
|
||||
{
|
||||
extern "C"
|
||||
{
|
||||
void* thread_proxy(void* param)
|
||||
static void* thread_proxy(void* param)
|
||||
{
|
||||
boost::detail::thread_data_ptr thread_info = static_cast<boost::detail::thread_data_base*>(param)->self;
|
||||
thread_info->self.reset();
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <algorithm>
|
||||
#include <windows.h>
|
||||
#ifndef UNDER_CE
|
||||
#include <process.h>
|
||||
#endif
|
||||
@@ -20,6 +19,7 @@
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/thread/detail/tss_hooks.hpp>
|
||||
#include <boost/date_time/posix_time/conversion.hpp>
|
||||
#include <windows.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -32,7 +32,12 @@ namespace boost
|
||||
{
|
||||
tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in
|
||||
current_thread_tls_key=TlsAlloc();
|
||||
BOOST_ASSERT(current_thread_tls_key!=TLS_OUT_OF_INDEXES);
|
||||
#if defined(UNDER_CE)
|
||||
// Windows CE does not define the TLS_OUT_OF_INDEXES constant.
|
||||
BOOST_ASSERT(current_thread_tls_key!=0xFFFFFFFF);
|
||||
#else
|
||||
BOOST_ASSERT(current_thread_tls_key!=TLS_OUT_OF_INDEXES);
|
||||
#endif
|
||||
}
|
||||
|
||||
void cleanup_tls_key()
|
||||
@@ -56,10 +61,13 @@ namespace boost
|
||||
void set_current_thread_data(detail::thread_data_base* new_data)
|
||||
{
|
||||
boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key);
|
||||
BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data));
|
||||
if(current_thread_tls_key)
|
||||
BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data));
|
||||
else
|
||||
boost::throw_exception(thread_resource_error());
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_THREADEX
|
||||
#ifndef BOOST_HAS_THREADEX
|
||||
// Windows CE doesn't define _beginthreadex
|
||||
|
||||
struct ThreadProxyData
|
||||
@@ -221,7 +229,15 @@ namespace boost
|
||||
void make_external_thread_data()
|
||||
{
|
||||
externally_launched_thread* me=detail::heap_new<externally_launched_thread>();
|
||||
set_current_thread_data(me);
|
||||
try
|
||||
{
|
||||
set_current_thread_data(me);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
detail::heap_delete(me);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
detail::thread_data_base* get_or_make_current_thread_data()
|
||||
@@ -540,8 +556,8 @@ namespace boost
|
||||
{
|
||||
detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
|
||||
thread_exit_callback_node* const new_node=
|
||||
heap_new<thread_exit_callback_node>(func,
|
||||
current_thread_data->thread_exit_callbacks);
|
||||
heap_new<thread_exit_callback_node>(
|
||||
func,current_thread_data->thread_exit_callbacks);
|
||||
current_thread_data->thread_exit_callbacks=new_node;
|
||||
}
|
||||
|
||||
@@ -583,10 +599,11 @@ namespace boost
|
||||
current_node->func=func;
|
||||
current_node->value=tss_data;
|
||||
}
|
||||
else
|
||||
else if(func && tss_data)
|
||||
{
|
||||
detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
|
||||
tss_data_node* const new_node=heap_new<tss_data_node>(key,func,tss_data,current_thread_data->tss_data);
|
||||
tss_data_node* const new_node=
|
||||
heap_new<tss_data_node>(key,func,tss_data,current_thread_data->tss_data);
|
||||
current_thread_data->tss_data=new_node;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)
|
||||
|
||||
#if defined(__MINGW32__) && !defined(_WIN64)
|
||||
#if (defined(__MINGW32__) && !defined(_WIN64)) || defined(__MINGW64__)
|
||||
|
||||
#include <boost/thread/detail/tss_hooks.hpp>
|
||||
|
||||
@@ -38,7 +38,8 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
#if (__MINGW32_MAJOR_VERSION >3) || ((__MINGW32_MAJOR_VERSION==3) && (__MINGW32_MINOR_VERSION>=18))
|
||||
#if defined(__MINGW64__) || (__MINGW32_MAJOR_VERSION >3) || \
|
||||
((__MINGW32_MAJOR_VERSION==3) && (__MINGW32_MINOR_VERSION>=18))
|
||||
extern "C"
|
||||
{
|
||||
PIMAGE_TLS_CALLBACK __crt_xl_tls_callback__ __attribute__ ((section(".CRT$XLB"))) = on_tls_callback;
|
||||
|
||||
Reference in New Issue
Block a user