Index: boost/thread/pthread/condition_variable_fwd.hpp =================================================================== --- boost/thread/pthread/condition_variable_fwd.hpp (revision 80241) +++ boost/thread/pthread/condition_variable_fwd.hpp (working copy) @@ -229,8 +229,11 @@ unique_lock& lock, struct timespec const &timeout); }; + + void notify_all_at_thread_exit(condition_variable& cond, unique_lock lk); } + #include #endif Index: boost/thread/pthread/thread_data.hpp =================================================================== --- boost/thread/pthread/thread_data.hpp (revision 80241) +++ boost/thread/pthread/thread_data.hpp (working copy) @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -117,6 +118,7 @@ typedef pthread_t native_handle_type; virtual void run()=0; + virtual void notify_all_at_thread_exit(condition_variable*, mutex*)=0; }; BOOST_THREAD_DECL thread_data_base* get_current_thread_data(); Index: boost/thread/detail/thread.hpp =================================================================== --- boost/thread/detail/thread.hpp (revision 80241) +++ boost/thread/detail/thread.hpp (working copy) @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -73,6 +75,24 @@ { f(); } + typedef std::vector + //, hidden_allocator > + > notify_list_t; + notify_list_t notify; + void notify_all_at_thread_exit(condition_variable* cv, mutex* m) + { + notify.push_back(std::pair(cv, m)); + } + ~thread_data() + { + for (notify_list_t::iterator i = notify.begin(), e = notify.end(); + i != e; ++i) + { + i->second->unlock(); + i->first->notify_all(); + } + + } private: F f; }; @@ -92,6 +112,14 @@ { f(); } + typedef std::vector + //, hidden_allocator > + > notify_list_t; + notify_list_t notify; + void notify_all_at_thread_exit(condition_variable* cv, mutex* m) + { + notify.push_back(std::pair(cv, m)); + } }; template @@ -109,6 +137,14 @@ { f(); } + typedef std::vector + //, hidden_allocator > + > notify_list_t; + notify_list_t notify; + void notify_all_at_thread_exit(condition_variable* cv, mutex* m) + { + notify.push_back(std::pair(cv, m)); + } }; } Index: boost/thread/win32/condition_variable.hpp =================================================================== --- boost/thread/win32/condition_variable.hpp (revision 80241) +++ boost/thread/win32/condition_variable.hpp (working copy) @@ -510,6 +510,7 @@ #endif }; + void notify_all_at_thread_exit(condition_variable& cond, unique_lock lk); } #include Index: boost/thread/win32/thread_data.hpp =================================================================== --- boost/thread/win32/thread_data.hpp (revision 80241) +++ boost/thread/win32/thread_data.hpp (working copy) @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #ifdef BOOST_THREAD_USES_CHRONO #include @@ -117,6 +119,8 @@ typedef detail::win32::handle native_handle_type; virtual void run()=0; + virtual void notify_all_at_thread_exit(condition_variable*, mutex*)=0; + }; typedef boost::intrusive_ptr thread_data_ptr; Index: libs/thread/test/threads/thread/members/detach_pass.cpp =================================================================== --- libs/thread/test/threads/thread/members/detach_pass.cpp (revision 80241) +++ libs/thread/test/threads/thread/members/detach_pass.cpp (working copy) @@ -17,6 +17,8 @@ // void detach(); +#define BOOST_THREAD_VESRION 3 + #include #include #include Index: libs/thread/test/sync/conditions/notify_all_at_thread_exit_pass.cpp =================================================================== --- libs/thread/test/sync/conditions/notify_all_at_thread_exit_pass.cpp (revision 0) +++ libs/thread/test/sync/conditions/notify_all_at_thread_exit_pass.cpp (revision 0) @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// 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) + +// + +// void notify_all_at_thread_exit(condition_variable& cond, unique_lock lk); + +#define BOOST_THREAD_USES_MOVE +#define BOOST_THREAD_VESRION 3 + +#include +#include +#include +#include +#include +#include + +boost::condition_variable cv; +boost::mutex mut; + +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::high_resolution_clock Clock; + +void func() +{ + boost::unique_lock < boost::mutex > lk(mut); + boost::notify_all_at_thread_exit(cv, boost::move(lk)); + boost::this_thread::sleep_for(ms(300)); +} + +int main() +{ + boost::unique_lock < boost::mutex > lk(mut); + boost::thread(func).detach(); + Clock::time_point t0 = Clock::now(); + cv.wait(lk); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(t1 - t0 > ms(250)); + return boost::report_errors(); +} + Property changes on: libs/thread/test/sync/conditions/notify_all_at_thread_exit_pass.cpp ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + Id Added: svn:eol-style + native Index: libs/thread/test/Jamfile.v2 =================================================================== --- libs/thread/test/Jamfile.v2 (revision 80241) +++ libs/thread/test/Jamfile.v2 (working copy) @@ -225,6 +225,7 @@ [ thread-run2 ./sync/conditions/condition_variable_any/wait_until_pass.cpp : condition_variable_any__wait_until_p ] [ thread-run2 ./sync/conditions/condition_variable_any/wait_until_pred_pass.cpp : condition_variable_any__wait_until_pred_p ] [ thread-run2 ./sync/conditions/cv_status/cv_status_pass.cpp : cv_status__cv_status_p ] + [ thread-run2 ./sync/conditions/notify_all_at_thread_exit_pass.cpp : notify_all_at_thread_exit_p ] ; explicit ts_async ; Index: libs/thread/src/win32/thread.cpp =================================================================== --- libs/thread/src/win32/thread.cpp (revision 80241) +++ libs/thread/src/win32/thread.cpp (working copy) @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -240,6 +241,9 @@ void run() {} + void notify_all_at_thread_exit(condition_variable*, mutex*) + {} + private: externally_launched_thread(externally_launched_thread&); void operator=(externally_launched_thread&); @@ -682,6 +686,14 @@ boost::run_thread_exit_callbacks(); } + void notify_all_at_thread_exit(condition_variable& cond, unique_lock lk) + { + 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()); + } + } } Index: libs/thread/src/pthread/thread.cpp =================================================================== --- libs/thread/src/pthread/thread.cpp (revision 80241) +++ libs/thread/src/pthread/thread.cpp (working copy) @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include #include @@ -175,6 +175,8 @@ void run() {} + void notify_all_at_thread_exit(condition_variable*, mutex*) + {} private: externally_launched_thread(externally_launched_thread&); @@ -677,6 +679,15 @@ } } } + void notify_all_at_thread_exit(condition_variable& cond, unique_lock lk) + { + 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()); + } + } + }