|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r84717 - in branches/release: boost/thread boost/thread/win32 libs/thread libs/thread/doc libs/thread/src/win32 libs/thread/test/sync/futures/promise libs/thread/test/threads/thread/constr
From: vicente.botet_at_[hidden]
Date: 2013-06-09 13:18:15
Author: viboes
Date: 2013-06-09 13:18:15 EDT (Sun, 09 Jun 2013)
New Revision: 84717
URL: http://svn.boost.org/trac/boost/changeset/84717
Log:
Thread: fix #8550, #8671, #8672.
Added:
branches/release/boost/thread/win32/mfc_thread_init.hpp
- copied unchanged from r84684, trunk/boost/thread/win32/mfc_thread_init.hpp
Properties modified:
branches/release/boost/thread/ (props changed)
branches/release/libs/thread/ (props changed)
Text files modified:
branches/release/boost/thread/future.hpp | 27 ++++++++++----------
branches/release/boost/thread/win32/mfc_thread_init.hpp | 41 ++++++++++++++++++++++++++++++++
branches/release/libs/thread/doc/changes.qbk | 3 ++
branches/release/libs/thread/src/win32/tss_pe.cpp | 41 ++++++++++++++++++++++++++++++++
branches/release/libs/thread/test/sync/futures/promise/set_exception_at_thread_exit_pass.cpp | 19 +++++++++++---
branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_const_pass.cpp | 25 ++++++++++++++++---
branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp | 4 ++
branches/release/libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp | 51 ++++++++++++++++++++++++++++++++++++++++
8 files changed, 189 insertions(+), 22 deletions(-)
Modified: branches/release/boost/thread/future.hpp
==============================================================================
--- branches/release/boost/thread/future.hpp Sun Jun 9 12:18:38 2013 (r84716)
+++ branches/release/boost/thread/future.hpp 2013-06-09 13:18:15 EDT (Sun, 09 Jun 2013) (r84717)
@@ -443,6 +443,7 @@
throw_exception(promise_already_satisfied());
}
exception=e;
+ this->is_constructed = true;
get_current_thread_data()->make_ready_at_thread_exit(shared_from_this());
}
bool has_value()
@@ -1746,7 +1747,7 @@
{
boost::unique_lock<boost::mutex> lock(future_->mutex);
- if(!future_->done)
+ if(!future_->done && !future_->is_constructed)
{
future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
}
@@ -1915,7 +1916,7 @@
{
boost::unique_lock<boost::mutex> lock(future_->mutex);
- if(!future_->done)
+ if(!future_->done && !future_->is_constructed)
{
future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
}
@@ -2057,7 +2058,7 @@
{
boost::unique_lock<boost::mutex> lock(future_->mutex);
- if(!future_->done)
+ if(!future_->done && !future_->is_constructed)
{
future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
}
@@ -3469,7 +3470,7 @@
boost::thread thr_;
public:
- explicit future_async_continuation(
+ future_async_continuation(
F& f, BOOST_THREAD_FWD_REF(Fp) c
) :
parent(f.future_),
@@ -3532,15 +3533,15 @@
struct future_async_continuation<F, void, Fp>: public future_object<void>
{
typedef future_object<void> base_type;
- F& parent;
+ F parent;
Fp continuation;
boost::thread thr_;
public:
- explicit future_async_continuation(
+ future_async_continuation(
F& f, BOOST_THREAD_FWD_REF(Fp) c
) :
- parent(f),
+ parent(f.future_),
continuation(boost::move(c)),
thr_()
{
@@ -3590,14 +3591,14 @@
struct future_deferred_continuation: future_object<Rp>
{
typedef future_object<Rp> base_type;
- F& parent;
+ F parent;
Fp continuation;
public:
- explicit future_deferred_continuation(
+ future_deferred_continuation(
F& f, BOOST_THREAD_FWD_REF(Fp) c
) :
- parent(f),
+ parent(f.future_),
//continuation(boost::move(c))
continuation(c)
{
@@ -3625,14 +3626,14 @@
struct future_deferred_continuation<F,void,Fp>: future_object<void>
{
typedef future_object<void> base_type;
- F& parent;
+ F parent;
Fp continuation;
public:
- explicit future_deferred_continuation(
+ future_deferred_continuation(
F& f, BOOST_THREAD_FWD_REF(Fp) c
):
- parent(f),
+ parent(f.future_),
continuation(boost::move(c))
{
this->set_deferred();
Copied: branches/release/boost/thread/win32/mfc_thread_init.hpp (from r84684, trunk/boost/thread/win32/mfc_thread_init.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/boost/thread/win32/mfc_thread_init.hpp 2013-06-09 13:18:15 EDT (Sun, 09 Jun 2013) (r84717, copy of r84684, trunk/boost/thread/win32/mfc_thread_init.hpp)
@@ -0,0 +1,41 @@
+#ifndef BOOST_THREAD_WIN32_MFC_THREAD_INIT_HPP
+#define BOOST_THREAD_WIN32_MFC_THREAD_INIT_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 2008 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+
+// check if we use MFC
+#ifdef _AFXDLL
+# if defined(_AFXEXT)
+
+// can't use ExtRawDllMain from afxdllx.h as it also defines the symbol _pRawDllMain
+extern "C"
+inline BOOL WINAPI ExtRawDllMain(HINSTANCE, DWORD dwReason, LPVOID)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ // save critical data pointers before running the constructors
+ AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
+ pModuleState->m_pClassInit = pModuleState->m_classList;
+ pModuleState->m_pFactoryInit = pModuleState->m_factoryList;
+ pModuleState->m_classList.m_pHead = NULL;
+ pModuleState->m_factoryList.m_pHead = NULL;
+ }
+ return TRUE; // ok
+}
+
+extern "C" __declspec(selectany) BOOL (WINAPI * const _pRawDllMainOrig)(HANDLE, DWORD, LPVOID) = &ExtRawDllMain;
+
+# elif defined(_USRDLL)
+
+extern "C" BOOL WINAPI RawDllMain(HANDLE, DWORD dwReason, LPVOID);
+extern "C" __declspec(selectany) BOOL (WINAPI * const _pRawDllMainOrig)(HANDLE, DWORD, LPVOID) = &RawDllMain;
+
+# endif
+#endif
+
+
+#endif
Modified: branches/release/libs/thread/doc/changes.qbk
==============================================================================
--- branches/release/libs/thread/doc/changes.qbk Sun Jun 9 12:18:38 2013 (r84716)
+++ branches/release/libs/thread/doc/changes.qbk 2013-06-09 13:18:15 EDT (Sun, 09 Jun 2013) (r84717)
@@ -53,10 +53,13 @@
* [@http://svn.boost.org/trac/boost/ticket/8443 #8443] Header file inclusion order may cause crashes
* [@http://svn.boost.org/trac/boost/ticket/8451 #8451] Missing documented function 'boost::scoped_thread::joinable'
* [@http://svn.boost.org/trac/boost/ticket/8530 #8530] [Coverity] Unused variable thread_handle, uninitialized variable cond_mutex in thread/pthread/thread_data.hpp
+* [@http://svn.boost.org/trac/boost/ticket/8550 #8550] static linking of Boost.Thread with an MFC-Dll
* [@http://svn.boost.org/trac/boost/ticket/8576 #8576] "sur parolle" should be "sur parole".
* [@http://svn.boost.org/trac/boost/ticket/8596 #8596] With C++0x enabled, boost::packaged_task stores a reference to function objects, instead of a copy.
* [@http://svn.boost.org/trac/boost/ticket/8626 #8626] Reintroduce BOOST_VERIFY on pthread_mutex_destroy return type
* [@http://svn.boost.org/trac/boost/ticket/8645 #8645] Typo in Strict lock definition
+* [@http://svn.boost.org/trac/boost/ticket/8671 #8671] promise: set_..._at_thread_exit
+* [@http://svn.boost.org/trac/boost/ticket/8672 #8672] future<>::then(void()) doesn't works
[heading Version 4.0.0 - boost 1.53]
Modified: branches/release/libs/thread/src/win32/tss_pe.cpp
==============================================================================
--- branches/release/libs/thread/src/win32/tss_pe.cpp Sun Jun 9 12:18:38 2013 (r84716)
+++ branches/release/libs/thread/src/win32/tss_pe.cpp 2013-06-09 13:18:15 EDT (Sun, 09 Jun 2013) (r84717)
@@ -80,6 +80,36 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+
+// _pRawDllMainOrig can be defined by including boost/thread/win32/mfc_thread_init.hpp
+// into your dll; it ensures that MFC-Dll-initialization will be done properly
+// The following code is adapted from the MFC-Dll-init code
+/*
+ * _pRawDllMainOrig MUST be an extern const variable, which will be aliased to
+ * _pDefaultRawDllMainOrig if no real user definition is present, thanks to the
+ * alternatename directive.
+ */
+
+// work at least with _MSC_VER 1500 (MSVC++ 9.0, VS 2008)
+#if (_MSC_VER >= 1500)
+
+extern "C" {
+extern BOOL (WINAPI * const _pRawDllMainOrig)(HANDLE, DWORD, LPVOID);
+extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NULL;
+#if defined (_M_IX86)
+#pragma comment(linker, "/alternatename:__pRawDllMainOrig=__pDefaultRawDllMainOrig")
+#elif defined (_M_X64) || defined (_M_ARM)
+#pragma comment(linker, "/alternatename:_pRawDllMainOrig=_pDefaultRawDllMainOrig")
+#else /* defined (_M_X64) || defined (_M_ARM) */
+#error Unsupported platform
+#endif /* defined (_M_X64) || defined (_M_ARM) */
+}
+
+#endif
+
+
+
+
//Definitions required by implementation
#if (_MSC_VER < 1300) // 1300 == VC++ 7.0
@@ -240,7 +270,11 @@
}
}
+#if (_MSC_VER >= 1500)
+ BOOL WINAPI dll_callback(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved)
+#else
BOOL WINAPI dll_callback(HANDLE, DWORD dwReason, LPVOID)
+#endif
{
switch (dwReason)
{
@@ -251,6 +285,13 @@
boost::on_process_exit();
break;
}
+
+#if (_MSC_VER >= 1500)
+ if( _pRawDllMainOrig )
+ {
+ return _pRawDllMainOrig(hInstance, dwReason, lpReserved);
+ }
+#endif
return true;
}
} //namespace
Modified: branches/release/libs/thread/test/sync/futures/promise/set_exception_at_thread_exit_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/promise/set_exception_at_thread_exit_pass.cpp Sun Jun 9 12:18:38 2013 (r84716)
+++ branches/release/libs/thread/test/sync/futures/promise/set_exception_at_thread_exit_pass.cpp 2013-06-09 13:18:15 EDT (Sun, 09 Jun 2013) (r84717)
@@ -44,10 +44,14 @@
}
}
-//void func(boost::promise<int> p)
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+void func(boost::promise<int> p)
+#else
boost::promise<int> p;
void func()
+#endif
{
+ //p.set_exception(boost::make_exception_ptr(3));
p.set_exception_at_thread_exit(boost::make_exception_ptr(3));
}
@@ -55,10 +59,14 @@
{
{
typedef int T;
- //boost::promise<T> p;
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ boost::thread(func, boost::move(p)).detach();
+#else
boost::future<T> f = p.get_future();
- //boost::thread(func, boost::move(p)).detach();
boost::thread(func).detach();
+#endif
try
{
f.get();
@@ -77,9 +85,12 @@
typedef int T;
boost::promise<T> p2;
boost::future<T> f = p2.get_future();
- //boost::thread(func, boost::move(p)).detach();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func, boost::move(p2)).detach();
+#else
p = boost::move(p2);
boost::thread(func).detach();
+#endif
try
{
f.get();
Modified: branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_const_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_const_pass.cpp Sun Jun 9 12:18:38 2013 (r84716)
+++ branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_const_pass.cpp 2013-06-09 13:18:15 EDT (Sun, 09 Jun 2013) (r84717)
@@ -23,9 +23,12 @@
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+void func(boost::promise<int> p)
+#else
boost::promise<int> p;
-//void func(boost::promise<int> p)
void func()
+#endif
{
const int i = 5;
p.set_value_at_thread_exit(i);
@@ -34,18 +37,32 @@
int main()
{
{
- //boost::promise<int> p;
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::promise<int> p;
+ boost::future<int> f = p.get_future();
+ boost::thread(func, boost::move(p)).detach();
+#else
boost::future<int> f = p.get_future();
- //boost::thread(func, boost::move(p)).detach();
boost::thread(func).detach();
- BOOST_TEST(f.get() == 5);
+#endif
+ try
+ {
+ BOOST_TEST(f.get() == 5);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
}
{
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
boost::promise<int> p2;
boost::future<int> f = p2.get_future();
p = boost::move(p2);
boost::thread(func).detach();
BOOST_TEST(f.get() == 5);
+#endif
}
return boost::report_errors();
}
Modified: branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp Sun Jun 9 12:18:38 2013 (r84716)
+++ branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp 2013-06-09 13:18:15 EDT (Sun, 09 Jun 2013) (r84717)
@@ -32,7 +32,8 @@
i = 1;
}
-void func2_mv(BOOST_THREAD_RV_REF(boost::promise<void>) p2)
+//void func2_mv(BOOST_THREAD_RV_REF(boost::promise<void>) p2)
+void func2_mv(boost::promise<void> p2)
{
p2.set_value_at_thread_exit();
i = 2;
@@ -92,6 +93,7 @@
boost::thread(func2, &p2).detach();
#endif
f.wait();
+ f.get();
BOOST_TEST(i == 2);
}
catch(std::exception& ex)
Modified: branches/release/libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp Sun Jun 9 12:18:38 2013 (r84716)
+++ branches/release/libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp 2013-06-09 13:18:15 EDT (Sun, 09 Jun 2013) (r84717)
@@ -40,6 +40,51 @@
}
};
+class M
+{
+
+public:
+ long data_;
+ static int n_moves;
+
+ BOOST_THREAD_MOVABLE_ONLY(M)
+ static void reset() {
+ n_moves=0;
+ }
+ explicit M(long i) : data_(i)
+ {
+ }
+ M(BOOST_THREAD_RV_REF(M) a) : data_(BOOST_THREAD_RV(a).data_)
+ {
+ BOOST_THREAD_RV(a).data_ = -1;
+ ++n_moves;
+ }
+ M& operator=(BOOST_THREAD_RV_REF(M) a)
+ {
+ data_ = BOOST_THREAD_RV(a).data_;
+ BOOST_THREAD_RV(a).data_ = -1;
+ ++n_moves;
+ return *this;
+ }
+ ~M()
+ {
+ }
+
+ void operator()(int) const
+ { }
+ long operator()() const
+ { return data_;}
+ long operator()(long i, long j) const
+ { return data_ + i + j;}
+};
+
+int M::n_moves = 0;
+
+void fct(BOOST_THREAD_RV_REF(M) v)
+{
+ BOOST_TEST_EQ(v.data_, 1);
+}
+
int main()
{
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
@@ -47,6 +92,12 @@
boost::thread t = boost::thread( MoveOnly(), MoveOnly() );
t.join();
}
+ {
+ M::reset();
+ boost::thread t = boost::thread( fct, M(1) );
+ t.join();
+ BOOST_TEST_EQ(M::n_moves, 2);
+ }
#endif
return boost::report_errors();
}
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