stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -0,0 +1,313 @@
// Copyright Oliver Kowalke 2013.
// 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)
#ifndef BOOST_FIBERS_DETAIL_SHARED_STATE_H
#define BOOST_FIBERS_DETAIL_SHARED_STATE_H
#include <algorithm>
#include <atomic>
#include <chrono>
#include <cstddef>
#include <exception>
#include <memory>
#include <mutex>
#include <type_traits>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/future/future_status.hpp>
#include <boost/fiber/condition_variable.hpp>
#include <boost/fiber/exceptions.hpp>
#include <boost/fiber/mutex.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace fibers {
namespace detail {
class shared_state_base {
private:
std::atomic< std::size_t > use_count_{ 0 };
mutable condition_variable waiters_{};
protected:
mutable mutex mtx_{};
bool ready_{ false };
std::exception_ptr except_{};
void mark_ready_and_notify_( std::unique_lock< mutex > & lk) noexcept {
BOOST_ASSERT( lk.owns_lock() );
ready_ = true;
lk.unlock();
waiters_.notify_all();
}
void owner_destroyed_( std::unique_lock< mutex > & lk) {
BOOST_ASSERT( lk.owns_lock() );
if ( ! ready_) {
set_exception_(
std::make_exception_ptr( broken_promise() ),
lk);
}
}
void set_exception_( std::exception_ptr except, std::unique_lock< mutex > & lk) {
BOOST_ASSERT( lk.owns_lock() );
if ( ready_) {
throw promise_already_satisfied();
}
except_ = except;
mark_ready_and_notify_( lk);
}
std::exception_ptr get_exception_ptr_( std::unique_lock< mutex > & lk) {
BOOST_ASSERT( lk.owns_lock() );
wait_( lk);
return except_;
}
void wait_( std::unique_lock< mutex > & lk) const {
BOOST_ASSERT( lk.owns_lock() );
waiters_.wait( lk, [this](){ return ready_; });
}
template< typename Rep, typename Period >
future_status wait_for_( std::unique_lock< mutex > & lk,
std::chrono::duration< Rep, Period > const& timeout_duration) const {
BOOST_ASSERT( lk.owns_lock() );
return waiters_.wait_for( lk, timeout_duration, [this](){ return ready_; })
? future_status::ready
: future_status::timeout;
}
template< typename Clock, typename Duration >
future_status wait_until_( std::unique_lock< mutex > & lk,
std::chrono::time_point< Clock, Duration > const& timeout_time) const {
BOOST_ASSERT( lk.owns_lock() );
return waiters_.wait_until( lk, timeout_time, [this](){ return ready_; })
? future_status::ready
: future_status::timeout;
}
virtual void deallocate_future() noexcept = 0;
public:
shared_state_base() = default;
virtual ~shared_state_base() = default;
shared_state_base( shared_state_base const&) = delete;
shared_state_base & operator=( shared_state_base const&) = delete;
void owner_destroyed() {
std::unique_lock< mutex > lk{ mtx_ };
owner_destroyed_( lk);
}
void set_exception( std::exception_ptr except) {
std::unique_lock< mutex > lk{ mtx_ };
set_exception_( except, lk);
}
std::exception_ptr get_exception_ptr() {
std::unique_lock< mutex > lk{ mtx_ };
return get_exception_ptr_( lk);
}
void wait() const {
std::unique_lock< mutex > lk{ mtx_ };
wait_( lk);
}
template< typename Rep, typename Period >
future_status wait_for( std::chrono::duration< Rep, Period > const& timeout_duration) const {
std::unique_lock< mutex > lk{ mtx_ };
return wait_for_( lk, timeout_duration);
}
template< typename Clock, typename Duration >
future_status wait_until( std::chrono::time_point< Clock, Duration > const& timeout_time) const {
std::unique_lock< mutex > lk{ mtx_ };
return wait_until_( lk, timeout_time);
}
friend inline
void intrusive_ptr_add_ref( shared_state_base * p) noexcept {
p->use_count_.fetch_add( 1, std::memory_order_relaxed);
}
friend inline
void intrusive_ptr_release( shared_state_base * p) noexcept {
if ( 1 == p->use_count_.fetch_sub( 1, std::memory_order_release) ) {
std::atomic_thread_fence( std::memory_order_acquire);
p->deallocate_future();
}
}
};
template< typename R >
class shared_state : public shared_state_base {
private:
typename std::aligned_storage< sizeof( R), alignof( R) >::type storage_{};
void set_value_( R const& value, std::unique_lock< mutex > & lk) {
BOOST_ASSERT( lk.owns_lock() );
if ( ready_) {
throw promise_already_satisfied{};
}
::new ( static_cast< void * >( std::addressof( storage_) ) ) R{ value };
mark_ready_and_notify_( lk);
}
void set_value_( R && value, std::unique_lock< mutex > & lk) {
BOOST_ASSERT( lk.owns_lock() );
if ( ready_) {
throw promise_already_satisfied{};
}
::new ( static_cast< void * >( std::addressof( storage_) ) ) R{ std::move( value) };
mark_ready_and_notify_( lk);
}
R & get_( std::unique_lock< mutex > & lk) {
BOOST_ASSERT( lk.owns_lock() );
wait_( lk);
if ( except_) {
std::rethrow_exception( except_);
}
return * reinterpret_cast< R * >( std::addressof( storage_) );
}
public:
typedef intrusive_ptr< shared_state > ptr_type;
shared_state() = default;
virtual ~shared_state() {
if ( ready_ && ! except_) {
reinterpret_cast< R * >( std::addressof( storage_) )->~R();
}
}
shared_state( shared_state const&) = delete;
shared_state & operator=( shared_state const&) = delete;
void set_value( R const& value) {
std::unique_lock< mutex > lk{ mtx_ };
set_value_( value, lk);
}
void set_value( R && value) {
std::unique_lock< mutex > lk{ mtx_ };
set_value_( std::move( value), lk);
}
R & get() {
std::unique_lock< mutex > lk{ mtx_ };
return get_( lk);
}
};
template< typename R >
class shared_state< R & > : public shared_state_base {
private:
R * value_{ nullptr };
void set_value_( R & value, std::unique_lock< mutex > & lk) {
BOOST_ASSERT( lk.owns_lock() );
if ( ready_) {
throw promise_already_satisfied();
}
value_ = std::addressof( value);
mark_ready_and_notify_( lk);
}
R & get_( std::unique_lock< mutex > & lk) {
BOOST_ASSERT( lk.owns_lock() );
wait_( lk);
if ( except_) {
std::rethrow_exception( except_);
}
return * value_;
}
public:
typedef intrusive_ptr< shared_state > ptr_type;
shared_state() = default;
virtual ~shared_state() = default;
shared_state( shared_state const&) = delete;
shared_state & operator=( shared_state const&) = delete;
void set_value( R & value) {
std::unique_lock< mutex > lk{ mtx_ };
set_value_( value, lk);
}
R & get() {
std::unique_lock< mutex > lk{ mtx_ };
return get_( lk);
}
};
template<>
class shared_state< void > : public shared_state_base {
private:
inline
void set_value_( std::unique_lock< mutex > & lk) {
BOOST_ASSERT( lk.owns_lock() );
if ( ready_) {
throw promise_already_satisfied();
}
mark_ready_and_notify_( lk);
}
inline
void get_( std::unique_lock< mutex > & lk) {
BOOST_ASSERT( lk.owns_lock() );
wait_( lk);
if ( except_) {
std::rethrow_exception( except_);
}
}
public:
typedef intrusive_ptr< shared_state > ptr_type;
shared_state() = default;
virtual ~shared_state() = default;
shared_state( shared_state const&) = delete;
shared_state & operator=( shared_state const&) = delete;
inline
void set_value() {
std::unique_lock< mutex > lk{ mtx_ };
set_value_( lk);
}
inline
void get() {
std::unique_lock< mutex > lk{ mtx_ };
get_( lk);
}
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_DETAIL_SHARED_STATE_H
@@ -0,0 +1,58 @@
// Copyright Oliver Kowalke 2013.
// 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)
#ifndef BOOST_FIBERS_DETAIL_SHARED_STATE_OBJECT_H
#define BOOST_FIBERS_DETAIL_SHARED_STATE_OBJECT_H
#include <memory>
#include <boost/config.hpp>
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/future/detail/shared_state.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace fibers {
namespace detail {
template< typename R, typename Allocator >
class shared_state_object : public shared_state< R > {
public:
typedef typename std::allocator_traits< Allocator >::template rebind_alloc<
shared_state_object
> allocator_type;
shared_state_object( allocator_type const& alloc) :
shared_state< R >{},
alloc_{ alloc } {
}
protected:
void deallocate_future() noexcept override final {
destroy_( alloc_, this);
}
private:
allocator_type alloc_;
static void destroy_( allocator_type const& alloc, shared_state_object * p) noexcept {
allocator_type a{ alloc };
a.destroy( p);
a.deallocate( p, 1);
}
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_DETAIL_SHARED_STATE_OBJECT_H
@@ -0,0 +1,41 @@
// Copyright Oliver Kowalke 2013.
// 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)
#ifndef BOOST_FIBERS_DETAIL_TASK_BASE_H
#define BOOST_FIBERS_DETAIL_TASK_BASE_H
#include <boost/config.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/future/detail/shared_state.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace fibers {
namespace detail {
template< typename R, typename ... Args >
struct task_base : public shared_state< R > {
typedef intrusive_ptr< task_base > ptr_type;
virtual ~task_base() {
}
virtual void run( Args && ... args) = 0;
virtual ptr_type reset() = 0;
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_DETAIL_TASK_BASE_H
@@ -0,0 +1,170 @@
// Copyright Oliver Kowalke 2013.
// 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)
#ifndef BOOST_FIBERS_DETAIL_TASK_OBJECT_H
#define BOOST_FIBERS_DETAIL_TASK_OBJECT_H
#include <exception>
#include <memory>
#include <tuple>
#include <utility>
#include <boost/config.hpp>
#if defined(BOOST_NO_CXX17_STD_APPLY)
#include <boost/context/detail/apply.hpp>
#endif
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/future/detail/task_base.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace fibers {
namespace detail {
template< typename Fn, typename Allocator, typename R, typename ... Args >
class task_object : public task_base< R, Args ... > {
private:
typedef task_base< R, Args ... > base_type;
public:
typedef typename std::allocator_traits< Allocator >::template rebind_alloc<
task_object
> allocator_type;
task_object( allocator_type const& alloc, Fn const& fn) :
base_type{},
fn_{ fn },
alloc_{ alloc } {
}
task_object( allocator_type const& alloc, Fn && fn) :
base_type{},
fn_{ std::move( fn) },
alloc_{ alloc } {
}
void run( Args && ... args) override final {
try {
this->set_value(
#if defined(BOOST_NO_CXX17_STD_APPLY)
boost::context::detail::apply(
fn_, std::make_tuple( std::forward< Args >( args) ... ) )
#else
std::apply(
fn_, std::make_tuple( std::forward< Args >( args) ... ) )
#endif
);
} catch (...) {
this->set_exception( std::current_exception() );
}
}
typename base_type::ptr_type reset() override final {
typedef std::allocator_traits< allocator_type > traity_type;
typename traity_type::pointer ptr{ traity_type::allocate( alloc_, 1) };
try {
traity_type::construct( alloc_, ptr, alloc_, std::move( fn_) );
} catch (...) {
traity_type::deallocate( alloc_, ptr, 1);
throw;
}
return { convert( ptr) };
}
protected:
void deallocate_future() noexcept override final {
destroy_( alloc_, this);
}
private:
Fn fn_;
allocator_type alloc_;
static void destroy_( allocator_type const& alloc, task_object * p) noexcept {
allocator_type a{ alloc };
a.destroy( p);
a.deallocate( p, 1);
}
};
template< typename Fn, typename Allocator, typename ... Args >
class task_object< Fn, Allocator, void, Args ... > : public task_base< void, Args ... > {
private:
typedef task_base< void, Args ... > base_type;
public:
typedef typename Allocator::template rebind<
task_object< Fn, Allocator, void, Args ... >
>::other allocator_type;
task_object( allocator_type const& alloc, Fn const& fn) :
base_type{},
fn_{ fn },
alloc_{ alloc } {
}
task_object( allocator_type const& alloc, Fn && fn) :
base_type{},
fn_{ std::move( fn) },
alloc_{ alloc } {
}
void run( Args && ... args) override final {
try {
#if defined(BOOST_NO_CXX17_STD_APPLY)
boost::context::detail::apply(
fn_, std::make_tuple( std::forward< Args >( args) ... ) );
#else
std::apply(
fn_, std::make_tuple( std::forward< Args >( args) ... ) );
#endif
this->set_value();
} catch (...) {
this->set_exception( std::current_exception() );
}
}
typename base_type::ptr_type reset() override final {
typedef std::allocator_traits< allocator_type > traity_type;
typename traity_type::pointer ptr{ traity_type::allocate( alloc_, 1) };
try {
traity_type::construct( alloc_, ptr, alloc_, std::move( fn_) );
} catch (...) {
traity_type::deallocate( alloc_, ptr, 1);
throw;
}
return { convert( ptr) };
}
protected:
void deallocate_future() noexcept override final {
destroy_( alloc_, this);
}
private:
Fn fn_;
allocator_type alloc_;
static void destroy_( allocator_type const& alloc, task_object * p) noexcept {
allocator_type a{ alloc };
a.destroy( p);
a.deallocate( p, 1);
}
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_DETAIL_TASK_OBJECT_H