GithubHelp home page GithubHelp logo

thread's Introduction

thread's People

Contributors

austin-beer avatar beman avatar dabrahams avatar danieljames avatar douggregor avatar eldiener avatar grafikrobot avatar hkaiser avatar jhunold avatar jzmaddock avatar karzhenkov avatar kojoley avatar lastique avatar marcelraad avatar mclow avatar ned14 avatar oe1rsa avatar pdimov avatar rick68 avatar shinobu-x avatar stgates avatar straszheim avatar swatanabe avatar thughes avatar thwitt avatar timblechmann avatar tvbuehler avatar viboes avatar vprus avatar wmamrak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

thread's Issues

Clang on Windows build failures due to duplicated Windows API definitions

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 ;

VS 2017.4 Preview test_scheduled_tp_p.exe deadlock

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.

.native_handle() should not be readonly

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.

when_all and when_any should probably not spawn a thread

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.

loop_executor should block on it's work_queue instead of polling

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.

MSVC++17: boost::synchronized_value with boost::synchronize

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.

VS 2017.4 Preview deadlocks on Test 10964.

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

fix as much time-related issues as possible and improve the QOI

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

  • we have created some internal monotonic clock that help to provide some functionalities that were not possible without, and
    *in addition, to improve the QOI, we pool when the platform doesn't provide a monotonic interface.

VS 2017.4 Preview executor_ex.exe deadlock

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.

hardcoded check for libpthreadGC2.a for mingw-w64 gcc

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.

DOS support please (used in embedded, disk utilities)

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.

future_then unit test contains two different implementations of do_continuation function

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.

windows: Bug in boost::condition_variable on Windows

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.

Wrong Error Code and Description

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.

Errors under g++/Cygwin

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()
                                        ^

[Proposal] Add APIs for deferred set_value/exception

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.

thread_group vector-like initialization

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.

Why does thread_group create_thread need to use unique_ptr?

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?

Android < 21 must not use pthread_condattr_setclock

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

boost::future::then() continuations block in the destructor

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.

Should thread_specific_ptr be moveable?

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

warning: cast between incompatible function types from FARPROC_ to gettickcount64_t

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");
                                                                                                                        ^

Thread causes test failure in Log

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'

boostorg/log#44

WINDOWS: Exception lock_error in shared_mutex.hpp

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);
             }

         }

Legal problem with `win32/thread_primitives.hpp`

A third-party legal review has identified a problem as reported here:

https://lists.boost.org/Archives/boost/2018/02/241435.php

regarding

// Borrowed from https://stackoverflow.com/questions/8211820/userland-interrupt-timer-access-such-as-via-kequeryinterrupttime-or-similar
inline ticks_type __stdcall GetTickCount64emulation()
{
static long count = -1l;
unsigned long previous_count, current_tick32, previous_count_zone, current_tick32_zone;
ticks_type current_tick64;
previous_count = (unsigned long) boost::detail::interlocked_read_acquire(&count);
current_tick32 = ::boost::winapi::GetTickCount();
if(previous_count == (unsigned long)-1l)
{
// count has never been written
unsigned long initial_count;
initial_count = current_tick32 >> 28;
previous_count = (unsigned long) _InterlockedCompareExchange(&count, (long)initial_count, -1l);
current_tick64 = initial_count;
current_tick64 <<= 28;
current_tick64 += current_tick32 & 0x0FFFFFFF;
return current_tick64;
}

introduced by

04c5341

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:

https://github.com/boostorg/log/blob/1cc577cbf5fae8f55c71c4493a7ef89027bd85dc/src/timestamp.cpp#L66-L86

Clang build error with BOOST_THREAD_ATTRIBUTE_MAY_ALIAS

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.

Proposal - Add API for getting/setting thread name in Boost?

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

VS 2017.4 Preview test_scheduler_p.exe deadlock

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.

Proposal: New launch policy for eagerly evaluated synchronous future continuations

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?

  • Implementing requestStorage without threads is easy, all I need is a way to queue unfunfilled storage requests, and to be notified when storage is liberated. I can set a promise with a handle to that storage when that happens, and that will trigger the remainder of the processing pipeline.
  • For loadInputs, I may want to use asynchronous IO, but that does not mean that I'll have to spawn one thread per IO request. Instead, I can just submit a bunch of IO requests to a number of centralized IO classes, get futures in return, and return the union of these futures (as computed by boost::when_all) as my result. Future unwrapping will then ensure that my result future is ready once the union of IO futures is ready.
  • I don't know what the user-provided function is doing, but I know it to be cpu-intensive, so I'm going to schedule it on some multithreaded executor in order to leverage all those CPU cores that I paid for. Because those executors us a thread pool pattern, I can be confident that no extra thread will be spawned as a result of this.
  • Finally, writeOutput can be structured like loadInputs: start asynchronous IO, get futures in return, and return the union of these IO futures as a result.

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?

  • boost::launch::deferred forces me to call .get() on my output futures in order to start the processing, thusly blocking my scheduling thread. The reason I'm bothering with an asynchronous architecture is that I don't want to do that.
  • boost::launch::executor means that I need to define some executor specifically for my scheduling continuations, which as mentioned previously are pretty short. Overhead aside, this means that I need to declare this executor as a (semi-)global variable or create one for every component that can potentially attach a synchronous continuation to a future.
  • boost::launch::inherit would probably be undefined behaviour here since my original future is set by a promise, and not by an asynchronous task originating from some launch policy.

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:

  • If .then() is called on a ready future, run the continuation immediately.
  • If .then() is called on a non-ready future, schedule the continuation to be run on the thread that will set the associated promise.

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?

can't put std::thread in vector of struct with other thread-related stuff, or class

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.

  • need to be able to instantiate an empty object at the start and fill in thread function and run it and
  • maybe even close it later, even within a struct.
  • constructor should not require running and configuring the thread upon instantiation.
  • std::thread.nativeHandle() should allow someone to CloseHandle() on windows.

VS 2017.4 Preview deadlock in sync_pq_multi_thread_p_lib.exe

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.

feature request: processor counts

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.

mingw-w64: wants to use libpthreadGC2.a, why not libpthread.a?

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.

Travis failures with std::thread

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

Windows MSYS2 GCC problem at building

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...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.