41 changes: 41 additions & 0 deletions appveyor.yml
@@ -0,0 +1,41 @@
# Copyright 2016, 2017 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)

version: 1.0.{build}-{branch}

shallow_clone: true

branches:
only:
- master
- develop
- /feature\/.*/

environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
TOOLSET: msvc-12.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-14.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1

install:
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- cd ..
- git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\thread\
- python tools/boostdep/depinst/depinst.py thread
- cmd /c bootstrap
- b2 headers

build: off

test_script:
- b2 libs/mp11/test toolset=%TOOLSET%
93 changes: 8 additions & 85 deletions doc/async_executors.qbk
@@ -1,5 +1,5 @@
[/
/ Copyright (c) 2014-2015 Vicente J. Botet Escriba
/ Copyright (c) 2014-2017 Vicente J. Botet Escriba
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Expand Down Expand Up @@ -481,7 +481,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
[/////////////////////////]
[section:work Class `work`]

#include <boost/thread/work.hpp>
#include <boost/thread/executors/work.hpp>
namespace boost {
typedef 'implementation_defined' work;
}
Expand All @@ -499,7 +499,7 @@ If invoked closure throws an exception the executor will call std::terminate, as

Executor abstract base class.

#include <boost/thread/executor.hpp>
#include <boost/thread/executors/executor.hpp>
namespace boost {
class executor
{
Expand Down Expand Up @@ -564,7 +564,7 @@ Executor abstract base class.

Polymorphic adaptor of a model of Executor to an executor.

#include <boost/thread/executor.hpp>
#include <boost/thread/executors/executor.hpp>
namespace boost {
template <typename Executor>
class executor_adaptor : public executor
Expand Down Expand Up @@ -643,7 +643,7 @@ Polymorphic adaptor of a model of Executor to an executor.

Executor abstract base class.

#include <boost/thread/generic_executor_ref.hpp>
#include <boost/thread/executors/generic_executor_ref.hpp>
namespace boost {
class generic_executor_ref
{
Expand Down Expand Up @@ -1333,7 +1333,7 @@ Executor providing time related functions.

A serial executor ensuring that there are no two work units that executes concurrently.

#include <boost/thread/serial_executor.hpp>
#include <boost/thread/executors/serial_executor.hpp>
namespace boost {
template <class Executor>
class serial_executor
Expand Down Expand Up @@ -1404,83 +1404,6 @@ A serial executor ensuring that there are no two work units that executes concur
]


[endsect]

[endsect]

[//////////////////////////////////////////////////////////]
[section:generic_serial_executor Class `generic_serial_executor`]

A serial executor ensuring that there are no two work units that executes concurrently.

#include <boost/thread/generic_serial_executor.hpp>
namespace boost {
class generic_serial_executor
{
public:
generic_serial_executor(generic_serial_executor const&) = delete;
generic_serial_executor& operator=(generic_serial_executor const&) = delete;

template <class Executor>
generic_serial_executor(Executor& ex);

generic_executor_ref& underlying_executor() noexcept;

void close();
bool closed();

template <typename Closure>
void submit(Closure&& closure);

bool try_executing_one();
template <typename Pred>
bool reschedule_until(Pred const& pred);

};
}

[/////////////////////////////////////]
[section:constructor Constructor `generic_serial_executor(Executor&)`]

template <class Executor>
generic_serial_executor(Executor& ex);

[variablelist

[[Effects:] [Constructs a serial_executor. ]]

[[Throws:] [Nothing. ]]

]


[endsect]
[/////////////////////////////////////]
[section:destructor Destructor `~serial_executor()`]

~generic_serial_executor();

[variablelist

[[Effects:] [Destroys the serial_executor.]]

[[Synchronization:] [The completion of all the closures happen before the completion of the executor destructor.]]

]

[endsect]
[/////////////////////////////////////]
[section:underlying_executor Function member `underlying_executor()`]

Executor& underlying_executor() noexcept;

[variablelist

[[Return:] [The underlying executor instance. ]]

]


[endsect]

[endsect]
Expand All @@ -1491,7 +1414,7 @@ A serial executor ensuring that there are no two work units that executes concur

A serial executor ensuring that there are no two work units that executes concurrently.

#include <boost/thread/inline_executor.hpp>
#include <boost/thread/executors/inline_executor.hpp>
namespace boost {
class inline_executor
{
Expand Down Expand Up @@ -1675,7 +1598,7 @@ A thread_executor with a threads for each task.

A user scheduled executor.

#include <boost/thread/loop_executor.hpp>
#include <boost/thread/executors/loop_executor.hpp>
namespace boost {
class loop_executor
{
Expand Down
8 changes: 8 additions & 0 deletions doc/changes.qbk
Expand Up @@ -23,10 +23,18 @@ Please take a look at [@http://www.boost.org/development/tests/master/developer/

[*Fixed Bugs:]

* [@http://svn.boost.org/trac/boost/ticket/12976 #12976] Boost Thread Executors documentation mistakes
* [@http://svn.boost.org/trac/boost/ticket/12949 #12949] using sleep_for in a thread context without including boost/thread/thread.hpp yields incorrect behaviour when BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC is defined
* [@http://svn.boost.org/trac/boost/ticket/13019 #13019] ABI compatibility for BOOST_THREAD_PROVIDES_INTERRUPTIONS incomplete
* [@http://svn.boost.org/trac/boost/ticket/13163 #13163] boost::detail::heap_new does not have a variadic variant

[*New Experimental Features:]


[heading Version 4.7.5 - boost 1.65.1]

[*Fixed Bugs:]

* [@https://github.com/boostorg/thread/issues/130 #130] windows: Bug in boost::condition_variable on Windows

[heading Version 4.7.4 - boost 1.65]
Expand Down
14 changes: 11 additions & 3 deletions include/boost/thread/executors/basic_thread_pool.hpp
Expand Up @@ -86,11 +86,18 @@ namespace executors
for(;;)
{
work task;
queue_op_status st = work_queue.wait_pull(task);
if (st == queue_op_status::closed) {
try
{
queue_op_status st = work_queue.wait_pull(task);
if (st == queue_op_status::closed) {
return;
}
task();
}
catch (boost::thread_interrupted&)
{
return;
}
task();
}
}
catch (...)
Expand Down Expand Up @@ -234,6 +241,7 @@ namespace executors
{
for (unsigned i = 0; i < threads.size(); ++i)
{
threads[i].interrupt();
threads[i].join();
}
}
Expand Down
14 changes: 10 additions & 4 deletions include/boost/thread/executors/detail/priority_executor_base.hpp
Expand Up @@ -57,10 +57,16 @@ namespace detail
{
for(;;)
{
work task;
queue_op_status st = _workq.wait_pull(task);
if (st == queue_op_status::closed) return;
task();
try {
work task;
queue_op_status st = _workq.wait_pull(task);
if (st == queue_op_status::closed) return;
task();
}
catch (boost::thread_interrupted&)
{
return;
}
}
}
catch (...)
Expand Down
1 change: 1 addition & 0 deletions include/boost/thread/executors/scheduled_thread_pool.hpp
Expand Up @@ -32,6 +32,7 @@ namespace executors
~scheduled_thread_pool()
{
this->close();
_workers.interrupt_all();
_workers.join_all();
}

Expand Down
1 change: 1 addition & 0 deletions include/boost/thread/executors/scheduler.hpp
Expand Up @@ -231,6 +231,7 @@ namespace boost
~scheduler()
{
this->close();
thr.interrupt();
thr.join();
}
template <class Ex>
Expand Down
9 changes: 5 additions & 4 deletions include/boost/thread/executors/scheduling_adaptor.hpp
Expand Up @@ -16,21 +16,22 @@ namespace executors
{

template <typename Executor>
class scheduling_adpator : public detail::scheduled_executor_base<>
class scheduling_adaptor : public detail::scheduled_executor_base<>
{
private:
Executor& _exec;
thread _scheduler;
public:

scheduling_adpator(Executor& ex)
scheduling_adaptor(Executor& ex)
: super(),
_exec(ex),
_scheduler(&super::loop, this) {}

~scheduling_adpator()
~scheduling_adaptor()
{
this->close();
_scheduler.interrupt();
_scheduler.join();
}

Expand All @@ -45,7 +46,7 @@ namespace executors

} //end executors

using executors::scheduling_adpator;
using executors::scheduling_adaptor;

} //end boost
#endif
10 changes: 5 additions & 5 deletions include/boost/thread/win32/basic_recursive_mutex.hpp
Expand Up @@ -44,13 +44,13 @@ namespace boost

bool try_lock() BOOST_NOEXCEPT
{
long const current_thread_id=win32::GetCurrentThreadId();
long const current_thread_id=boost::detail::winapi::GetCurrentThreadId();
return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id);
}

void lock()
{
long const current_thread_id=win32::GetCurrentThreadId();
long const current_thread_id=boost::detail::winapi::GetCurrentThreadId();
if(!try_recursive_lock(current_thread_id))
{
mutex.lock();
Expand All @@ -61,7 +61,7 @@ namespace boost
#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(::boost::system_time const& target)
{
long const current_thread_id=win32::GetCurrentThreadId();
long const current_thread_id=boost::detail::winapi::GetCurrentThreadId();
return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target);
}
template<typename Duration>
Expand All @@ -75,13 +75,13 @@ namespace boost
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
long const current_thread_id=win32::GetCurrentThreadId();
long const current_thread_id=boost::detail::winapi::GetCurrentThreadId();
return try_recursive_lock(current_thread_id) || try_timed_lock_for(current_thread_id,rel_time);
}
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
{
long const current_thread_id=win32::GetCurrentThreadId();
long const current_thread_id=boost::detail::winapi::GetCurrentThreadId();
return try_recursive_lock(current_thread_id) || try_timed_lock_until(current_thread_id,t);
}
#endif
Expand Down
14 changes: 7 additions & 7 deletions include/boost/thread/win32/basic_timed_mutex.hpp
Expand Up @@ -55,7 +55,7 @@ namespace boost
#endif
if(old_event)
{
win32::CloseHandle(old_event);
winapi::CloseHandle(old_event);
}
}

Expand All @@ -81,9 +81,9 @@ namespace boost

do
{
unsigned const retval(win32::WaitForSingleObjectEx(sem, ::boost::detail::win32::infinite,0));
unsigned const retval(winapi::WaitForSingleObjectEx(sem, ::boost::detail::win32::infinite,0));
BOOST_VERIFY(0 == retval || ::boost::detail::win32::wait_abandoned == retval);
// BOOST_VERIFY(win32::WaitForSingleObject(
// BOOST_VERIFY(winapi::WaitForSingleObject(
// sem,::boost::detail::win32::infinite)==0);
clear_waiting_and_try_lock(old_count);
lock_acquired=!(old_count&lock_flag_value);
Expand Down Expand Up @@ -142,7 +142,7 @@ namespace boost

do
{
if(win32::WaitForSingleObjectEx(sem,::boost::detail::get_milliseconds_until(wait_until),0)!=0)
if(winapi::WaitForSingleObjectEx(sem,::boost::detail::get_milliseconds_until(wait_until),0)!=0)
{
BOOST_INTERLOCKED_DECREMENT(&active_count);
return false;
Expand Down Expand Up @@ -210,7 +210,7 @@ namespace boost
}
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-now);

if(win32::WaitForSingleObjectEx(sem,static_cast<unsigned long>(rel_time.count()),0)!=0)
if(winapi::WaitForSingleObjectEx(sem,static_cast<unsigned long>(rel_time.count()),0)!=0)
{
BOOST_INTERLOCKED_DECREMENT(&active_count);
return false;
Expand All @@ -232,7 +232,7 @@ namespace boost
{
if(!win32::interlocked_bit_test_and_set(&active_count,event_set_flag_bit))
{
win32::SetEvent(get_event());
winapi::SetEvent(get_event());
}
}
}
Expand All @@ -256,7 +256,7 @@ namespace boost
#endif
if(old_event!=0)
{
win32::CloseHandle(new_event);
winapi::CloseHandle(new_event);
return old_event;
}
else
Expand Down
6 changes: 3 additions & 3 deletions include/boost/thread/win32/condition_variable.hpp
Expand Up @@ -76,7 +76,7 @@ namespace boost
void release(unsigned count_to_release)
{
notified=true;
detail::win32::ReleaseSemaphore(semaphore,count_to_release,0);
detail::winapi::ReleaseSemaphore(semaphore,count_to_release,0);
}

void release_waiters()
Expand All @@ -96,7 +96,7 @@ namespace boost

bool woken()
{
unsigned long const woken_result=detail::win32::WaitForSingleObjectEx(wake_sem,0,0);
unsigned long const woken_result=detail::winapi::WaitForSingleObjectEx(wake_sem,0,0);
BOOST_ASSERT((woken_result==detail::win32::timeout) || (woken_result==0));
return woken_result==0;
}
Expand Down Expand Up @@ -135,7 +135,7 @@ namespace boost
void wake_waiters(long count_to_wake)
{
detail::interlocked_write_release(&total_count,total_count-count_to_wake);
detail::win32::ReleaseSemaphore(wake_sem,count_to_wake,0);
detail::winapi::ReleaseSemaphore(wake_sem,count_to_wake,0);
}

template<typename lock_type>
Expand Down
50 changes: 25 additions & 25 deletions include/boost/thread/win32/once.hpp
Expand Up @@ -124,7 +124,7 @@ namespace boost
std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name));
detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address),
mutex_name + once_mutex_name_fixed_length);
detail::int_to_string(win32::GetCurrentProcessId(),
detail::int_to_string(winapi::GetCurrentProcessId(),
mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2);
}

Expand All @@ -136,9 +136,9 @@ namespace boost
}

#ifdef BOOST_NO_ANSI_APIS
return ::boost::detail::win32::OpenEventW(
return ::boost::detail::winapi::OpenEventW(
#else
return ::boost::detail::win32::OpenEventA(
return ::boost::detail::winapi::OpenEventA(
#endif
::boost::detail::win32::synchronize |
::boost::detail::win32::event_modify_state,
Expand Down Expand Up @@ -186,7 +186,7 @@ namespace boost
}
if(ctx.event_handle)
{
::boost::detail::win32::ResetEvent(ctx.event_handle);
::boost::detail::winapi::ResetEvent(ctx.event_handle);
}
return true;
}
Expand All @@ -207,7 +207,7 @@ namespace boost
}
if(ctx.event_handle)
{
::boost::detail::win32::SetEvent(ctx.event_handle);
::boost::detail::winapi::SetEvent(ctx.event_handle);
}
}
inline void rollback_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT
Expand All @@ -219,7 +219,7 @@ namespace boost
}
if(ctx.event_handle)
{
::boost::detail::win32::SetEvent(ctx.event_handle);
::boost::detail::winapi::SetEvent(ctx.event_handle);
}
}
}
Expand Down Expand Up @@ -264,7 +264,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite, 0));
}
}
Expand Down Expand Up @@ -308,7 +308,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -355,7 +355,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -400,7 +400,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -443,7 +443,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -486,7 +486,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -529,7 +529,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -574,7 +574,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -617,7 +617,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -660,7 +660,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -703,7 +703,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -748,7 +748,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -793,7 +793,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -839,7 +839,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -886,7 +886,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -930,7 +930,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -977,7 +977,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -1024,7 +1024,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down Expand Up @@ -1073,7 +1073,7 @@ namespace boost
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
ctx.event_handle,::boost::detail::win32::infinite,0));
}
}
Expand Down
30 changes: 15 additions & 15 deletions include/boost/thread/win32/shared_mutex.hpp
Expand Up @@ -67,19 +67,19 @@ namespace boost
{
if(old_state.exclusive_waiting)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0);
BOOST_VERIFY(detail::winapi::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0);
}

if(old_state.shared_waiting || old_state.exclusive_waiting)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
BOOST_VERIFY(detail::winapi::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
}
}
void release_shared_waiters(state_data old_state)
{
if(old_state.shared_waiting || old_state.exclusive_waiting)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
BOOST_VERIFY(detail::winapi::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
}
}

Expand Down Expand Up @@ -107,9 +107,9 @@ namespace boost

~shared_mutex()
{
detail::win32::CloseHandle(upgrade_sem);
detail::win32::CloseHandle(semaphores[unlock_sem]);
detail::win32::CloseHandle(semaphores[exclusive_sem]);
detail::winapi::CloseHandle(upgrade_sem);
detail::winapi::CloseHandle(semaphores[unlock_sem]);
detail::winapi::CloseHandle(semaphores[exclusive_sem]);
}

bool try_lock_shared()
Expand Down Expand Up @@ -191,7 +191,7 @@ namespace boost
return true;
}

unsigned long const res=detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until), 0);
unsigned long const res=detail::winapi::WaitForSingleObjectEx(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until), 0);
if(res==detail::win32::timeout)
{
for(;;)
Expand Down Expand Up @@ -296,7 +296,7 @@ namespace boost
unsigned long res;
if (tp>n) {
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-n);
res=detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],
res=detail::winapi::WaitForSingleObjectEx(semaphores[unlock_sem],
static_cast<unsigned long>(rel_time.count()), 0);
} else {
res=detail::win32::timeout;
Expand Down Expand Up @@ -375,7 +375,7 @@ namespace boost
{
if(old_state.upgrade)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(upgrade_sem,1,0)!=0);
BOOST_VERIFY(detail::winapi::ReleaseSemaphore(upgrade_sem,1,0)!=0);
}
else
{
Expand Down Expand Up @@ -474,7 +474,7 @@ namespace boost
#else
const bool wait_all = false;
#endif
unsigned long const wait_res=detail::win32::WaitForMultipleObjectsEx(2,semaphores,wait_all,::boost::detail::get_milliseconds_until(wait_until), 0);
unsigned long const wait_res=detail::winapi::WaitForMultipleObjectsEx(2,semaphores,wait_all,::boost::detail::get_milliseconds_until(wait_until), 0);
if(wait_res==detail::win32::timeout)
{
for(;;)
Expand All @@ -500,7 +500,7 @@ namespace boost
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if (must_notify)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
BOOST_VERIFY(detail::winapi::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
}

if(current_state==old_state)
Expand Down Expand Up @@ -586,7 +586,7 @@ namespace boost
unsigned long wait_res;
if (tp>n) {
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
wait_res=detail::win32::WaitForMultipleObjectsEx(2,semaphores,wait_all,
wait_res=detail::winapi::WaitForMultipleObjectsEx(2,semaphores,wait_all,
static_cast<unsigned long>(rel_time.count()), 0);
} else {
wait_res=detail::win32::timeout;
Expand Down Expand Up @@ -616,7 +616,7 @@ namespace boost
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if (must_notify)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
BOOST_VERIFY(detail::winapi::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
}
if(current_state==old_state)
{
Expand Down Expand Up @@ -698,7 +698,7 @@ namespace boost
return;
}

BOOST_VERIFY(!detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],detail::win32::infinite, 0));
BOOST_VERIFY(!detail::winapi::WaitForSingleObjectEx(semaphores[unlock_sem],detail::winapi::infinite, 0));
}
}

Expand Down Expand Up @@ -790,7 +790,7 @@ namespace boost
{
if(!last_reader)
{
BOOST_VERIFY(!detail::win32::WaitForSingleObjectEx(upgrade_sem,detail::win32::infinite, 0));
BOOST_VERIFY(!detail::winapi::WaitForSingleObjectEx(upgrade_sem,detail::win32::infinite, 0));
}
break;
}
Expand Down
2 changes: 1 addition & 1 deletion include/boost/thread/win32/thread_data.hpp
Expand Up @@ -153,7 +153,7 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
void interrupt()
{
BOOST_VERIFY(detail::win32::SetEvent(interruption_handle)!=0);
BOOST_VERIFY(detail::winapi::SetEvent(interruption_handle)!=0);
}
#endif
typedef detail::win32::handle native_handle_type;
Expand Down
44 changes: 3 additions & 41 deletions include/boost/thread/win32/thread_heap_alloc.hpp
Expand Up @@ -12,45 +12,7 @@
#include <boost/throw_exception.hpp>
#include <boost/core/no_exceptions_support.hpp>

#if defined( BOOST_USE_WINDOWS_H )
# include <windows.h>

namespace boost
{
namespace detail
{
namespace win32
{
using ::GetProcessHeap;
using ::HeapAlloc;
using ::HeapFree;
}
}
}

#else

# ifdef HeapAlloc
# undef HeapAlloc
# endif

namespace boost
{
namespace detail
{
namespace win32
{
extern "C"
{
__declspec(dllimport) handle __stdcall GetProcessHeap();
__declspec(dllimport) void* __stdcall HeapAlloc(handle,unsigned long,ulong_ptr);
__declspec(dllimport) int __stdcall HeapFree(handle,unsigned long,void*);
}
}
}
}

#endif
#include <boost/detail/winapi/heap_memory.hpp>

#include <boost/config/abi_prefix.hpp>

Expand All @@ -60,7 +22,7 @@ namespace boost
{
inline void* allocate_raw_heap_memory(unsigned size)
{
void* const heap_memory=detail::win32::HeapAlloc(detail::win32::GetProcessHeap(),0,size);
void* const heap_memory=detail::winapi::HeapAlloc(detail::winapi::GetProcessHeap(),0,size);
if(!heap_memory)
{
boost::throw_exception(std::bad_alloc());
Expand All @@ -70,7 +32,7 @@ namespace boost

inline void free_raw_heap_memory(void* heap_memory)
{
BOOST_VERIFY(detail::win32::HeapFree(detail::win32::GetProcessHeap(),0,heap_memory)!=0);
BOOST_VERIFY(detail::winapi::HeapFree(detail::winapi::GetProcessHeap(),0,heap_memory)!=0);
}
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) && ! defined (BOOST_NO_CXX11_RVALUE_REFERENCES)
template<typename T,typename... Args>
Expand Down
248 changes: 46 additions & 202 deletions include/boost/thread/win32/thread_primitives.hpp
Expand Up @@ -17,6 +17,21 @@
#include <boost/thread/exceptions.hpp>
#include <boost/detail/interlocked.hpp>
#include <boost/detail/winapi/config.hpp>

#include <boost/detail/winapi/semaphore.hpp>
#include <boost/detail/winapi/dll.hpp>
#include <boost/detail/winapi/system.hpp>
#include <boost/detail/winapi/time.hpp>
#include <boost/detail/winapi/event.hpp>
#include <boost/detail/winapi/thread.hpp>
#include <boost/detail/winapi/get_current_thread.hpp>
#include <boost/detail/winapi/get_current_thread_id.hpp>
#include <boost/detail/winapi/get_current_process.hpp>
#include <boost/detail/winapi/get_current_process_id.hpp>
#include <boost/detail/winapi/wait.hpp>
#include <boost/detail/winapi/handles.hpp>
#include <boost/detail/winapi/access_rights.hpp>

//#include <boost/detail/winapi/synchronization.hpp>
#include <boost/thread/win32/interlocked_read.hpp>
#include <algorithm>
Expand All @@ -25,200 +40,29 @@
#include <thread>
#endif

#if defined( BOOST_USE_WINDOWS_H )
# include <windows.h>

namespace boost
{
namespace detail
{
namespace win32
{
typedef HANDLE handle;
typedef SYSTEM_INFO system_info;
typedef unsigned __int64 ticks_type;
typedef FARPROC farproc_t;
unsigned const infinite=INFINITE;
unsigned const timeout=WAIT_TIMEOUT;
handle const invalid_handle_value=INVALID_HANDLE_VALUE;
unsigned const event_modify_state=EVENT_MODIFY_STATE;
unsigned const synchronize=SYNCHRONIZE;
unsigned const wait_abandoned=WAIT_ABANDONED;
unsigned const create_event_initial_set = 0x00000002;
unsigned const create_event_manual_reset = 0x00000001;
unsigned const event_all_access = EVENT_ALL_ACCESS;
unsigned const semaphore_all_access = SEMAPHORE_ALL_ACCESS;


# ifdef BOOST_NO_ANSI_APIS
# if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
using ::CreateMutexW;
using ::CreateEventW;
using ::CreateSemaphoreW;
# else
using ::CreateMutexExW;
using ::CreateEventExW;
using ::CreateSemaphoreExW;
# endif
using ::OpenEventW;
using ::GetModuleHandleW;
# else
using ::CreateMutexA;
using ::CreateEventA;
using ::OpenEventA;
using ::CreateSemaphoreA;
using ::GetModuleHandleA;
# endif
#if BOOST_PLAT_WINDOWS_RUNTIME
using ::GetNativeSystemInfo;
using ::GetTickCount64;
#else
using ::GetSystemInfo;
using ::GetTickCount;
#endif
using ::CloseHandle;
using ::ReleaseMutex;
using ::ReleaseSemaphore;
using ::SetEvent;
using ::ResetEvent;
using ::WaitForMultipleObjectsEx;
using ::WaitForSingleObjectEx;
using ::GetCurrentProcessId;
using ::GetCurrentThreadId;
using ::GetCurrentThread;
using ::GetCurrentProcess;
using ::DuplicateHandle;
#if !BOOST_PLAT_WINDOWS_RUNTIME
using ::SleepEx;
using ::Sleep;
using ::QueueUserAPC;
using ::GetProcAddress;
#endif
}
}
}
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )

# ifdef UNDER_CE
# ifndef WINAPI
# ifndef _WIN32_WCE_EMULATION
# define WINAPI __cdecl // Note this doesn't match the desktop definition
# else
# define WINAPI __stdcall
# endif
# endif

# ifdef __cplusplus
extern "C" {
# endif
typedef int BOOL;
typedef unsigned long DWORD;
typedef void* HANDLE;
# include <kfuncs.h>
# ifdef __cplusplus
}
# endif
# endif

# ifdef __cplusplus
extern "C" {
# endif
struct _SYSTEM_INFO;
# ifdef __cplusplus
}
#endif

namespace boost
{
namespace detail
{
namespace win32
{
# ifdef _WIN64
typedef unsigned __int64 ulong_ptr;
# else
typedef unsigned long ulong_ptr;
# endif
typedef void* handle;
typedef _SYSTEM_INFO system_info;
typedef ::boost::detail::winapi::HANDLE_ handle;
typedef ::boost::detail::winapi::SYSTEM_INFO_ system_info;
typedef unsigned __int64 ticks_type;
typedef int (__stdcall *farproc_t)();
unsigned const infinite=~0U;
unsigned const timeout=258U;
handle const invalid_handle_value=(handle)(-1);
unsigned const event_modify_state=2;
unsigned const synchronize=0x100000u;
unsigned const wait_abandoned=0x00000080u;
typedef ::boost::detail::winapi::FARPROC_ farproc_t;
unsigned const infinite=::boost::detail::winapi::INFINITE_;
unsigned const timeout=::boost::detail::winapi::WAIT_TIMEOUT_;
handle const invalid_handle_value=::boost::detail::winapi::INVALID_HANDLE_VALUE_;
unsigned const event_modify_state=::boost::detail::winapi::EVENT_MODIFY_STATE_;
unsigned const synchronize=::boost::detail::winapi::SYNCHRONIZE_;
unsigned const wait_abandoned=::boost::detail::winapi::WAIT_ABANDONED_;
unsigned const create_event_initial_set = 0x00000002;
unsigned const create_event_manual_reset = 0x00000001;
unsigned const event_all_access = 0x1F0003;
unsigned const semaphore_all_access = 0x1F0003;

extern "C"
{
struct _SECURITY_ATTRIBUTES;
# ifdef BOOST_NO_ANSI_APIS
# if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
__declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*);
__declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*);
__declspec(dllimport) void* __stdcall CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*);
# else
__declspec(dllimport) void* __stdcall CreateMutexExW(_SECURITY_ATTRIBUTES*,wchar_t const*,unsigned long,unsigned long);
__declspec(dllimport) void* __stdcall CreateEventExW(_SECURITY_ATTRIBUTES*,wchar_t const*,unsigned long,unsigned long);
__declspec(dllimport) void* __stdcall CreateSemaphoreExW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*,unsigned long,unsigned long);
# endif
__declspec(dllimport) void* __stdcall OpenEventW(unsigned long,int,wchar_t const*);
__declspec(dllimport) void* __stdcall GetModuleHandleW(wchar_t const*);
# else
__declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*);
__declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*);
__declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*);
__declspec(dllimport) void* __stdcall OpenEventA(unsigned long,int,char const*);
__declspec(dllimport) void* __stdcall GetModuleHandleA(char const*);
# endif
#if BOOST_PLAT_WINDOWS_RUNTIME
__declspec(dllimport) void __stdcall GetNativeSystemInfo(_SYSTEM_INFO*);
__declspec(dllimport) ticks_type __stdcall GetTickCount64();
#else
__declspec(dllimport) void __stdcall GetSystemInfo(_SYSTEM_INFO*);
__declspec(dllimport) unsigned long __stdcall GetTickCount();
#endif
__declspec(dllimport) int __stdcall CloseHandle(void*);
__declspec(dllimport) int __stdcall ReleaseMutex(void*);
__declspec(dllimport) unsigned long __stdcall WaitForSingleObjectEx(void*,unsigned long,int);
__declspec(dllimport) unsigned long __stdcall WaitForMultipleObjectsEx(unsigned long nCount,void* const * lpHandles,int bWaitAll,unsigned long dwMilliseconds,int bAlertable);
__declspec(dllimport) int __stdcall ReleaseSemaphore(void*,long,long*);
__declspec(dllimport) int __stdcall DuplicateHandle(void*,void*,void*,void**,unsigned long,int,unsigned long);
#if !BOOST_PLAT_WINDOWS_RUNTIME
__declspec(dllimport) unsigned long __stdcall SleepEx(unsigned long,int);
__declspec(dllimport) void __stdcall Sleep(unsigned long);
typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr);
__declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr);
__declspec(dllimport) farproc_t __stdcall GetProcAddress(void *, const char *);
#endif

# ifndef UNDER_CE
__declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
__declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
__declspec(dllimport) void* __stdcall GetCurrentThread();
__declspec(dllimport) void* __stdcall GetCurrentProcess();
__declspec(dllimport) int __stdcall SetEvent(void*);
__declspec(dllimport) int __stdcall ResetEvent(void*);
# else
using ::GetCurrentProcessId;
using ::GetCurrentThreadId;
using ::GetCurrentThread;
using ::GetCurrentProcess;
using ::SetEvent;
using ::ResetEvent;
# endif
}
unsigned const event_all_access = ::boost::detail::winapi::EVENT_ALL_ACCESS_;
unsigned const semaphore_all_access = boost::detail::winapi::SEMAPHORE_ALL_ACCESS_;
}
}
}
#else
# error "Win32 functions not available"
#endif

#include <boost/config/abi_prefix.hpp>

Expand Down Expand Up @@ -250,7 +94,7 @@ namespace boost
ticks_type current_tick64;

previous_count = (unsigned long) boost::detail::interlocked_read_acquire(&count);
current_tick32 = GetTickCount();
current_tick32 = ::boost::detail::winapi::GetTickCount();

if(previous_count == (unsigned long)-1l)
{
Expand Down Expand Up @@ -302,13 +146,13 @@ namespace boost
// GetTickCount and GetModuleHandle are not allowed in the Windows Runtime,
// and kernel32 isn't used in Windows Phone.
#if BOOST_PLAT_WINDOWS_RUNTIME
gettickcount64impl = &GetTickCount64;
gettickcount64impl = &::boost::detail::winapi::GetTickCount64;
#else
farproc_t addr=GetProcAddress(
#if !defined(BOOST_NO_ANSI_APIS)
GetModuleHandleA("KERNEL32.DLL"),
::boost::detail::winapi::GetModuleHandleA("KERNEL32.DLL"),
#else
GetModuleHandleW(L"KERNEL32.DLL"),
::boost::detail::winapi::GetModuleHandleW(L"KERNEL32.DLL"),
#endif
"GetTickCount64");
if(addr)
Expand Down Expand Up @@ -341,11 +185,11 @@ namespace boost
initial_event_state state)
{
#if !defined(BOOST_NO_ANSI_APIS)
handle const res = win32::CreateEventA(0, type, state, mutex_name);
handle const res = ::boost::detail::winapi::CreateEventA(0, type, state, mutex_name);
#elif BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
handle const res = win32::CreateEventW(0, type, state, mutex_name);
handle const res = ::boost::detail::winapi::CreateEventW(0, type, state, mutex_name);
#else
handle const res = win32::CreateEventExW(
handle const res = ::boost::detail::winapi::CreateEventExW(
0,
mutex_name,
type ? create_event_manual_reset : 0 | state ? create_event_initial_set : 0,
Expand All @@ -367,12 +211,12 @@ namespace boost
inline handle create_anonymous_semaphore_nothrow(long initial_count,long max_count)
{
#if !defined(BOOST_NO_ANSI_APIS)
handle const res=win32::CreateSemaphoreA(0,initial_count,max_count,0);
handle const res=::boost::detail::winapi::CreateSemaphoreA(0,initial_count,max_count,0);
#else
#if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
handle const res=win32::CreateSemaphoreEx(0,initial_count,max_count,0,0);
handle const res=::boost::detail::winapi::CreateSemaphoreEx(0,initial_count,max_count,0,0);
#else
handle const res=win32::CreateSemaphoreExW(0,initial_count,max_count,0,0,semaphore_all_access);
handle const res=::boost::detail::winapi::CreateSemaphoreExW(0,initial_count,max_count,0,0,semaphore_all_access);
#endif
#endif
return res;
Expand All @@ -390,10 +234,10 @@ namespace boost

inline handle duplicate_handle(handle source)
{
handle const current_process=GetCurrentProcess();
handle const current_process=::boost::detail::winapi::GetCurrentProcess();
long const same_access_flag=2;
handle new_handle=0;
bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
bool const success=::boost::detail::winapi::DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
if(!success)
{
boost::throw_exception(thread_resource_error());
Expand All @@ -403,15 +247,15 @@ namespace boost

inline void release_semaphore(handle semaphore,long count)
{
BOOST_VERIFY(ReleaseSemaphore(semaphore,count,0)!=0);
BOOST_VERIFY(::boost::detail::winapi::ReleaseSemaphore(semaphore,count,0)!=0);
}

inline void get_system_info(system_info *info)
{
#if BOOST_PLAT_WINDOWS_RUNTIME
win32::GetNativeSystemInfo(info);
::boost::detail::winapi::GetNativeSystemInfo(info);
#else
win32::GetSystemInfo(info);
::boost::detail::winapi::GetSystemInfo(info);
#endif
}

Expand All @@ -422,15 +266,15 @@ namespace boost
#if BOOST_PLAT_WINDOWS_RUNTIME
std::this_thread::yield();
#else
::boost::detail::win32::Sleep(0);
::boost::detail::winapi::Sleep(0);
#endif
}
else
{
#if BOOST_PLAT_WINDOWS_RUNTIME
::boost::detail::win32::WaitForSingleObjectEx(::boost::detail::win32::GetCurrentThread(), milliseconds, 0);
::boost::detail::winapi::WaitForSingleObjectEx(::boost::detail::winapi::GetCurrentThread(), milliseconds, 0);
#else
::boost::detail::win32::Sleep(milliseconds);
::boost::detail::winapi::Sleep(milliseconds);
#endif
}
}
Expand All @@ -446,7 +290,7 @@ namespace boost
{
if (m_completionHandle != ::boost::detail::win32::invalid_handle_value)
{
CloseHandle(m_completionHandle);
::boost::detail::winapi::CloseHandle(m_completionHandle);
}
}

Expand Down Expand Up @@ -474,7 +318,7 @@ namespace boost
{
if(handle_to_manage && handle_to_manage!=invalid_handle_value)
{
BOOST_VERIFY(CloseHandle(handle_to_manage));
BOOST_VERIFY(::boost::detail::winapi::CloseHandle(handle_to_manage));
}
}

Expand Down
14 changes: 7 additions & 7 deletions src/win32/thread.cpp
Expand Up @@ -508,7 +508,7 @@ namespace boost
bool thread::interruption_requested() const BOOST_NOEXCEPT
{
detail::thread_data_ptr local_thread_info=(get_thread_info)();
return local_thread_info.get() && (detail::win32::WaitForSingleObjectEx(local_thread_info->interruption_handle,0,0)==0);
return local_thread_info.get() && (detail::winapi::WaitForSingleObjectEx(local_thread_info->interruption_handle,0,0)==0);
}

#endif
Expand Down Expand Up @@ -738,7 +738,7 @@ namespace boost

if(handle_count)
{
unsigned long const notified_index=detail::win32::WaitForMultipleObjectsEx(handle_count,handles,false,using_timer?INFINITE:time_left.milliseconds, 0);
unsigned long const notified_index=detail::winapi::WaitForMultipleObjectsEx(handle_count,handles,false,using_timer?INFINITE:time_left.milliseconds, 0);
if(notified_index<handle_count)
{
if(notified_index==wait_handle_index)
Expand All @@ -748,7 +748,7 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
else if(notified_index==interruption_index)
{
detail::win32::ResetEvent(detail::get_current_thread_data()->interruption_handle);
detail::winapi::ResetEvent(detail::get_current_thread_data()->interruption_handle);
throw thread_interrupted();
}
#endif
Expand Down Expand Up @@ -823,7 +823,7 @@ namespace boost

if(handle_count)
{
unsigned long const notified_index=detail::win32::WaitForMultipleObjectsEx(handle_count,handles,false,using_timer?INFINITE:time_left.milliseconds, 0);
unsigned long const notified_index=detail::winapi::WaitForMultipleObjectsEx(handle_count,handles,false,using_timer?INFINITE:time_left.milliseconds, 0);
if(notified_index<handle_count)
{
if(notified_index==wait_handle_index)
Expand Down Expand Up @@ -860,7 +860,7 @@ namespace boost
return current_thread_data->id;
}
#endif
return detail::win32::GetCurrentThreadId();
return detail::winapi::GetCurrentThreadId();
#else
return thread::id(get_or_make_current_thread_data());
#endif
Expand All @@ -871,7 +871,7 @@ namespace boost
{
if(interruption_enabled() && interruption_requested())
{
detail::win32::ResetEvent(detail::get_current_thread_data()->interruption_handle);
detail::winapi::ResetEvent(detail::get_current_thread_data()->interruption_handle);
throw thread_interrupted();
}
}
Expand All @@ -883,7 +883,7 @@ namespace boost

bool interruption_requested() BOOST_NOEXCEPT
{
return detail::get_current_thread_data() && (detail::win32::WaitForSingleObjectEx(detail::get_current_thread_data()->interruption_handle,0,0)==0);
return detail::get_current_thread_data() && (detail::winapi::WaitForSingleObjectEx(detail::get_current_thread_data()->interruption_handle,0,0)==0);
}
#endif

Expand Down
56 changes: 37 additions & 19 deletions src/win32/tss_pe.cpp
Expand Up @@ -111,10 +111,28 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU


//Definitions required by implementation

typedef int (__cdecl *_PVFV)();
#define INIRETSUCCESS 0
#define PVAPI int __cdecl
#if (_MSC_VER < 1300) || ((_MSC_VER > 1900) && (_MSC_VER < 1910)) // 1300 == VC++ 7.0, 1900 == VC++ 14.0, 1910 == VC++ 2017
typedef void ( __cdecl *_PVFV_ )();
typedef void ( __cdecl *_PIFV_ )();
#define INIRETSUCCESS_V
#define INIRETSUCCESS_I
#define PVAPI_V void __cdecl
#define PVAPI_I void __cdecl
#elif (_MSC_VER >= 1910)
typedef void ( __cdecl *_PVFV_ )();
typedef int ( __cdecl *_PIFV_ )();
#define INIRETSUCCESS_V
#define INIRETSUCCESS_I 0
#define PVAPI_V void __cdecl
#define PVAPI_I int __cdecl
#else
typedef int ( __cdecl *_PVFV_ )();
typedef int ( __cdecl *_PIFV_ )();
#define INIRETSUCCESS_V 0
#define INIRETSUCCESS_I 0
#define PVAPI_V int __cdecl
#define PVAPI_I int __cdecl
#endif

typedef void (NTAPI* _TLSCB)(HINSTANCE, DWORD, PVOID);

Expand All @@ -130,9 +148,9 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
{
//Forward declarations

static PVAPI on_tls_prepare();
static PVAPI on_process_init();
static PVAPI on_process_term();
static PVAPI_I on_tls_prepare();
static PVAPI_V on_process_init();
static PVAPI_V on_process_term();
static void NTAPI on_tls_callback(HINSTANCE, DWORD, PVOID);

//The .CRT$Xxx information is taken from Codeguru:
Expand All @@ -144,9 +162,9 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
#pragma section(".CRT$XTU",long,read)
#pragma section(".CRT$XLC",long,read)
__declspec(allocate(".CRT$XLC")) _TLSCB __xl_ca=on_tls_callback;
__declspec(allocate(".CRT$XIU"))_PVFV p_tls_prepare = on_tls_prepare;
__declspec(allocate(".CRT$XCU"))_PVFV p_process_init = on_process_init;
__declspec(allocate(".CRT$XTU"))_PVFV p_process_term = on_process_term;
__declspec(allocate(".CRT$XIU"))_PIFV_ p_tls_prepare = on_tls_prepare;
__declspec(allocate(".CRT$XCU"))_PVFV_ p_process_init = on_process_init;
__declspec(allocate(".CRT$XTU"))_PVFV_ p_process_term = on_process_term;
#else
#if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
# pragma data_seg(push, old_seg)
Expand All @@ -158,13 +176,13 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
//this could be changed easily if required.

#pragma data_seg(".CRT$XIU")
static _PVFV p_tls_prepare = on_tls_prepare;
static _PIFV_ p_tls_prepare = on_tls_prepare;
#pragma data_seg()

//Callback after all global ctors.

#pragma data_seg(".CRT$XCU")
static _PVFV p_process_init = on_process_init;
static _PVFV_ p_process_init = on_process_init;
#pragma data_seg()

//Callback for tls notifications.
Expand All @@ -175,7 +193,7 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
//Callback for termination.

#pragma data_seg(".CRT$XTU")
static _PVFV p_process_term = on_process_term;
static _PVFV_ p_process_term = on_process_term;
#pragma data_seg()
#if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
# pragma data_seg(pop, old_seg)
Expand All @@ -187,7 +205,7 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
#pragma warning(disable:4189)
#endif

PVAPI on_tls_prepare()
PVAPI_I on_tls_prepare()
{
//The following line has an important side effect:
//if the TLS directory is not already there, it will
Expand Down Expand Up @@ -222,13 +240,13 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
*pfdst = 0;
#endif

return INIRETSUCCESS;
return INIRETSUCCESS_I;
}
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif

PVAPI on_process_init()
PVAPI_V on_process_init()
{
//Schedule on_thread_exit() to be called for the main
//thread before destructors of global objects have been
Expand All @@ -245,13 +263,13 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU

boost::on_process_enter();

return INIRETSUCCESS;
return INIRETSUCCESS_V;
}

PVAPI on_process_term()
PVAPI_V on_process_term()
{
boost::on_process_exit();
return INIRETSUCCESS;
return INIRETSUCCESS_V;
}

void NTAPI on_tls_callback(HINSTANCE /*h*/, DWORD dwReason, PVOID /*pv*/)
Expand Down
6 changes: 3 additions & 3 deletions test/test_9856.cpp
Expand Up @@ -6,7 +6,7 @@ using namespace boost;

int main() {
atomic<size_t> total(0), failures(0);

#pragma omp parallel shared(total, failures) num_threads(1000)
{
mutex mtx;
Expand All @@ -20,10 +20,10 @@ int main() {
}
if(failures)
std::cout << "There were " << failures << " failures out of " << total << " timed waits." << std::endl;
if((100*failures)/total>10)
if((100*failures)/total>40)
{
std::cerr << "This exceeds 10%, so failing the test." << std::endl;
return 1;
}
return 0;
}
}
2 changes: 1 addition & 1 deletion test/test_scheduling_adaptor.cpp
Expand Up @@ -35,7 +35,7 @@ void fn(int x)
void test_timing(const int n)
{
thread_pool tp(4);
boost::scheduling_adpator<thread_pool> sa(tp);
boost::scheduling_adaptor<thread_pool> sa(tp);
for(int i = 1; i <= n; i++)
{
sa.submit_after(boost::bind(fn,i),seconds(i));
Expand Down