Portable C++ multi-threading. C++11, C++14.
Distributed under the Boost Software License, Version 1.0.
Boost.org thread module
Home Page: http://boost.org/libs/thread
Portable C++ multi-threading. C++11, C++14.
Distributed under the Boost Software License, Version 1.0.
Since I can't reopen #156 and @viboes closed it without even looking into it I have to make a new one.
The problem here is that boost has a hardcoded check for libpthreadGC2.a, when mingw-w64's runtime provides a posix thread library in the same naming and usage scheme, requiring no extra work on that part. You guys should take advantage of it, so end users won't have to install another otherwise unneeded dependency when a perfectly good pthreads implementation is already available in their toolchain.
This is a Boost.Thread issue, it lives in your build files, and it is not invalid.
Clang output:
-c src/pthread/thread.cpp
In file included from src/pthread/thread.cpp:17:
In file included from include/boost/thread/once.hpp:20:
include/boost/thread/pthread/once_atomic.hpp:91:5: error: unknown type name 'BOOST_THREAD_ATTRIBUTE_MAY_ALIAS'
BOOST_THREAD_ATTRIBUTE_MAY_ALIAS thread_detail::atomic_int_type storage;
^
include/boost/thread/pthread/once_atomic.hpp:91:53: error: non-friend class member 'atomic_int_type' cannot have a qualified name
BOOST_THREAD_ATTRIBUTE_MAY_ALIAS thread_detail::atomic_int_type storage;
~~~~~~~~~~~~~~~^
include/boost/thread/pthread/once_atomic.hpp:91:68: error: expected ';' at end of declaration list
BOOST_THREAD_ATTRIBUTE_MAY_ALIAS thread_detail::atomic_int_type storage;
^
include/boost/thread/pthread/once_atomic.hpp:100:52: error: no member named 'storage' in 'boost::once_flag'
return reinterpret_cast< atomic_type& >(flag.storage);
~~~~ ^
See these lines https://github.com/boostorg/thread/blob/develop/include/boost/thread/detail/config.hpp#L20
It's suspicious that in #ifndef
we define macro to nothing and then instantly set it to MAY_ALIAS
.
Maybe there's missing #else
?
I have a custom build (b2 is not used), so it's possible that I could miss some flags set.
Ticketing http://lists.boost.org/boost-users/2015/12/85442.php: boost::thread_specific_ptr
currently declares its copy members privately which prevents moveability.
From what I can tell, a move should be possible along the lines of:
auto* p = other.release(); // without invoking other's cleanup fn
reset(p); // potentially different cleanup fn associated
The only problematic situation I can think of is a scenario with two
semantically different custom cleanup function where a move eventually
triggers only the second one. But this is behavior is consistent with
move semantic.
/cc @viboes
sync_queue has not push_back but doc has
I'm trying to compile simple code using boost:synchronized_value with boost::synchronize but i'm having problems doing that:
#include <iostream>
#include <boost\thread\synchronized_value.hpp>
int main()
{
boost::synchronized_value<int> val1 = 10;
boost::synchronized_value<int> val2 = 20;
auto tuple = boost::synchronize(val1, val2);
std::cout << *std::get<0>(tuple) << *std::get<1>(tuple) << "\n";
return 0;
}
will result in this error:
boost::mutex::mutex(const boost::mutex &)" : Es wurde versucht, auf eine gelöschte Funktion zu verweisen
(use of deleted function)
What i have found out is that this only happens with MSVC++ compilers and only with /std:c++17
if i try to use c++14 it will compile fine, but i want to use c++17 features.
I installed boost with vcpkg if that matters.
May be related to trac #13069.
Deadlock requires end-task to continue tests.
Produced in 3222938 with 2017.4 preview, suspect also occurs in 2017.3. Tested in debug, address-model=64. All Threads appear to be stuck on thread.cpp line 741.
unsigned long const notified_index=detail::win32::WaitForMultipleObjectsEx(handle_count,handles,false,using_timer?INFINITE:time_left.milliseconds, 0);
Stack frame of primary thread is
> boost_thread-vc141-mt-gd-1_65.dll!boost::this_thread::interruptible_wait(void * handle_to_wait_for, boost::detail::timeout target_time) Line 741 C++ Symbols loaded.
boost_thread-vc141-mt-gd-1_65.dll!boost::thread::join_noexcept() Line 453 C++ Symbols loaded.
sync_pq_multi_thread_p.exe!boost::thread::join() Line 775 C++ Symbols loaded.
sync_pq_multi_thread_p.exe!boost::thread_group::join_all() Line 120 C++ Symbols loaded.
sync_pq_multi_thread_p.exe!compute_sum(const int n) Line 139 C++ Symbols loaded.
sync_pq_multi_thread_p.exe!main() Line 209 C++ Symbols loaded.
Stack frame of a worker thread is:
> boost_thread-vc141-mt-gd-1_65.dll!boost::this_thread::interruptible_wait(void * handle_to_wait_for, boost::detail::timeout target_time) Line 741 C++ Symbols loaded.
sync_pq_multi_thread_p.exe!boost::detail::basic_cv_list_entry::wait(boost::detail::timeout abs_time) Line 95 C++ Symbols loaded.
sync_pq_multi_thread_p.exe!boost::detail::basic_condition_variable::do_wait<boost::unique_lock<boost::mutex> >(boost::unique_lock<boost::mutex> & lock, boost::detail::timeout abs_time) Line 245 C++ Symbols loaded.
sync_pq_multi_thread_p.exe!boost::condition_variable::wait(boost::unique_lock<boost::mutex> & m) Line 339 C++ Symbols loaded.
sync_pq_multi_thread_p.exe!boost::concurrent::detail::sync_queue_base<int,boost::detail::priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> > >::wait_until_not_empty(boost::unique_lock<boost::mutex> & lk) Line 191 C++ Symbols loaded.
sync_pq_multi_thread_p.exe!boost::concurrent::sync_priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> >::pull() Line 251 C++ Symbols loaded.
sync_pq_multi_thread_p.exe!atomic_pull(boost::concurrent::sync_priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> > * q, boost::atomics::atomic<int> * sum) Line 105 C++ Symbols loaded.
sync_pq_multi_thread_p.exe!boost::_bi::list2<boost::_bi::value<boost::concurrent::sync_priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> > * __ptr64>,boost::_bi::value<boost::atomics::atomic<int> * __ptr64> >::operator()<void (__cdecl*)(boost::concurrent::sync_priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> > * __ptr64,boost::atomics::atomic<int> * __ptr64),boost::_bi::list0>(boost::_bi::type<void> __formal, void(*)(boost::concurrent::sync_priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> > *, boost::atomics::atomic<int> *) & f, boost::_bi::list0 & a, int __formal) Line 320 C++ Symbols loaded.
sync_pq_multi_thread_p.exe!boost::_bi::bind_t<void,void (__cdecl*)(boost::concurrent::sync_priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> > * __ptr64,boost::atomics::atomic<int> * __ptr64),boost::_bi::list2<boost::_bi::value<boost::concurrent::sync_priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> > * __ptr64>,boost::_bi::value<boost::atomics::atomic<int> * __ptr64> > >::operator()() Line 1295 C++ Symbols loaded.
sync_pq_multi_thread_p.exe!boost::detail::invoke<boost::_bi::bind_t<void,void (__cdecl*)(boost::concurrent::sync_priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> > * __ptr64,boost::atomics::atomic<int> * __ptr64),boost::_bi::list2<boost::_bi::value<boost::concurrent::sync_priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> > * __ptr64>,boost::_bi::value<boost::atomics::atomic<int> * __ptr64> > > >(boost::_bi::bind_t<void,void (__cdecl*)(boost::concurrent::sync_priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> > *,boost::atomics::atomic<int> *),boost::_bi::list2<boost::_bi::value<boost::concurrent::sync_priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> > *>,boost::_bi::value<boost::atomics::atomic<int> *> > > && f) Line 135 C++ Symbols loaded.
sync_pq_multi_thread_p.exe!boost::detail::thread_data<boost::_bi::bind_t<void,void (__cdecl*)(boost::concurrent::sync_priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> > * __ptr64,boost::atomics::atomic<int> * __ptr64),boost::_bi::list2<boost::_bi::value<boost::concurrent::sync_priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> > * __ptr64>,boost::_bi::value<boost::atomics::atomic<int> * __ptr64> > > >::run2<>(boost::detail::tuple_indices<> __formal) Line 76 C++ Symbols loaded.
sync_pq_multi_thread_p.exe!boost::detail::thread_data<boost::_bi::bind_t<void,void (__cdecl*)(boost::concurrent::sync_priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> > * __ptr64,boost::atomics::atomic<int> * __ptr64),boost::_bi::list2<boost::_bi::value<boost::concurrent::sync_priority_queue<int,boost::container::vector<int,boost::container::new_allocator<int> >,std::less<int> > * __ptr64>,boost::_bi::value<boost::atomics::atomic<int> * __ptr64> > > >::run() Line 82 C++ Symbols loaded.
boost_thread-vc141-mt-gd-1_65.dll!boost::`anonymous namespace'::thread_start_function(void * param) Line 296 C++ Symbols loaded.
Dump/pdb/etc available, email me.
Microsoft Windows [Version 6.1.7601]
gcc (GCC) 6.4.0
Run from Boost.Thread test folder:
$ ../../../b2.exe -j2 toolset=gcc test_thread
Performing configuration checks
- 32-bit : no (cached)
- 64-bit : yes (cached)
- arm : no (cached)
- mips1 : no (cached)
- power : no (cached)
- sparc : no (cached)
- x86 : yes (cached)
- symlinks supported : yes (cached)
...patience...
...patience...
...found 3098 targets...
...updating 42 targets...
gcc.compile.c++ ..\..\..\bin.v2\libs\thread\test\test_thread.test\gcc-gnu-6.4.0\debug\threadapi-win32\threading-multi\test_thread.o
gcc.compile.c++ ..\..\..\bin.v2\libs\thread\test\test_thread.test\gcc-gnu-6.4.0\debug\threadapi-win32\threading-multi\winrt_init.o
gcc.compile.c++ ..\..\..\bin.v2\libs\thread\build\gcc-gnu-6.4.0\debug\threadapi-win32\threading-multi\win32\thread.o
..\..\..\libs\thread\src\win32\thread.cpp: In function ‘void boost::{anonymous}::create_current_thread_tls_key()’:
..\..\..\libs\thread\src\win32\thread.cpp:84:37: error: ‘tss_cleanup_implemented’ was not declared in this scope
tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in
^
..\..\..\libs\thread\src\win32\thread.cpp: In member function ‘bool boost::thread::start_thread_noexcept()’:
..\..\..\libs\thread\src\win32\thread.cpp:322:127: error: ‘struct boost::detail::thread_data_base’ has no member named ‘id’
uintptr_t const new_thread=_beginthreadex(0,0,&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
^~
..\..\..\libs\thread\src\win32\thread.cpp:323:13: error: in argument to unary !
if(!new_thread)
^~~~~~~~~~
..\..\..\libs\thread\src\win32\thread.cpp:327:48: error: ‘intrusive_ptr_add_ref’ was not declared in this scope
intrusive_ptr_add_ref(thread_info.get());
^
..\..\..\libs\thread\src\win32\thread.cpp:328:45: error: ‘boost::detail::win32’ has not been declared
thread_info->thread_handle=(detail::win32::handle)(new_thread);
^~~~~
..\..\..\libs\thread\src\win32\thread.cpp: In member function ‘bool boost::thread::start_thread_noexcept(const attributes&)’:
..\..\..\libs\thread\src\win32\thread.cpp:342:117: error: ‘struct boost::detail::thread_data_base’ has no member named ‘id’
CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, &thread_info->id);
^~
..\..\..\libs\thread\src\win32\thread.cpp:343:11: error: in argument to unary !
if(!new_thread)
^~~~~~~~~~
..\..\..\libs\thread\src\win32\thread.cpp:347:46: error: ‘intrusive_ptr_add_ref’ was not declared in this scope
intrusive_ptr_add_ref(thread_info.get());
^
..\..\..\libs\thread\src\win32\thread.cpp:348:43: error: ‘boost::detail::win32’ has not been declared
thread_info->thread_handle=(detail::win32::handle)(new_thread);
^~~~~
..\..\..\libs\thread\src\win32\thread.cpp: In constructor ‘boost::{anonymous}::externally_launched_thread::externally_launched_thread()’:
..\..\..\libs\thread\src\win32\thread.cpp:365:19: error: ‘count’ was not declared in this scope
++count;
^~~~~
..\..\..\libs\thread\src\win32\thread.cpp:365:19: note: suggested alternative:
In file included from /usr/lib/gcc/x86_64-pc-msys/6.4.0/include/c++/algorithm:62:0,
from ..\..\../boost/smart_ptr/shared_ptr.hpp:39,
from ..\..\../boost/shared_ptr.hpp:17,
from ..\..\../boost/date_time/time_clock.hpp:17,
from ..\..\../boost/thread/thread_time.hpp:9,
from ..\..\../boost/thread/lock_types.hpp:18,
from ..\..\../boost/thread/pthread/thread_data.hpp:12,
from ..\..\../boost/thread/thread_only.hpp:17,
from ..\..\..\libs\thread\src\win32\thread.cpp:11:
/usr/lib/gcc/x86_64-pc-msys/6.4.0/include/c++/bits/stl_algo.h:3961:5: note: ‘std::count’
count(_InputIterator __first, _InputIterator __last, const _Tp& __value)
^~~~~
..\..\..\libs\thread\src\win32\thread.cpp:367:17: error: ‘interruption_enabled’ was not declared in this scope
interruption_enabled=false;
^~~~~~~~~~~~~~~~~~~~
..\..\..\libs\thread\src\win32\thread.cpp:367:17: note: suggested alternative:
In file included from ..\..\../boost/thread/thread_only.hpp:22:0,
from ..\..\..\libs\thread\src\win32\thread.cpp:11:
..\..\../boost/thread/detail/thread.hpp:624:32: note: ‘boost::this_thread::interruption_enabled’
bool BOOST_THREAD_DECL interruption_enabled() BOOST_NOEXCEPT;
^~~~~~~~~~~~~~~~~~~~
..\..\..\libs\thread\src\win32\thread.cpp: At global scope:
..\..\..\libs\thread\src\win32\thread.cpp:414:16: error: redefinition of ‘boost::thread::id boost::thread::get_id() const’
thread::id thread::get_id() const BOOST_NOEXCEPT
^~~~~~
In file included from ..\..\../boost/thread/thread_only.hpp:22:0,
from ..\..\..\libs\thread\src\win32\thread.cpp:11:
..\..\../boost/thread/detail/thread.hpp:748:16: note: ‘boost::thread::id boost::thread::get_id() const’ previously defined here
thread::id thread::get_id() const BOOST_NOEXCEPT
^~~~~~
..\..\..\libs\thread\src\win32\thread.cpp: In member function ‘bool boost::thread::join_noexcept()’:
..\..\..\libs\thread\src\win32\thread.cpp:442:13: error: ‘interruptible_wait’ is not a member of ‘boost::this_thread’
this_thread::interruptible_wait(this->native_handle(),detail::timeout::sentinel());
^~~~~~~~~~~
..\..\..\libs\thread\src\win32\thread.cpp:442:75: error: ‘boost::detail::timeout’ has not been declared
this_thread::interruptible_wait(this->native_handle(),detail::timeout::sentinel());
^~~~~~~
..\..\..\libs\thread\src\win32\thread.cpp: At global scope:
..\..\..\libs\thread\src\win32\thread.cpp:453:10: error: redefinition of ‘bool boost::thread::timed_join(const system_time&)’
bool thread::timed_join(boost::system_time const& wait_until)
^~~~~~
In file included from ..\..\../boost/thread/thread_only.hpp:22:0,
from ..\..\..\libs\thread\src\win32\thread.cpp:11:
..\..\../boost/thread/detail/thread.hpp:540:14: note: ‘bool boost::thread::timed_join(const system_time&)’ previously defined here
bool timed_join(const system_time& abs_time)
^~~~~~~~~~
..\..\..\libs\thread\src\win32\thread.cpp:458:10: error: prototype for ‘bool boost::thread::do_try_join_until_noexcept(uintmax_t, bool&)’ does not match any in class ‘boost::thread’
bool thread::do_try_join_until_noexcept(uintmax_t milli, bool& res)
^~~~~~
In file included from ..\..\../boost/thread/thread_only.hpp:22:0,
from ..\..\..\libs\thread\src\win32\thread.cpp:11:
..\..\../boost/thread/detail/thread.hpp:536:14: error: candidate is: bool boost::thread::do_try_join_until_noexcept(const timespec&, bool&)
bool do_try_join_until_noexcept(struct timespec const &timeout, bool& res);
^~~~~~~~~~~~~~~~~~~~~~~~~~
..\..\..\libs\thread\src\win32\thread.cpp: In member function ‘void boost::thread::interrupt()’:
..\..\..\libs\thread\src\win32\thread.cpp:494:32: error: ‘struct boost::detail::thread_data_base’ has no member named ‘interrupt’
local_thread_info->interrupt();
^~~~~~~~~
..\..\..\libs\thread\src\win32\thread.cpp: In member function ‘bool boost::thread::interruption_requested() const’:
..\..\..\libs\thread\src\win32\thread.cpp:501:44: error: ‘winapi’ has not been declared
return local_thread_info.get() && (winapi::WaitForSingleObjectEx(local_thread_info->interruption_handle,0,0)==0);
^~~~~~
..\..\..\libs\thread\src\win32\thread.cpp:501:93: error: ‘struct boost::detail::thread_data_base’ has no member named ‘interruption_handle’; did you mean ‘interrupt_enabled’?
return local_thread_info.get() && (winapi::WaitForSingleObjectEx(local_thread_info->interruption_handle,0,0)==0);
^~~~~~~~~~~~~~~~~~~
..\..\..\libs\thread\src\win32\thread.cpp: In static member function ‘static unsigned int boost::thread::hardware_concurrency()’:
..\..\..\libs\thread\src\win32\thread.cpp:508:17: error: ‘boost::detail::win32’ has not been declared
detail::win32::system_info info;
^~~~~
..\..\..\libs\thread\src\win32\thread.cpp:509:17: error: ‘boost::detail::win32’ has not been declared
detail::win32::get_system_info(&info);
^~~~~
..\..\..\libs\thread\src\win32\thread.cpp:509:41: error: ‘info’ was not declared in this scope
detail::win32::get_system_info(&info);
^~~~
..\..\..\libs\thread\src\win32\thread.cpp: In member function ‘__pthread_t* boost::thread::native_handle()’:
..\..\..\libs\thread\src\win32\thread.cpp:547:28: error: ‘boost::detail::win32’ has not been declared
return detail::win32::invalid_handle_value;
^~~~~
..\..\..\libs\thread\src\win32\thread.cpp:553:25: error: ‘boost::detail::win32’ has not been declared
return (detail::win32::handle)local_thread_info->thread_handle;
^~~~~
..\..\..\libs\thread\src\win32\thread.cpp:553:39: error: expected ‘;’ before ‘local_thread_info’
return (detail::win32::handle)local_thread_info->thread_handle;
^~~~~~~~~~~~~~~~~
..\..\..\libs\thread\src\win32\thread.cpp: At global scope:
..\..\..\libs\thread\src\win32\thread.cpp:566:40: error: ‘timeout’ is not a member of ‘boost::detail’
LARGE_INTEGER get_due_time(detail::timeout const& target_time)
^~~~~~
..\..\..\libs\thread\src\win32\thread.cpp:567:13: error: expected ‘,’ or ‘;’ before ‘{’ token
{
^
..\..\..\libs\thread\src\win32\thread.cpp:1018:1: error: expected ‘}’ at end of input
}
^
..\..\..\libs\thread\src\win32\thread.cpp:1018:1: error: expected ‘}’ at end of input
..\..\..\libs\thread\src\win32\thread.cpp:1018:1: error: expected ‘}’ at end of input
In file included from ..\..\../boost/smart_ptr/shared_ptr.hpp:28:0,
from ..\..\../boost/shared_ptr.hpp:17,
from ..\..\../boost/date_time/time_clock.hpp:17,
from ..\..\../boost/thread/thread_time.hpp:9,
from ..\..\../boost/thread/lock_types.hpp:18,
from ..\..\../boost/thread/pthread/thread_data.hpp:12,
from ..\..\../boost/thread/thread_only.hpp:17,
from ..\..\..\libs\thread\src\win32\thread.cpp:11:
..\..\../boost/smart_ptr/detail/shared_count.hpp: In instantiation of ‘boost::detail::shared_count::shared_count(P, D) [with P = boost::detail::thread_data_base*; D = bool]’:
..\..\../boost/smart_ptr/shared_ptr.hpp:388:76: required from ‘boost::shared_ptr<T>::shared_ptr(Y*, D) [with Y = boost::detail::thread_data_base; D = bool; T = boost::detail::thread_data_base]’
..\..\..\libs\thread\src\win32\thread.cpp:255:96: required from here
..\..\../boost/smart_ptr/detail/shared_count.hpp:185:14: error: ‘d’ cannot be used as a function
d(p); // delete p
~^~~
In file included from ..\..\../boost/smart_ptr/detail/shared_count.hpp:30:0,
from ..\..\../boost/smart_ptr/shared_ptr.hpp:28,
from ..\..\../boost/shared_ptr.hpp:17,
from ..\..\../boost/date_time/time_clock.hpp:17,
from ..\..\../boost/thread/thread_time.hpp:9,
from ..\..\../boost/thread/lock_types.hpp:18,
from ..\..\../boost/thread/pthread/thread_data.hpp:12,
from ..\..\../boost/thread/thread_only.hpp:17,
from ..\..\..\libs\thread\src\win32\thread.cpp:11:
..\..\../boost/smart_ptr/detail/sp_counted_impl.hpp: In instantiation of ‘void boost::detail::sp_counted_impl_pd<P, D>::dispose() [with P = boost::detail::thread_data_base*; D = bool]’:
..\..\..\libs\thread\src\win32\thread.cpp:1018:1: required from here
..\..\../boost/smart_ptr/detail/sp_counted_impl.hpp:172:9: error: expression cannot be used as a function
del( ptr );
^~~
..\..\..\libs\thread\src\win32\thread.cpp:402:35: warning: ‘boost::detail::thread_data_base* boost::{anonymous}::get_or_make_current_thread_data()’ defined but not used [-Wunused-function]
detail::thread_data_base* get_or_make_current_thread_data()
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
..\..\..\libs\thread\src\win32\thread.cpp:91:14: warning: ‘void boost::{anonymous}::cleanup_tls_key()’ defined but not used [-Wunused-function]
void cleanup_tls_key()
^~~~~~~~~~~~~~~
"g++" -O0 -fno-inline -Wall -pedantic -g -mthreads -m64 -Wextra -Wno-long-long -Wno-unused-parameter -Wunused-function -pedantic -DBOOST_ALL_NO_LIB=1 -DBOOST_CHRONO_DYN_LINK=1 -DBOOST_SYSTEM_DYN_LINK=1 -DBOOST_THREAD_BUILD_DLL=1 -DBOOST_THREAD_USES_CHRONO -DBOOST_USE_WINDOWS_H -DWIN32_LEAN_AND_MEAN -I"..\..\.." -c -o "..\..\..\bin.v2\libs\thread\build\gcc-gnu-6.4.0\debug\threadapi-win32\threading-multi\win32\thread.o" "..\..\..\libs\thread\src\win32\thread.cpp"
...failed gcc.compile.c++ ..\..\..\bin.v2\libs\thread\build\gcc-gnu-6.4.0\debug\threadapi-win32\threading-multi\win32\thread.o...
...skipped <p..\..\..\bin.v2\libs\thread\build\gcc-gnu-6.4.0\debug\threadapi-win32\threading-multi>libboost_thread-gcc64-mt-d-x64-1_67.dll.a for lack of <p..\..\..\bin.v2\libs\thread\build\gcc-gnu-6.4.0\debug\threadapi-win32\threading-multi>win32\thread.o...
As discussed on the mailing list:
http://lists.boost.org/Archives/boost/2016/05/229385.php
http://lists.boost.org/Archives/boost/2016/05/229426.php
http://lists.boost.org/Archives/boost/2016/05/229452.php
(more to come)
The proposal is for us to add functions to the Boost thread API for getting and setting thread names (to ease debugging). It appears that there is quite well-known "cut-and-paste" boilerplate code for this on at least Windows, Linux and OS X and probably more. Can have common API, but the (very simple) implementation will vary.
If nobody else steps up, I would be happy to add this to my own backlog.
I've also been working with an external developer which is getting Ethereum
C++ working on Alpine Linux, as a statically linked executable using musl,
rather than glibc.
One rather confusing element was related to setting and getting thread
names, which is the process of working through this issue, I find appears
not to have made its way into either Boost or the C++11 standard library,
though it must be a very common cross-platform use-case.
ethereum/libweb3core#73
https://github.com/ethereum/libweb3core/pull/73/files
I've just added this comment-block, while fixing the issue:
/// Set the current thread's log name.
///
/// It appears that there is not currently any cross-platform way of setting
/// thread names either in Boost or in the C++11 runtime libraries. What is
/// more, the API for 'pthread_setname_np' is not even consistent across
/// platforms which implement it.
///
/// A proposal to add such functionality on the Boost mailing list, which
/// I assume never happened, but which I should follow-up and ask about.
/// http://boost.2283326.n4.nabble.com/Adding-an-option-to-set-the-name-of-a-boost-thread-td4638283.html
///
/// man page for 'pthread_setname_np', including this crucial snippet of
/// information ... "These functions are nonstandard GNU extensions."
/// http://man7.org/linux/man-pages/man3/pthread_setname_np.3.html
///
/// Stack Overflow "Can I set the name of a thread in pthreads / linux?"
/// which includes useful information on the minor API differences between
/// Linux, BSD and OS X.
/// http://stackoverflow.com/questions/2369738/can-i-set-the-name-of-a-thread-in-pthreads-linux/7989973#7989973
///
/// musl mailng list posting "pthread set name on MIPs" which includes the
/// information that musl doesn't currently implement 'pthread_setname_np'
/// https://marc.info/?l=musl&m=146171729013062&w=1
void setThreadName(std::string const& _n);
Would I be right in assuming that this never happened?
http://boost.2283326.n4.nabble.com/Adding-an-option-to-set-the-name-of-a-boost-thread-td4638283.html
If not, where can I log an issue to request that we revisit that? From
what I can see, everybody is likely just cut-and-pasting much the same code
for this functionality.
http://stackoverflow.com/questions/10121560/stdthread-naming-your-thread
Cheers,
Bob Summerwill
std::thread lacks GetActiveProcessorCount() and GetMaximumProcessorCount() or equivalent methods to find out how many threads or processors there are in the computer. without that information it's too easy to overload the box with too many threads and it gets really slow.
group processor counts are probably needed also since that is a concern on big iron.
The bug was made in commit ace2b8f (see line 247)
// do it here to avoid throwing on the destructor
entry->remove_waiter();
Instead should be entry.remove_waiter();
because of entry_manager has overloaded operator -> and the function is called on basic_cv_list_entry but not entry_manager itself. This results in synchronization issues.
This question is based on
https://svn.boost.org/trac/boost/ticket/11798
On linux mutex is used to guard iternal state of shared_mutex. Windows uses spinlocks instead. It would be great if on linux it would be the same as on windows (spinlocks). Its not a bug, but an optimisation request. Thanks in advance.
VS 2017.4 Preview (and I believe 2017.3) deadlock mysteriously running test 10964. Interestingly enough, this does not create a failure in the tests, but does prevent advancement of b2 until task manager is used to end-task. This was tested in 3222938. See test_10964.cpp
As above. The mingw-w64 runtime can produce a set of pthread dlls and import libraries
(usr/bin/libwinpthread-1.dll, usr/lib/libpthread.a, usr/lib/libpthread.dll.a, usr/lib/libwinpthread.a, and usr/lib/libwinpthread.dll.a) which can be used just like the linux ones,
whereas I have no idea where libpthreadGC2.a even comes from.
a windows HANDLE is a pointer. I suspect it should not be readonly. I don't know about pthreads or pth or OpenMP, but this doesn't look like a safe idea.
Platform - Windows.
Make a simple program:
void func1()
{
boost::this_thread::sleep_for(boost::chrono::hours(10));
}
int main()
{
_tsetlocale(LC_ALL, _T("Russian"));
boost::thread_group myThreadGroup;
try
{
while (true)
{
myThreadGroup.create_thread(func1);
}
}
catch (const boost::thread_resource_error& ex)
{
printf("thread_resource_error. what: %s, native_error: %d; message: %s, value: %d", ex.what(), ex.native_error(),
ex.code().message().c_str(), ex.code().value());
}
getchar();
return 0;
}
Locale may be set another. I set Russian locale to display error messages correctly.
And I get Result:
thread_resource_error. what: boost::thread_resource_error: Была сделана попытка загрузить программу, имеющую неверный формат, native_error: 11; message: Была сделана попытка загрузить программу, имеющую неверный формат, value: 11
This is not the correct error code. Native error code=11. This is windows Error code ERROR_BAD_FORMAT.
"An attempt was made to load a program with an incorrect format." (that displayed in russian language).
This error occurs when the calling LoadLibrary () function, and does not create a thread.
But! There is the following definition in errno.h : EAGAIN (11) Resource temporarily unavailable
I think that this is what was meant.
You should not write errno-error codes in "native error" field (since this is the place for Windows-based error for OS Windows), and then do not try to decipher this code.
You can provide a mechanism to set and decryption errno-error codes.
Deadlock requires end-task to continue tests.
Produced in 3222938 with 2017.4 preview, suspect also occurs in 2017.3. Tested in debug, address-model=64.
Maybe related to #134
All Threads appear to be stuck on thread.cpp line 741.
Main thread call stack:
> boost_thread-vc141-mt-gd-1_65.dll!boost::this_thread::interruptible_wait(void * handle_to_wait_for, boost::detail::timeout target_time) Line 741 C++ Symbols loaded.
boost_thread-vc141-mt-gd-1_65.dll!boost::thread::join_noexcept() Line 453 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::thread::join() Line 775 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::thread_group::join_all() Line 120 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::executors::scheduled_thread_pool::~scheduled_thread_pool() Line 35 C++ Symbols loaded.
test_scheduled_tp_p.exe!test_deque_multi(const int n) Line 84 C++ Symbols loaded.
test_scheduled_tp_p.exe!main() Line 94 C++ Symbols loaded.
Worker thread call stack:
> boost_thread-vc141-mt-gd-1_65.dll!boost::this_thread::interruptible_wait(void * handle_to_wait_for, boost::detail::timeout target_time) Line 741 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::detail::basic_cv_list_entry::wait(boost::detail::timeout abs_time) Line 95 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::detail::basic_condition_variable::do_wait<boost::unique_lock<boost::mutex> >(boost::unique_lock<boost::mutex> & lock, boost::detail::timeout abs_time) Line 245 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::condition_variable::wait(boost::unique_lock<boost::mutex> & m) Line 339 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::concurrent::sync_timed_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::chrono::steady_clock>::wait_until_not_empty_time_reached_or_closed(boost::unique_lock<boost::mutex> & lk) Line 238 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::concurrent::sync_timed_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::chrono::steady_clock>::wait_pull(boost::unique_lock<boost::mutex> & lk, boost::detail::nullary_function<void __cdecl(void)> & elem) Line 419 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::concurrent::sync_timed_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::chrono::steady_clock>::wait_pull(boost::detail::nullary_function<void __cdecl(void)> & elem) Line 429 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::executors::detail::priority_executor_base<boost::concurrent::sync_timed_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::chrono::steady_clock> >::loop() Line 61 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::_mfi::mf0<void,boost::executors::detail::priority_executor_base<boost::concurrent::sync_timed_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::chrono::steady_clock> > >::call<boost::executors::scheduled_thread_pool * __ptr64>(boost::executors::scheduled_thread_pool * & u, const void * __formal) Line 41 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::_mfi::mf0<void,boost::executors::detail::priority_executor_base<boost::concurrent::sync_timed_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::chrono::steady_clock> > >::operator()<boost::executors::scheduled_thread_pool * __ptr64>(boost::executors::scheduled_thread_pool * & u) Line 56 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::_bi::list1<boost::_bi::value<boost::executors::scheduled_thread_pool * __ptr64> >::operator()<boost::_mfi::mf0<void,boost::executors::detail::priority_executor_base<boost::concurrent::sync_timed_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::chrono::steady_clock> > >,boost::_bi::list0>(boost::_bi::type<void> __formal, boost::_mfi::mf0<void,boost::executors::detail::priority_executor_base<boost::concurrent::sync_timed_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::chrono::steady_clock> > > & f, boost::_bi::list0 & a, int __formal) Line 260 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::_bi::bind_t<void,boost::_mfi::mf0<void,boost::executors::detail::priority_executor_base<boost::concurrent::sync_timed_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::chrono::steady_clock> > >,boost::_bi::list1<boost::_bi::value<boost::executors::scheduled_thread_pool * __ptr64> > >::operator()() Line 1295 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::detail::invoke<boost::_bi::bind_t<void,boost::_mfi::mf0<void,boost::executors::detail::priority_executor_base<boost::concurrent::sync_timed_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::chrono::steady_clock> > >,boost::_bi::list1<boost::_bi::value<boost::executors::scheduled_thread_pool * __ptr64> > > >(boost::_bi::bind_t<void,boost::_mfi::mf0<void,boost::executors::detail::priority_executor_base<boost::concurrent::sync_timed_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::chrono::steady_clock> > >,boost::_bi::list1<boost::_bi::value<boost::executors::scheduled_thread_pool *> > > && f) Line 135 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::detail::thread_data<boost::_bi::bind_t<void,boost::_mfi::mf0<void,boost::executors::detail::priority_executor_base<boost::concurrent::sync_timed_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::chrono::steady_clock> > >,boost::_bi::list1<boost::_bi::value<boost::executors::scheduled_thread_pool * __ptr64> > > >::run2<>(boost::detail::tuple_indices<> __formal) Line 76 C++ Symbols loaded.
test_scheduled_tp_p.exe!boost::detail::thread_data<boost::_bi::bind_t<void,boost::_mfi::mf0<void,boost::executors::detail::priority_executor_base<boost::concurrent::sync_timed_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::chrono::steady_clock> > >,boost::_bi::list1<boost::_bi::value<boost::executors::scheduled_thread_pool * __ptr64> > > >::run() Line 82 C++ Symbols loaded.
boost_thread-vc141-mt-gd-1_65.dll!boost::`anonymous namespace'::thread_start_function(void * param) Line 296 C++ Symbols loaded.
[External Code] Annotated Frame
Dump/pdb/etc available, email me.
Hi,
My testing program sometimes get exception lock_error.
According to dump, the exception is caused by the share_waiting overflow in bool timed_lock_shared(boost::system_time const& wait_until)
I've tried to modify the code in shared_mutex.hpp to avoid getting exception.
But I'm not sure if it's the right way to fix the issue or not.
Platform: Windows 10
Boost version: 1.62
Testing code:
boost::shared_mutex mtx;
int g_cnt = 5000000;
void f()
{
while (g_cnt > 0)
{
boost::upgrade_lock<boost::shared_mutex> readlock(mtx);
boost::upgrade_to_unique_lock<boost::shared_mutex> writelock(readlock);
if (g_cnt > 0)
--g_cnt;
}
}
void g()
{
while (g_cnt > 0)
{
boost::shared_lock<boost::shared_mutex> readlock(mtx);
}
}
void h()
{
while (g_cnt > 0)
{
boost::unique_lock<boost::shared_mutex> lock(mtx);
if (g_cnt > 0)
--g_cnt;
}
}
int main()
{
boost::thread t0(f);
boost::thread t1(g);
boost::thread t2(h);
t0.join();
t1.join();
t2.join();
}
Related info in Dump:
//Stack
....
VCRUNTIME140!CxxThrowException+0xc2
boost::throw_exception<boost::lock_error>+0x3f [...\boost\boost\throw_exception.hpp @ 69]
boost::shared_mutex::timed_lock_shared+0x297 [...\boost\boost\thread\win32\shared_mutex.hpp @ 169]
boost::shared_mutex::lock_shared+0x17 (Inline Function @ 00007ff6`980f115c) [...\boost\boost\thread\win32\shared_mutex.hpp @ 144]
boost::shared_lock<boost::shared_mutex>::lock+0x13c [...\boost\boost\thread\lock_types.hpp @ 645]
boost::shared_lock<boost::shared_mutex>::{ctor}+0x14 (Inline Function @ 00007ff6`981384c4) [...\boost\boost\thread\lock_types.hpp @ 520]
g+0x34
boost_thread_vc140_mt_1_62!boost::`anonymous namespace'::thread_start_function+0x43 [...\boost\boost_1_62_0\libs\thread\src\win32\thread.cpp @ 296]
….
//value of old_state
@"old_state" [Type: boost::shared_mutex::state_data]
[+0x000 (10: 0)] shared_count : 0x0
[+0x000 (21:11)] shared_waiting : 0x7ff
[+0x000 (22:22)] exclusive : 0x1
[+0x000 (23:23)] upgrade : 0x0
[+0x000 (30:24)] exclusive_waiting : 0x1
[+0x000 (31:31)] exclusive_waiting_blocked : 0x1
Changes in shared_mutex.hpp:
void release_shared_waiters(state_data old_state)
{
- if(old_state.shared_waiting || old_state.exclusive_waiting)
+ if(old_state.shared_waiting)
{
- BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting,0)!=0);
}
}
should be functional in #if defined(DOS)&&(defined(WATCOMC)||defined(__MARSC)||defined(DJGPP)) compilers - all they have now is fsu pthreads and pth which I think are timer-based.
compiling for DOS requires a 32-bit Windows OS currently. maybe not for Mars C/C++.
please consider this.
These classes should be usable with other thread implementations, as e.g. std::thread.
The documentation says that queue_back_view
supports the pull methods while they are not present in the implementation.
The current implementation of boost::when_all and boost::when_any spawns a thread that calls wait_for_all or wait_for_any. This behaviour can result in explosive creation of OS threads when these functions are called often, which is probably not what the user expects since asynchronous primitives like futures are normally used as an alternatives to spawning lots of waiting threads.
As a simple workaround, future continuations can be used instead to asynchronously set the output future of when_all or when_any as appropriate when its input futures become ready. More efficient solutions probably exist to someone familiar with the Boost future implementation.
compile-c-c++ ..\..\bin.v2\libs\log\test\util_ipc_reliable_mq.test\msvc-14.1\deb
ug\threadapi-win32\threading-multi\run\util_ipc_reliable_mq.obj
util_ipc_reliable_mq.cpp
C:\Projects\boost-git\boost\boost/thread/win32/thread_heap_alloc.hpp(25): error
C2039: 'HeapAlloc': is not a member of 'boost::detail::winapi'
C:\Projects\boost-git\boost\boost/log/utility/permissions.hpp(37): note: see dec
laration of 'boost::detail::winapi'
C:\Projects\boost-git\boost\boost/thread/win32/thread_heap_alloc.hpp(25): error
C2039: 'GetProcessHeap': is not a member of 'boost::detail::winapi'
C:\Projects\boost-git\boost\boost/log/utility/permissions.hpp(37): note: see dec
laration of 'boost::detail::winapi'
C:\Projects\boost-git\boost\boost/thread/win32/thread_heap_alloc.hpp(35): error
C2039: 'HeapFree': is not a member of 'boost::detail::winapi'
C:\Projects\boost-git\boost\boost/log/utility/permissions.hpp(37): note: see dec
laration of 'boost::detail::winapi'
C:\Projects\boost-git\boost\boost/thread/win32/thread_heap_alloc.hpp(35): error
C2039: 'GetProcessHeap': is not a member of 'boost::detail::winapi'
C:\Projects\boost-git\boost\boost/log/utility/permissions.hpp(37): note: see dec
laration of 'boost::detail::winapi'
Deadlock requires end-task to continue tests.
Produced in 3222938 with 2017.4 preview, suspect also occurs in 2017.3. Tested in debug, address-model=64.
Maybe related to #134 and #135
All Threads appear to be stuck on thread.cpp line 741.
Main thread call stack:
> boost_thread-vc141-mt-gd-1_65.dll!boost::this_thread::interruptible_wait(void * handle_to_wait_for, boost::detail::timeout target_time) Line 741 C++ Symbols loaded.
boost_thread-vc141-mt-gd-1_65.dll!boost::thread::join_noexcept() Line 453 C++ Symbols loaded.
test_scheduler_p.exe!boost::thread::join() Line 775 C++ Symbols loaded.
test_scheduler_p.exe!boost::executors::basic_thread_pool::join() Line 238 C++ Symbols loaded.
test_scheduler_p.exe!boost::executors::basic_thread_pool::~basic_thread_pool() Line 227 C++ Symbols loaded.
test_scheduler_p.exe!main() Line 80 C++ Symbols loaded.
Worker threads (2) call stack:
> boost_thread-vc141-mt-gd-1_65.dll!boost::this_thread::interruptible_wait(void * handle_to_wait_for, boost::detail::timeout target_time) Line 741 C++ Symbols loaded.
test_scheduler_p.exe!boost::detail::basic_cv_list_entry::wait(boost::detail::timeout abs_time) Line 95 C++ Symbols loaded.
test_scheduler_p.exe!boost::detail::basic_condition_variable::do_wait<boost::unique_lock<boost::mutex> >(boost::unique_lock<boost::mutex> & lock, boost::detail::timeout abs_time) Line 245 C++ Symbols loaded.
test_scheduler_p.exe!boost::condition_variable::wait(boost::unique_lock<boost::mutex> & m) Line 339 C++ Symbols loaded.
test_scheduler_p.exe!boost::concurrent::detail::sync_queue_base<boost::detail::nullary_function<void __cdecl(void)>,boost::csbl::devector<boost::detail::nullary_function<void __cdecl(void)> > >::wait_until_not_empty_or_closed(boost::unique_lock<boost::mutex> & lk) Line 201 C++ Symbols loaded.
test_scheduler_p.exe!boost::concurrent::sync_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::csbl::devector<boost::detail::nullary_function<void __cdecl(void)> > >::wait_pull(boost::detail::nullary_function<void __cdecl(void)> & elem, boost::unique_lock<boost::mutex> & lk) Line 161 C++ Symbols loaded.
test_scheduler_p.exe!boost::concurrent::sync_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::csbl::devector<boost::detail::nullary_function<void __cdecl(void)> > >::wait_pull(boost::detail::nullary_function<void __cdecl(void)> & elem) Line 181 C++ Symbols loaded.
test_scheduler_p.exe!boost::executors::basic_thread_pool::worker_thread() Line 89 C++ Symbols loaded.
test_scheduler_p.exe!boost::detail::invoke<void (__cdecl boost::executors::basic_thread_pool::*)(void) __ptr64,boost::executors::basic_thread_pool * __ptr64>(void(boost::executors::basic_thread_pool::*)() && f, boost::executors::basic_thread_pool * && a0) Line 78 C++ Symbols loaded.
test_scheduler_p.exe!boost::detail::thread_data<void (__cdecl boost::executors::basic_thread_pool::*)(void) __ptr64,boost::executors::basic_thread_pool * __ptr64>::run2<1>(boost::detail::tuple_indices<1> __formal) Line 76 C++ Symbols loaded.
test_scheduler_p.exe!boost::detail::thread_data<void (__cdecl boost::executors::basic_thread_pool::*)(void) __ptr64,boost::executors::basic_thread_pool * __ptr64>::run() Line 82 C++ Symbols loaded.
boost_thread-vc141-mt-gd-1_65.dll!boost::`anonymous namespace'::thread_start_function(void * param) Line 296 C++ Symbols loaded.
[External Code] Annotated Frame
Dump/pdb/etc available, email me.
While building 1.68.0 beta 1 on x86_64 cross-compiling to Windows 32 bits with mingw-w64 + g++ 8.2.0, I get the following warning:
"i686-w64-mingw32-g++-8.2.0" -I/softs/win32-mingw-8.2.0/release/iconv/include -I/softs/win32-mingw-8.2.0/release/gettext/include -I/softs/win32-mingw-8.2.0/release/bzip2/include -I/softs/win32-mingw-8.2.0/release/zlib/include -I/softs/win32-mingw-8.2.0/release/jpeg-turbo/include -I/softs/win32-mingw-8.2.0/release/xz/include -I/softs/win32-mingw-8.2.0/release/tiff/include -I/softs/win32-mingw-8.2.0/release/png/include -std=c++14 -O2 -DNDEBUG -m32 -mthreads -O3 -finline-functions -Wno-inline -Wall -pedantic -march=i686 -Wextra -Wno-long-long -Wno-unused-parameter -Wunused-function -pedantic -DBOOST_ALL_NO_LIB=1 -DBOOST_ASIO_NO_DEPRECATED -DBOOST_CHRONO_STATIC_LINK=1 -DBOOST_FILESYSTEM_NO_DEPRECATED -DBOOST_LOG_WITHOUT_EVENT_LOG -DBOOST_SYSTEM_NO_DEPRECATED -DBOOST_SYSTEM_STATIC_LINK=1 -DBOOST_THREAD_BUILD_LIB=1 -DBOOST_THREAD_USES_CHRONO -DBOOST_THREAD_WIN32 -DBOOST_USE_WINDOWS_H -DNDEBUG -DWIN32_LEAN_AND_MEAN -I"." -c -o "bin.v2/libs/thread/build/gcc-8.2.0/release/link-static/target-os-windows/threadapi-win32/threading-multi/win32/thread_primitives.o" "libs/thread/src/win32/thread_primitives.cpp"
libs/thread/src/win32/thread_primitives.cpp: In function 'boost::detail::win32::ticks_type boost::detail::win32::{anonymous}::get_tick_count_init()':
libs/thread/src/win32/thread_primitives.cpp:97:120: warning: cast between incompatible function types from 'boost::winapi::FARPROC_' {aka 'int (__attribute__((stdcall)) *)()'} to 'boost::detail::win32::detail::gettickcount64_t' {aka 'long long unsigned int (__attribute__((stdcall)) *)()'} [-Wcast-function-type]
(boost::detail::win32::detail::gettickcount64_t)boost::winapi::get_proc_address(hKernel32, "GetTickCount64");
^
Clang and MSVC
Would you merge PR with some of the attributes?
boost::thread_group
could provide a constructor taking a number and a function object:
boost::thread_group threads(10, [] { run something });
This is especially useful when mixing threads and something like Boost.ASIO with an io_service
, or when using Fibers. In that case, the function being run in all the threads is the same, so it makes sense to use a constructor like this.
Another possibility would be to provide an iterator-based constructor (iterators to callables):
std::vector<std::function<void()>> functions;
boost::thread_group threads(functions.begin(), functions.end());
I don't have a use-case for the latter, but I do have one for the former. I can submit a PR if there's interest for any of this.
clang++ -c -x c++ -Wextra -Wno-long-long -Wno-unused-parameter -Wunused-function -O3 -Wno-inline -Wall -pthread -fPIC -m64 -Wextra -Wno-long-long -Wno-unused-parameter -Wunused-function -DBOOST_ALL_NO_LIB=1 -DBOOST_CHRONO_STATIC_LINK=1 -DBOOST_SYSTEM_NO_DEPRECATED -DBOOST_SYSTEM_STATIC_LINK=1 -DBOOST_THREAD_BUILD_LIB=1 -DBOOST_THREAD_POSIX -DBOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED -DBOOST_THREAD_USE_LIB=1 -DNDEBUG -I".." "../libs/thread/test/../example/future_then.cpp" -E > future_then.i
void do_continuation(boost::unique_lock<boost::mutex>& lock)
{
if (! continuations.empty()) {
continuations_type the_continuations = continuations;
continuations.clear();
relocker rlk(lock);
for (continuations_type::iterator it = the_continuations.begin(); it != the_continuations.end(); ++it) {
(*it)->launch_continuation();
}
}
}
clang++ -c -x c++ -Wextra -Wno-long-long -Wno-unused-parameter -Wno-variadic-macros -Wunused-function -O0 -g -fno-inline -Wall -g -pthread -m64 -Wextra -Wno-long-long -Wno-unused-parameter -Wno-variadic-macros -Wunused-function -DBOOST_ALL_NO_LIB=1 -DBOOST_SYSTEM_STATIC_LINK=1 -DBOOST_THREAD_BUILD_LIB=1 -DBOOST_THREAD_DONT_USE_CHRONO -DBOOST_THREAD_POSIX -I".." "../libs/thread/src/pthread/thread.cpp" -E > thread.i
void do_continuation(boost::unique_lock<boost::mutex>& lock)
{
}
The essential reason is that the macro #define BOOST_THREAD_VERSION 4
defined in future_then.cpp makes the implementation of do_continuation in future_then.o different from that in thread.o.
change ECMAScript value to Javascript (JavaScript is original language)
JavaScript is a fuller language put out by Danny Goodman. it probably has a better regex spec.
he might be looking for a better publisher.
the other name is offending lots of developers, which are 1/4 the population.
Hello,
the pthread_condattr_setclock
function is only available for __ANDROID_API__ >= 21
. The unconditional use in pthread_helpers.hpp leads to an compile error.
What would be the proper way to handle it? Should the preprocessor condition in boost::pthread::cond_init
be tightened or BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
not be defined on Android < 21?
Would the following patch make sense?
diff --git a/boost/thread/detail/config.hpp b/boost/thread/detail/config.hpp
index 70c74687f6..aae25268d3 100644
--- a/boost/thread/detail/config.hpp
+++ b/boost/thread/detail/config.hpp
@@ -417,6 +417,11 @@
#define BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
#elif defined(BOOST_THREAD_CHRONO_MAC_API)
#define BOOST_THREAD_HAS_MONO_CLOCK
+#elif defined(__ANDROID__)
+ #define BOOST_THREAD_HAS_MONO_CLOCK
+ #if defined(__ANDROID_API__) && __ANDROID_API__ >= 21
+ #define BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
+ #endif
#else
#include <time.h> // check for CLOCK_MONOTONIC
#if defined(CLOCK_MONOTONIC)
Thanks,
Gregor
try putting std::thread in struct and later trying to fill in blanks. it can't be done.
also, you have to CloseHandle() in windows when thread is done and people don't know this. which may explain any server resource leaks. that you can't do without a vector or array of struct.
buffer(size);
should be buffer(size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION))
https://github.com/boostorg/thread/blob/develop/src/win32/thread.cpp
On line 526
boost thread doesn't compile with Clang 4.0.1 on Windows, there are a lot of errors about duplicated Windows API definitions
In file included from libs\coroutine\src\windows\stack_traits.cpp:23:
In file included from .\boost/thread.hpp:13:
In file included from .\boost/thread/thread.hpp:12:
In file included from .\boost/thread/thread_only.hpp:15:
In file included from .\boost/thread/win32/thread_data.hpp:11:
.\boost/thread/win32/thread_primitives.hpp:173:55: error: conflicting types for 'CreateMutexA'
__declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*);
^
C:\Program Files (x86)\Windows Kits\10\include\10.0.15063.0\um\synchapi.h:489:1: note: previous declaration is here
CreateMutexA(
^
In file included from libs\coroutine\src\windows\stack_traits.cpp:23:
In file included from .\boost/thread.hpp:13:
In file included from .\boost/thread/thread.hpp:12:
In file included from .\boost/thread/thread_only.hpp:15:
In file included from .\boost/thread/win32/thread_data.hpp:11:
.\boost/thread/win32/thread_primitives.hpp:174:55: error: conflicting types for 'CreateSemaphoreA'
__declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*);
^
C:\Program Files (x86)\Windows Kits\10\include\10.0.15063.0\um\winbase.h:3009:1: note: previous declaration is here
CreateSemaphoreA(
^
In file included from libs\coroutine\src\windows\stack_traits.cpp:23:
In file included from .\boost/thread.hpp:13:
In file included from .\boost/thread/thread.hpp:12:
In file included from .\boost/thread/thread_only.hpp:15:
In file included from .\boost/thread/win32/thread_data.hpp:11:
.\boost/thread/win32/thread_primitives.hpp:175:55: error: conflicting types for 'CreateEventA'
__declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*);
^
C:\Program Files (x86)\Windows Kits\10\include\10.0.15063.0\um\synchapi.h:530:1: note: previous declaration is here
CreateEventA(
^
In file included from libs\coroutine\src\windows\stack_traits.cpp:23:
In file included from .\boost/thread.hpp:13:
In file included from .\boost/thread/thread.hpp:12:
In file included from .\boost/thread/thread_only.hpp:15:
In file included from .\boost/thread/win32/thread_data.hpp:11:
.\boost/thread/win32/thread_primitives.hpp:177:55: error: functions that differ only in their return type cannot be overloaded
__declspec(dllimport) void* __stdcall GetModuleHandleA(char const*);
^
C:\Program Files (x86)\Windows Kits\10\include\10.0.15063.0\um\libloaderapi.h:300:1: note: previous declaration is here
GetModuleHandleA(
^
In file included from libs\coroutine\src\windows\stack_traits.cpp:23:
In file included from .\boost/thread.hpp:13:
In file included from .\boost/thread/thread.hpp:12:
In file included from .\boost/thread/thread_only.hpp:15:
In file included from .\boost/thread/win32/thread_data.hpp:11:
.\boost/thread/win32/thread_primitives.hpp:194:54: warning: redeclaration of 'Sleep' should not add 'dllimport' attribute [-Wdll-attribute-on-redeclaration]
__declspec(dllimport) void __stdcall Sleep(unsigned long);
^
C:\Program Files (x86)\Windows Kits\10\include\10.0.15063.0\um\synchapi.h:820:1: note: previous declaration is here
Sleep(
^
In file included from libs\coroutine\src\windows\stack_traits.cpp:23:
In file included from .\boost/thread.hpp:13:
In file included from .\boost/thread/thread.hpp:12:
In file included from .\boost/thread/thread_only.hpp:15:
In file included from .\boost/thread/win32/thread_data.hpp:11:
.\boost/thread/win32/thread_primitives.hpp:197:59: error: functions that differ only in their return type cannot be overloaded
__declspec(dllimport) farproc_t __stdcall GetProcAddress(void *, const char *);
^
C:\Program Files (x86)\Windows Kits\10\include\10.0.15063.0\um\libloaderapi.h:384:1: note: previous declaration is here
GetProcAddress(
^
my user config
using clang : 5.0 :
"C:/Program Files/LLVM/bin/clang.exe" :
<compileflags>-fmsc-version=1910 -DBOOST_USE_WINAPI_VERSION=0x0501
<ranlib>"C:/Program Files/LLVM/bin/llvm-ranlib.exe"
<archiver>"C:/Program Files/LLVM/bin/llvm-ar.exe"
<linkflags>-fuse-ld=lld ;
Deadlock requires end-task to continue tests.
Produced in 3222938 with 2017.4 preview, suspect also occurs in 2017.3. Tested in debug, address-model=64.
Maybe related to #134 and #135 and #136
All Threads appear to be stuck on thread.cpp line 741.
Main thread call stack:
[External Code] Annotated Frame
> boost_thread-vc141-mt-gd-1_65.dll!boost::this_thread::interruptible_wait(void * handle_to_wait_for, boost::detail::timeout target_time) Line 741 C++ Symbols loaded.
boost_thread-vc141-mt-gd-1_65.dll!boost::thread::join_noexcept() Line 453 C++ Symbols loaded.
ex_executor.exe!boost::thread::join() Line 775 C++ Symbols loaded.
ex_executor.exe!boost::executors::basic_thread_pool::join() Line 238 C++ Symbols loaded.
ex_executor.exe!boost::executors::basic_thread_pool::~basic_thread_pool() Line 227 C++ Symbols loaded.
[External Code] Annotated Frame
ex_executor.exe!test_executor_adaptor() Line 121 C++ Symbols loaded.
ex_executor.exe!main() Line 207 C++ Symbols loaded.
[External Code] Annotated Frame
Worker thread:
[External Code] Annotated Frame
> boost_thread-vc141-mt-gd-1_65.dll!boost::this_thread::interruptible_wait(void * handle_to_wait_for, boost::detail::timeout target_time) Line 741 C++ Symbols loaded.
ex_executor.exe!boost::detail::basic_cv_list_entry::wait(boost::detail::timeout abs_time) Line 95 C++ Symbols loaded.
ex_executor.exe!boost::detail::basic_condition_variable::do_wait<boost::unique_lock<boost::mutex> >(boost::unique_lock<boost::mutex> & lock, boost::detail::timeout abs_time) Line 245 C++ Symbols loaded.
ex_executor.exe!boost::condition_variable::wait(boost::unique_lock<boost::mutex> & m) Line 339 C++ Symbols loaded.
ex_executor.exe!boost::concurrent::detail::sync_queue_base<boost::detail::nullary_function<void __cdecl(void)>,boost::csbl::devector<boost::detail::nullary_function<void __cdecl(void)> > >::wait_until_not_empty_or_closed(boost::unique_lock<boost::mutex> & lk) Line 201 C++ Symbols loaded.
ex_executor.exe!boost::concurrent::sync_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::csbl::devector<boost::detail::nullary_function<void __cdecl(void)> > >::wait_pull(boost::detail::nullary_function<void __cdecl(void)> & elem, boost::unique_lock<boost::mutex> & lk) Line 161 C++ Symbols loaded.
ex_executor.exe!boost::concurrent::sync_queue<boost::detail::nullary_function<void __cdecl(void)>,boost::csbl::devector<boost::detail::nullary_function<void __cdecl(void)> > >::wait_pull(boost::detail::nullary_function<void __cdecl(void)> & elem) Line 181 C++ Symbols loaded.
ex_executor.exe!boost::executors::basic_thread_pool::worker_thread() Line 89 C++ Symbols loaded.
ex_executor.exe!boost::detail::invoke<void (__cdecl boost::executors::basic_thread_pool::*)(void) __ptr64,boost::executors::basic_thread_pool * __ptr64>(void(boost::executors::basic_thread_pool::*)() && f, boost::executors::basic_thread_pool * && a0) Line 78 C++ Symbols loaded.
ex_executor.exe!boost::detail::thread_data<void (__cdecl boost::executors::basic_thread_pool::*)(void) __ptr64,boost::executors::basic_thread_pool * __ptr64>::run2<1>(boost::detail::tuple_indices<1> __formal) Line 76 C++ Symbols loaded.
ex_executor.exe!boost::detail::thread_data<void (__cdecl boost::executors::basic_thread_pool::*)(void) __ptr64,boost::executors::basic_thread_pool * __ptr64>::run() Line 82 C++ Symbols loaded.
boost_thread-vc141-mt-gd-1_65.dll!boost::`anonymous namespace'::thread_start_function(void * param) Line 296 C++ Symbols loaded.
[External Code] Annotated Frame
Will make some dumps if needed.
As discussed on the mailing list:
http://lists.boost.org/boost-users/2017/02/87211.php
The proposal is to add these functions:
promise::set_value_deferred
promise::set_exception_deferred
promise::notify_deferred
It's for finer-grain control. The existing set_xxx_at_thread_exit
can thus be implemented in terms of these functions (where at thread-exit, it calls notify_deferred
automatically).
This allows using the shared-state's storage w/o additional space overhead on the user side.
I'm running the tests for Boost.Pool under g++/Cygwin, and this is what I get:
In file included from ..\../boost/thread/win32/recursive_mutex.hpp:13:0,
from ..\../boost/thread/recursive_mutex.hpp:14,
from ..\../boost/thread.hpp:18,
from test\test_threading.cpp:10:
..\../boost/thread/win32/basic_recursive_mutex.hpp: In member function 'bool boo
st::detail::basic_recursive_mutex_impl<underlying_mutex_type>::timed_lock(const
Duration&)':
..\../boost/thread/win32/basic_recursive_mutex.hpp:70:61: error: 'boost::detail:
:winapi' has not been declared
long const current_thread_id=boost::detail::winapi::GetCurrentT
hreadId();
^~~~~~
..\../boost/thread/win32/basic_recursive_mutex.hpp: In member function 'bool boo
st::detail::basic_recursive_mutex_impl<underlying_mutex_type>::try_lock_for(cons
t boost::chrono::duration<Rep2, Period2>&)':
..\../boost/thread/win32/basic_recursive_mutex.hpp:79:61: error: 'boost::detail:
:winapi' has not been declared
long const current_thread_id=boost::detail::winapi::GetCurrentT
hreadId();
^~~~~~
..\../boost/thread/win32/basic_recursive_mutex.hpp: In member function 'bool boo
st::detail::basic_recursive_mutex_impl<underlying_mutex_type>::try_lock_until(co
nst boost::chrono::time_point<Clock, Duration>&)':
..\../boost/thread/win32/basic_recursive_mutex.hpp:85:61: error: 'boost::detail:
:winapi' has not been declared
long const current_thread_id=boost::detail::winapi::GetCurrentT
hreadId();
^~~~~~
This should presumably be boost::winapi
?
Also, there's this:
..\..\libs\thread\src\win32\thread.cpp: In function 'void boost::{anonymous}::cr
eate_current_thread_tls_key()':
..\..\libs\thread\src\win32\thread.cpp:86:13: error: 'tss_cleanup_implemented' w
as not declared in this scope
tss_cleanup_implemented(); // if anyone uses TSS, we need the clean
up linked in
^~~~~~~~~~~~~~~~~~~~~~~
Additionally, with cxxstd=03
I get these:
In file included from ..\../boost/thread/detail/config.hpp:14:0,
from ..\../boost/thread/win32/thread_data.hpp:9,
from ..\../boost/thread/thread_only.hpp:15,
from ..\..\libs\thread\src\win32\thread.cpp:11:
..\../boost/thread/detail/thread_safety.hpp:26:38: warning: anonymous variadic m
acros were introduced in C++11 [-Wvariadic-macros]
#define BOOST_THREAD_ACQUIRED_BEFORE(...) \
^~~
..\../boost/thread/detail/thread_safety.hpp:29:37: warning: anonymous variadic m
acros were introduced in C++11 [-Wvariadic-macros]
#define BOOST_THREAD_ACQUIRED_AFTER(...) \
^~~
...
In file included from ..\../boost/thread/win32/condition_variable.hpp:19:0,
from ..\../boost/thread/condition_variable.hpp:14,
from ..\../boost/thread/thread_only.hpp:26,
from ..\..\libs\thread\src\win32\thread.cpp:11:
..\../boost/thread/lock_guard.hpp:65:40: warning: invoking macro BOOST_THREAD_RE
LEASE argument 1: empty macro arguments are undefined in ISO C++98 [-Wpedantic]
~lock_guard() BOOST_THREAD_RELEASE()
^
The links in README.md are broken and needs updating.
Some time-related functions doesn't work when the system-time backs and forwards the system clock (the return result is not correct in some cases).
In addition the timeout is not as close as it could be.
We have a branch (#142) for fixing these issues where
The Travis jobs using the default g++ 4.8 installation fail with
gcc.compile.c++ bin.v2/libs/thread/test/ex_std_thread_guard.test/gcc-gnu-4.8/debug/cxxstd-11/threadapi-pthread/threading-multi/std_thread_guard.o
gcc.link bin.v2/libs/thread/test/ex_std_thread_guard.test/gcc-gnu-4.8/debug/cxxstd-11/threadapi-pthread/threading-multi/ex_std_thread_guard
gcc.compile.c++ bin.v2/libs/thread/test/ex_std_thread_guard_lib.test/gcc-gnu-4.8/debug/cxxstd-11/threadapi-pthread/threading-multi/std_thread_guard.o
gcc.link bin.v2/libs/thread/test/ex_std_thread_guard_lib.test/gcc-gnu-4.8/debug/cxxstd-11/threadapi-pthread/threading-multi/ex_std_thread_guard_lib
testing.capture-output bin.v2/libs/thread/test/ex_std_thread_guard_lib.test/gcc-gnu-4.8/debug/cxxstd-11/threadapi-pthread/threading-multi/ex_std_thread_guard_lib.run
====== BEGIN OUTPUT ======
terminate called after throwing an instance of 'std::system_error'
what(): Enable multithreading to use std::thread: Operation not permitted
Aborted (core dumped)
EXIT STATUS: 134
====== END OUTPUT ======
That's odd, I'm not sure what we need to do to "enable multithreading" there.
See f.ex. https://travis-ci.org/boostorg/boost/jobs/285103799
Hi, I'm a newcomer to boost. When I read the code about boost thread, I found that thread_group's member function create_thread
used unique_ptr. Why? Use unique_ptr to avoid threads.push_back(new_thread.get());
out of memory error that caused not releasing the thread push_backed unsuccessful?
A third-party legal review has identified a problem as reported here:
https://lists.boost.org/Archives/boost/2018/02/241435.php
regarding
thread/include/boost/thread/win32/thread_primitives.hpp
Lines 89 to 110 in 526c72c
introduced by
The easiest way to fix that is to rewrite GetTickCount64emulation
in terms of boost::atomic_uint64_t
. As pointed out in
https://lists.boost.org/Archives/boost/2018/02/241453.php
an implementation already exists in Boost.Log:
loop_executor::loop
is currently:
void loop()
{
while (!closed())
{
schedule_one_or_yield();
}
while (try_executing_one())
{
}
}
The first loop repeatedly calls schedule_one_or_yield()
which is simply
void schedule_one_or_yield()
{
if ( ! try_executing_one())
{
this_thread::yield();
}
}
The current implementation uses unnecessary CPU cycles (esp. if all other threads are idle) by busy waiting. As concurrent::sync_queue<work> work_queue
already supports a blocking wait_pull_front
, it would be better to use a (private?) wait_executing_one
that behaves just like try_executing_one
but calls work_queue.wait_pull_front
instead of try_pull_front
.
IMHO, the current implementation is an outright performance bug.
The futures returned from boost::future<T>::then()
block in the destructor. While this appears to be a design decision to be similar to boost::async
/std::async
, it practically makes fire and forget continuations (technically register and forget) impractical.
I'm using these to have the last continuation on a chain fire off an event to Qt to handle on its main loop, this gives me no location where calling .get() is desirable, nor a "natural" location to store the future. So currently I have to resort to keeping a vector of pending futures and occasionally garbage collecting them: v.erase(std::remove_if(v.begin(), v.end(), [](const auto& f) { return f.is_ready(); }), v.end())
.
I assume that it's obvious how cumbersome and undesirable this is.
I would very much like for futures to never block in the destructor. Preferably for those started from boost::async
too, but I hardly use that anyway, so only not blocking for those returned from then()
would be fine for me too.
Alternatively, providing a detach()
method, like stlab::future::detach()
would be fine too and in line with thread
's detach
method.
From a conceptual point of view, future continuations are awesome. They allow the dynamic definition of a processing pipeline, where multiple asynchronous operations are chained transparently without ever blocking for any of them until doing so is actually required.
However, I am finding myself in a situation where none of Boost's continuation launch policies seem to fit, in the sense that all of them result in bad performance or unnecessarily convoluted code. And I would like to propose another launch policy which could address that.
Consider the following processing pipeline, which is a heavily simplified form of my processing chain where future continuations are a attached in several places throughout the codebase.
auto future = requestStorage()
.then( loadInputs )
.then( executor, userProvidedFunction )
.then( writeOutput );
In this processing pipeline, requestStorage queues an allocation request to a bounded storage mechanism, which will be honored once some storage becomes available. At this point, the future returned by requestStorage will be set with a handle to the corresponding storage location. When that happens, I want to load inputs from some IO resource into the storage system, then call a user-provided function which operates on those inputs in a CPU-intensive manner, and finally write down the outputs. At the end, I get a future or similar that I can use to tell when the whole process has completed.
Now, my goal is to run this processing pipeline for a bunch of user requests without spawning a large number of OS threads, because I know the later to kill my task scheduling performance. How do I do that?
So, it is possibly to implement every piece of work in my processing chain with a constant number of threads and a tiny bit of scheduling work here and there. The problem is that the default behaviour of Boost's future continuations is to spawn all of that scheduling work in extra threads, resulting in a huge number of OS threads being spawned and destroyed per request.
To quite GDB on this matter:
[New Thread 0x7ffff7f97700 (LWP 6365)]
[New Thread 0x7ffff6794700 (LWP 6366)]
[Thread 0x7ffff7f97700 (LWP 6365) exited]
[New Thread 0x7ffff6f95700 (LWP 6367)]
[Thread 0x7ffff6794700 (LWP 6366) exited]
[Thread 0x7ffff6f95700 (LWP 6367) exited]
[New Thread 0x7ffff7f97700 (LWP 6369)]
[New Thread 0x7ffff6f95700 (LWP 6370)]
[Thread 0x7ffff7f97700 (LWP 6369) exited]
[New Thread 0x7ffff7f97700 (LWP 6371)]
[Thread 0x7ffff6f95700 (LWP 6370) exited]
...and, unsurprisingly, looking at performance profiles, pthread_clone ends up being a signficant contributor to my request scheduling overhead.
Why does this happen? Well, my first guess is that future.then()'s default launch policy is boost::launch::async, which spawns an extra thread. Definitely not what I want here. So, what are my other options?
None of these seem to be very good fit here. Since again, my scheduling work is very small and nonblocking, what I would like to do instead is the following:
An astute reader will notice that this launch policy is essentially a variant of boost::launch::deferred that uses eager evaluation instead of lazy evaluation: we want to run the continuation as soon as the future is ready, and not as soon as its value is requested.
In addition, this launch policy is extremely light on resource requirements: you do not need extra threads, executors, concurrent queues, mutexes or any other kind of heavy-handed infrastructure, you could in principle implement it directly in the future class using nothing but an atomic compare-and-swap in future.then() and an atomic read in promise.set_xyz().
So, what would you think about this proposal?
relocker DTOR is implemented as the following:
~relocker()
{
if(unlocked)
{
lock.lock();
}
}
that lock.lock() can throw (see unique_lock::lock in lock_types.hpp) leading to std::terminate if compiled in c++11 mode
Some tests are failing on msvc-12.0, see
https://ci.appveyor.com/project/boostorg/boost/build/1.0.3620
...failed compile-c-c++ bin.v2\libs\thread\test\queue_views__single_thread_p.test\msvc-12.0\debug\threading-multi\sync\mutual_exclusion\queue_views\single_thread_pass.obj...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.