2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-09 23:42:18 +00:00

Thread: Added promise::set_..._at_thread_exit

[SVN r81172]
This commit is contained in:
Vicente J. Botet Escriba
2012-11-04 16:47:02 +00:00
parent 18491c933d
commit 315af061cd
14 changed files with 952 additions and 133 deletions

View File

@@ -18,6 +18,7 @@
#include <boost/thread/tss.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/thread/detail/tss_hooks.hpp>
#include <boost/thread/future.hpp>
#include <boost/assert.hpp>
#include <boost/throw_exception.hpp>
@@ -37,16 +38,20 @@ namespace boost
{
thread_data_base::~thread_data_base()
{
{
for (notify_list_t::iterator i = notify.begin(), e = notify.end();
i != e; ++i)
{
i->second->unlock();
i->first->notify_all();
}
}
for (async_states_t::iterator i = async_states_.begin(), e = async_states_.end();
i != e; ++i)
{
(*i)->make_ready();
}
}
}
namespace
{
#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
@@ -76,15 +81,6 @@ namespace boost
}
}
detail::thread_data_base* get_current_thread_data()
{
if(current_thread_tls_key==TLS_OUT_OF_INDEXES)
{
return 0;
}
return (detail::thread_data_base*)TlsGetValue(current_thread_tls_key);
}
void set_current_thread_data(detail::thread_data_base* new_data)
{
boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key);
@@ -99,6 +95,20 @@ namespace boost
}
}
}
namespace detail
{
thread_data_base* get_current_thread_data()
{
if(current_thread_tls_key==TLS_OUT_OF_INDEXES)
{
return 0;
}
return (detail::thread_data_base*)TlsGetValue(current_thread_tls_key);
}
}
namespace
{
#ifndef BOOST_HAS_THREADEX
// Windows CE doesn't define _beginthreadex
@@ -157,7 +167,7 @@ namespace boost
{
void run_thread_exit_callbacks()
{
detail::thread_data_ptr current_thread_data(get_current_thread_data(),false);
detail::thread_data_ptr current_thread_data(detail::get_current_thread_data(),false);
if(current_thread_data)
{
while(! current_thread_data->tss_data.empty() || current_thread_data->thread_exit_callbacks)
@@ -295,11 +305,11 @@ namespace boost
detail::thread_data_base* get_or_make_current_thread_data()
{
detail::thread_data_base* current_thread_data(get_current_thread_data());
detail::thread_data_base* current_thread_data(detail::get_current_thread_data());
if(!current_thread_data)
{
make_external_thread_data();
current_thread_data=get_current_thread_data();
current_thread_data=detail::get_current_thread_data();
}
return current_thread_data;
}
@@ -487,10 +497,10 @@ namespace boost
handles[handle_count++]=handle_to_wait_for;
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
if(get_current_thread_data() && get_current_thread_data()->interruption_enabled)
if(detail::get_current_thread_data() && detail::get_current_thread_data()->interruption_enabled)
{
interruption_index=handle_count;
handles[handle_count++]=get_current_thread_data()->interruption_handle;
handles[handle_count++]=detail::get_current_thread_data()->interruption_handle;
}
#endif
detail::win32::handle_manager timer_handle;
@@ -547,7 +557,7 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
else if(notified_index==interruption_index)
{
detail::win32::ResetEvent(get_current_thread_data()->interruption_handle);
detail::win32::ResetEvent(detail::get_current_thread_data()->interruption_handle);
throw thread_interrupted();
}
#endif
@@ -584,19 +594,19 @@ namespace boost
{
if(interruption_enabled() && interruption_requested())
{
detail::win32::ResetEvent(get_current_thread_data()->interruption_handle);
detail::win32::ResetEvent(detail::get_current_thread_data()->interruption_handle);
throw thread_interrupted();
}
}
bool interruption_enabled() BOOST_NOEXCEPT
{
return get_current_thread_data() && get_current_thread_data()->interruption_enabled;
return detail::get_current_thread_data() && detail::get_current_thread_data()->interruption_enabled;
}
bool interruption_requested() BOOST_NOEXCEPT
{
return get_current_thread_data() && (detail::win32::WaitForSingleObject(get_current_thread_data()->interruption_handle,0)==0);
return detail::get_current_thread_data() && (detail::win32::WaitForSingleObject(detail::get_current_thread_data()->interruption_handle,0)==0);
}
#endif
@@ -611,15 +621,15 @@ namespace boost
{
if(interruption_was_enabled)
{
get_current_thread_data()->interruption_enabled=false;
detail::get_current_thread_data()->interruption_enabled=false;
}
}
disable_interruption::~disable_interruption() BOOST_NOEXCEPT
{
if(get_current_thread_data())
if(detail::get_current_thread_data())
{
get_current_thread_data()->interruption_enabled=interruption_was_enabled;
detail::get_current_thread_data()->interruption_enabled=interruption_was_enabled;
}
}
@@ -627,15 +637,15 @@ namespace boost
{
if(d.interruption_was_enabled)
{
get_current_thread_data()->interruption_enabled=true;
detail::get_current_thread_data()->interruption_enabled=true;
}
}
restore_interruption::~restore_interruption() BOOST_NOEXCEPT
{
if(get_current_thread_data())
if(detail::get_current_thread_data())
{
get_current_thread_data()->interruption_enabled=false;
detail::get_current_thread_data()->interruption_enabled=false;
}
}
}
@@ -734,7 +744,7 @@ namespace boost
BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk)
{
detail::thread_data_base* const current_thread_data(get_current_thread_data());
detail::thread_data_base* const current_thread_data(detail::get_current_thread_data());
if(current_thread_data)
{
current_thread_data->notify_all_at_thread_exit(&cond, lk.release());