mirror of
https://github.com/boostorg/thread.git
synced 2026-02-03 09:42:16 +00:00
Compare commits
11 Commits
boost-1.78
...
feature/pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fadb514c71 | ||
|
|
30dcb6dcbc | ||
|
|
d56f3f25ad | ||
|
|
52b62ee7b0 | ||
|
|
78af23ca14 | ||
|
|
743d19d7d3 | ||
|
|
7f7faf234d | ||
|
|
1de55fceda | ||
|
|
8db325363b | ||
|
|
f71e0f1645 | ||
|
|
4bc126fc37 |
47
.github/workflows/ci.yml
vendored
47
.github/workflows/ci.yml
vendored
@@ -18,35 +18,58 @@ jobs:
|
||||
matrix:
|
||||
include:
|
||||
- toolset: gcc-4.8
|
||||
os: ubuntu-18.04
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
cxxstd: 11
|
||||
install: g++-4.8
|
||||
- toolset: gcc-5
|
||||
cxxstd: 11
|
||||
os: ubuntu-18.04
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
install: g++-5
|
||||
- toolset: gcc-7
|
||||
os: ubuntu-18.04
|
||||
os: ubuntu-20.04
|
||||
install: g++-7
|
||||
- toolset: gcc-9
|
||||
os: ubuntu-20.04
|
||||
- toolset: gcc-11
|
||||
os: ubuntu-20.04
|
||||
install: g++-11
|
||||
os: ubuntu-22.04
|
||||
- toolset: clang
|
||||
compiler: clang++-12
|
||||
compiler: clang++-15
|
||||
cxxstd: 20
|
||||
os: ubuntu-20.04
|
||||
install: clang-12
|
||||
os: ubuntu-22.04
|
||||
install: clang-15
|
||||
- toolset: clang
|
||||
os: macos-10.15
|
||||
os: macos-11
|
||||
cxxstd: 11
|
||||
- toolset: clang
|
||||
os: macos-12
|
||||
cxxstd: 14
|
||||
- toolset: clang
|
||||
os: macos-13
|
||||
cxxstd: 17
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
container: ${{matrix.container}}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup container environment
|
||||
if: matrix.container
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get -y install sudo python3 git g++
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
@@ -66,7 +89,7 @@ jobs:
|
||||
cd boost-root
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
python3 tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
./bootstrap.sh
|
||||
./b2 -d0 headers
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/thread/thread_functors.hpp>
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/thread/detail/thread_interruption.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
@@ -85,6 +86,10 @@ namespace boost
|
||||
*/
|
||||
~strict_scoped_thread()
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// exceptions from a destructor call std::terminate
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
CallableThread on_destructor;
|
||||
|
||||
on_destructor(t_);
|
||||
@@ -188,6 +193,10 @@ namespace boost
|
||||
*/
|
||||
~scoped_thread()
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// exceptions from a destructor call std::terminate
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
CallableThread on_destructor;
|
||||
|
||||
on_destructor(t_);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <boost/thread/detail/delete.hpp>
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/thread/thread_functors.hpp>
|
||||
#include <boost/thread/detail/thread_interruption.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
@@ -34,6 +35,10 @@ namespace boost
|
||||
}
|
||||
~thread_guard()
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// exceptions from a destructor call std::terminate
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
CallableThread on_destructor;
|
||||
|
||||
on_destructor(t_);
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct basic_timed_mutex
|
||||
struct BOOST_THREAD_CAPABILITY("mutex") basic_timed_mutex
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(unsigned char,lock_flag_bit=31);
|
||||
BOOST_STATIC_CONSTANT(unsigned char,event_set_flag_bit=30);
|
||||
@@ -62,12 +62,12 @@ namespace boost
|
||||
}
|
||||
|
||||
// Take the lock flag if it's available
|
||||
bool try_lock() BOOST_NOEXCEPT
|
||||
bool try_lock() BOOST_NOEXCEPT BOOST_THREAD_TRY_ACQUIRE(true)
|
||||
{
|
||||
return !win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit);
|
||||
}
|
||||
|
||||
void lock()
|
||||
void lock() BOOST_THREAD_ACQUIRE()
|
||||
{
|
||||
if(try_lock())
|
||||
{
|
||||
@@ -93,7 +93,7 @@ namespace boost
|
||||
|
||||
// Loop until the number of waiters has been incremented or we've taken the lock flag
|
||||
// The loop is necessary since this function may be called by multiple threads simultaneously
|
||||
void mark_waiting_and_try_lock(long& old_count)
|
||||
void mark_waiting_and_try_lock(long& old_count) BOOST_THREAD_TRY_ACQUIRE(true)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
@@ -117,7 +117,7 @@ namespace boost
|
||||
// until we've taken the lock flag and cleared the event set flag and decremented the
|
||||
// number of waiters
|
||||
// The loop is necessary since this function may be called by multiple threads simultaneously
|
||||
void clear_waiting_and_try_lock(long& old_count)
|
||||
void clear_waiting_and_try_lock(long& old_count) BOOST_THREAD_TRY_ACQUIRE(true)
|
||||
{
|
||||
old_count&=~lock_flag_value;
|
||||
old_count|=event_set_flag_value;
|
||||
@@ -152,7 +152,7 @@ namespace boost
|
||||
}
|
||||
|
||||
template <typename Clock, typename Timepoint, typename Duration>
|
||||
bool do_lock_until(Timepoint const& t, Duration const& max)
|
||||
bool do_lock_until(Timepoint const& t, Duration const& max) BOOST_THREAD_TRY_ACQUIRE(true)
|
||||
{
|
||||
if(try_lock())
|
||||
{
|
||||
@@ -238,7 +238,7 @@ namespace boost
|
||||
}
|
||||
#endif
|
||||
|
||||
void unlock()
|
||||
void unlock() BOOST_THREAD_RELEASE()
|
||||
{
|
||||
// Clear the lock flag using atomic addition (works since long is always 32 bits on Windows)
|
||||
long const old_count=BOOST_INTERLOCKED_EXCHANGE_ADD(&active_count,lock_flag_value);
|
||||
|
||||
@@ -52,7 +52,7 @@ struct get_tick_count64_state
|
||||
BOOST_ALIGNMENT(64) static get_tick_count64_state g_state;
|
||||
|
||||
//! Artifical implementation of GetTickCount64
|
||||
ticks_type WINAPI get_tick_count64()
|
||||
ticks_type BOOST_WINAPI_WINAPI_CC get_tick_count64()
|
||||
{
|
||||
uint64_t old_state = g_state.ticks.load(boost::memory_order_acquire);
|
||||
|
||||
@@ -67,7 +67,7 @@ ticks_type WINAPI get_tick_count64()
|
||||
}
|
||||
|
||||
//! The function is called periodically in the system thread pool to make sure g_state.ticks is timely updated
|
||||
void NTAPI refresh_get_tick_count64(boost::winapi::PVOID_, boost::winapi::BOOLEAN_)
|
||||
void BOOST_WINAPI_NTAPI_CC refresh_get_tick_count64(boost::winapi::PVOID_, boost::winapi::BOOLEAN_)
|
||||
{
|
||||
get_tick_count64();
|
||||
}
|
||||
@@ -88,7 +88,7 @@ void cleanup_get_tick_count64()
|
||||
}
|
||||
}
|
||||
|
||||
ticks_type WINAPI get_tick_count_init()
|
||||
ticks_type BOOST_WINAPI_WINAPI_CC get_tick_count_init()
|
||||
{
|
||||
boost::winapi::HMODULE_ hKernel32 = boost::winapi::GetModuleHandleW(L"kernel32.dll");
|
||||
if (hKernel32)
|
||||
|
||||
@@ -368,6 +368,10 @@ rule generate_self_contained_header_tests
|
||||
[ thread-run test_10964.cpp ]
|
||||
[ thread-test test_11053.cpp ]
|
||||
[ thread-run test_11266.cpp ]
|
||||
[ thread-run test_366_1.cpp ]
|
||||
[ thread-run test_366_2.cpp ]
|
||||
[ thread-run test_366_3.cpp ]
|
||||
[ thread-run test_366_4.cpp ]
|
||||
;
|
||||
|
||||
|
||||
|
||||
37
test/test_366_1.cpp
Normal file
37
test/test_366_1.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include "boost/thread/thread_guard.hpp"
|
||||
#include "boost/thread.hpp"
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <iostream>
|
||||
|
||||
static void inner_thread_func()
|
||||
{
|
||||
boost::this_thread::sleep_for(
|
||||
boost::chrono::hours(1) );
|
||||
}
|
||||
|
||||
static void outer_thread_func()
|
||||
{
|
||||
boost::thread inner( inner_thread_func );
|
||||
boost::thread_guard<boost::interrupt_and_join_if_joinable> guard( inner );
|
||||
}
|
||||
|
||||
static void double_interrupt()
|
||||
{
|
||||
boost::thread outer( outer_thread_func );
|
||||
boost::thread_guard<boost::interrupt_and_join_if_joinable> guard( outer );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST( true ); // perform lwt initialization
|
||||
|
||||
std::cout << "Start" << std::endl;
|
||||
double_interrupt();
|
||||
std::cout << "End" << std::endl;
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
35
test/test_366_2.cpp
Normal file
35
test/test_366_2.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include "boost/thread/scoped_thread.hpp"
|
||||
#include "boost/thread.hpp"
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <iostream>
|
||||
|
||||
static void inner_thread_func()
|
||||
{
|
||||
boost::this_thread::sleep_for(
|
||||
boost::chrono::hours(1) );
|
||||
}
|
||||
|
||||
static void outer_thread_func()
|
||||
{
|
||||
boost::scoped_thread<boost::interrupt_and_join_if_joinable> inner( inner_thread_func );
|
||||
}
|
||||
|
||||
static void double_interrupt()
|
||||
{
|
||||
boost::scoped_thread<boost::interrupt_and_join_if_joinable> outer( outer_thread_func );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST( true ); // perform lwt initialization
|
||||
|
||||
std::cout << "Start" << std::endl;
|
||||
double_interrupt();
|
||||
std::cout << "End" << std::endl;
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
35
test/test_366_3.cpp
Normal file
35
test/test_366_3.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include "boost/thread/scoped_thread.hpp"
|
||||
#include "boost/thread.hpp"
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <iostream>
|
||||
|
||||
static void inner_thread_func()
|
||||
{
|
||||
boost::this_thread::sleep_for(
|
||||
boost::chrono::hours(1) );
|
||||
}
|
||||
|
||||
static void outer_thread_func()
|
||||
{
|
||||
boost::strict_scoped_thread<boost::interrupt_and_join_if_joinable> inner( inner_thread_func );
|
||||
}
|
||||
|
||||
static void double_interrupt()
|
||||
{
|
||||
boost::strict_scoped_thread<boost::interrupt_and_join_if_joinable> outer( outer_thread_func );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST( true ); // perform lwt initialization
|
||||
|
||||
std::cout << "Start" << std::endl;
|
||||
double_interrupt();
|
||||
std::cout << "End" << std::endl;
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
59
test/test_366_4.cpp
Normal file
59
test/test_366_4.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include "boost/thread/scoped_thread.hpp"
|
||||
#include "boost/thread.hpp"
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <iostream>
|
||||
|
||||
static void do_first_half()
|
||||
{
|
||||
std::cout << "Doing first half of the work\n";
|
||||
|
||||
boost::this_thread::sleep_for(
|
||||
boost::chrono::hours( 1 ) );
|
||||
|
||||
std::cout << "First half of the work complete\n";
|
||||
}
|
||||
|
||||
static void do_second_half()
|
||||
{
|
||||
std::cout << "Doing second half of the work\n";
|
||||
|
||||
boost::this_thread::sleep_for(
|
||||
boost::chrono::hours( 1 ) );
|
||||
|
||||
std::cout << "Second half of the work complete\n";
|
||||
}
|
||||
|
||||
static void outer_thread_func()
|
||||
{
|
||||
boost::scoped_thread<boost::interrupt_and_join_if_joinable> worker1( do_first_half );
|
||||
boost::scoped_thread<boost::interrupt_and_join_if_joinable> worker2( do_second_half );
|
||||
|
||||
worker1.join();
|
||||
worker2.join();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST( true ); // perform lwt initialization
|
||||
|
||||
std::cout << "Start" << std::endl;
|
||||
|
||||
{
|
||||
boost::thread outer( outer_thread_func );
|
||||
|
||||
boost::this_thread::sleep_for( boost::chrono::seconds( 1 ) );
|
||||
|
||||
std::cout << "Interrupting work\n";
|
||||
|
||||
outer.interrupt();
|
||||
outer.join();
|
||||
}
|
||||
|
||||
std::cout << "End" << std::endl;
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
Reference in New Issue
Block a user