mirror of
https://github.com/latentPrion/libspinscale.git
synced 2026-06-23 19:48:32 +00:00
PostingPromise: Add dynamic post-to io_context targeting
This allows us to dynamically choose the target that a PostingPromise coro will be posted to at runtime rather than only posting to the statically configured ThreadTag::io_context() target. Big usability improvement.
This commit is contained in:
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef POST_TARGET_H
|
||||||
|
#define POST_TARGET_H
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <boost/asio/io_context.hpp>
|
||||||
|
|
||||||
|
namespace sscl::co {
|
||||||
|
|
||||||
|
/** Opt-in dynamic post-TO target for TaggedPostingPromise coroutines.
|
||||||
|
* When omitted, initial_suspend posts to ThreadTag::io_context().
|
||||||
|
* Post-back still uses callerIoContext (getSelf() at co_await site).
|
||||||
|
*/
|
||||||
|
struct ExplicitPostTarget
|
||||||
|
{
|
||||||
|
boost::asio::io_context& ioContext;
|
||||||
|
|
||||||
|
explicit ExplicitPostTarget(boost::asio::io_context& ctx) noexcept
|
||||||
|
: ioContext(ctx)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool is_explicit_post_target_v =
|
||||||
|
std::same_as<std::remove_cvref_t<T>, ExplicitPostTarget>;
|
||||||
|
|
||||||
|
} // namespace sscl::co
|
||||||
|
|
||||||
|
#endif // POST_TARGET_H
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <exception>
|
#include <exception>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <optional>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
|
|
||||||
#include <spinscale/componentThread.h>
|
#include <spinscale/componentThread.h>
|
||||||
#include <spinscale/co/coQutex.h>
|
#include <spinscale/co/coQutex.h>
|
||||||
|
#include <spinscale/co/postTarget.h>
|
||||||
#include <spinscale/co/promiseChainLink.h>
|
#include <spinscale/co/promiseChainLink.h>
|
||||||
#include <spinscale/co/promiseReturnOps.h>
|
#include <spinscale/co/promiseReturnOps.h>
|
||||||
#include <spinscale/co/returnValues.h>
|
#include <spinscale/co/returnValues.h>
|
||||||
@@ -191,6 +193,7 @@ struct PostingPromise
|
|||||||
: returnValues(), postBackStatus(*this)
|
: returnValues(), postBackStatus(*this)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/** Non-viral entry: post-TO uses ThreadTag default (via TaggedPostingPromise). */
|
||||||
template <typename... TailArgs>
|
template <typename... TailArgs>
|
||||||
PostingPromise(
|
PostingPromise(
|
||||||
std::exception_ptr &_callerExceptionPtr,
|
std::exception_ptr &_callerExceptionPtr,
|
||||||
@@ -201,12 +204,41 @@ struct PostingPromise
|
|||||||
postBackStatus(*this)
|
postBackStatus(*this)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/** Member coroutines pass the implicit object parameter before explicit
|
/** Non-viral entry with explicit post-TO target. */
|
||||||
* (exceptionPtr, callback, ...) args. Discard the object and delegate to
|
template <typename... TailArgs>
|
||||||
* the free-function constructor shape.
|
PostingPromise(
|
||||||
*/
|
std::exception_ptr &_callerExceptionPtr,
|
||||||
|
std::function<void()> _callerLambda,
|
||||||
|
ExplicitPostTarget _calleePostTarget,
|
||||||
|
TailArgs &&...) noexcept
|
||||||
|
: returnValues(_callerExceptionPtr),
|
||||||
|
callerLambda(std::move(_callerLambda)),
|
||||||
|
postBackStatus(*this),
|
||||||
|
calleePostTarget(std::move(_calleePostTarget))
|
||||||
|
{}
|
||||||
|
|
||||||
|
/** Viral / free-function entry with explicit post-TO target. */
|
||||||
|
template <typename... TailArgs>
|
||||||
|
PostingPromise(
|
||||||
|
ExplicitPostTarget _calleePostTarget,
|
||||||
|
TailArgs &&...) noexcept
|
||||||
|
: returnValues(),
|
||||||
|
postBackStatus(*this),
|
||||||
|
calleePostTarget(std::move(_calleePostTarget))
|
||||||
|
{}
|
||||||
|
|
||||||
|
/** Viral / free-function entry: post-TO uses ThreadTag default. */
|
||||||
|
template <typename FirstArg, typename... TailArgs>
|
||||||
|
requires (!is_explicit_post_target_v<std::remove_cvref_t<FirstArg>>)
|
||||||
|
PostingPromise(FirstArg &&, TailArgs &&...) noexcept
|
||||||
|
: PostingPromise()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/** Member non-viral: peel implicit object parameter. */
|
||||||
template <typename ObjectArg, typename... TailArgs>
|
template <typename ObjectArg, typename... TailArgs>
|
||||||
requires (!std::same_as<std::remove_cvref_t<ObjectArg>, std::exception_ptr>)
|
requires (
|
||||||
|
!std::same_as<std::remove_cvref_t<ObjectArg>, std::exception_ptr>
|
||||||
|
&& !is_explicit_post_target_v<std::remove_cvref_t<ObjectArg>>)
|
||||||
PostingPromise(
|
PostingPromise(
|
||||||
ObjectArg &&,
|
ObjectArg &&,
|
||||||
std::exception_ptr &_callerExceptionPtr,
|
std::exception_ptr &_callerExceptionPtr,
|
||||||
@@ -217,6 +249,48 @@ struct PostingPromise
|
|||||||
std::move(_callerLambda))
|
std::move(_callerLambda))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/** Member non-viral with explicit post-TO target. */
|
||||||
|
template <typename ObjectArg, typename... TailArgs>
|
||||||
|
requires (
|
||||||
|
!std::same_as<std::remove_cvref_t<ObjectArg>, std::exception_ptr>
|
||||||
|
&& !is_explicit_post_target_v<std::remove_cvref_t<ObjectArg>>)
|
||||||
|
PostingPromise(
|
||||||
|
ObjectArg &&,
|
||||||
|
std::exception_ptr &_callerExceptionPtr,
|
||||||
|
std::function<void()> _callerLambda,
|
||||||
|
ExplicitPostTarget _calleePostTarget,
|
||||||
|
TailArgs &&...) noexcept
|
||||||
|
: PostingPromise(
|
||||||
|
_callerExceptionPtr,
|
||||||
|
std::move(_callerLambda),
|
||||||
|
std::move(_calleePostTarget))
|
||||||
|
{}
|
||||||
|
|
||||||
|
/** Member viral with explicit post-TO target. */
|
||||||
|
template <typename ObjectArg, typename... TailArgs>
|
||||||
|
requires (
|
||||||
|
!std::same_as<std::remove_cvref_t<ObjectArg>, std::exception_ptr>
|
||||||
|
&& !is_explicit_post_target_v<std::remove_cvref_t<ObjectArg>>)
|
||||||
|
PostingPromise(
|
||||||
|
ObjectArg &&,
|
||||||
|
ExplicitPostTarget _calleePostTarget,
|
||||||
|
TailArgs &&...) noexcept
|
||||||
|
: PostingPromise(std::move(_calleePostTarget))
|
||||||
|
{}
|
||||||
|
|
||||||
|
/** Member viral: peel implicit object parameter. */
|
||||||
|
template <typename ObjectArg, typename FirstArg, typename... TailArgs>
|
||||||
|
requires (
|
||||||
|
!std::same_as<std::remove_cvref_t<ObjectArg>, std::exception_ptr>
|
||||||
|
&& !is_explicit_post_target_v<std::remove_cvref_t<ObjectArg>>
|
||||||
|
&& !is_explicit_post_target_v<std::remove_cvref_t<FirstArg>>)
|
||||||
|
PostingPromise(
|
||||||
|
ObjectArg &&,
|
||||||
|
FirstArg &&,
|
||||||
|
TailArgs &&...) noexcept
|
||||||
|
: PostingPromise()
|
||||||
|
{}
|
||||||
|
|
||||||
~PostingPromise() noexcept
|
~PostingPromise() noexcept
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_LIBSSCL_DEBUG_CO
|
#ifdef CONFIG_LIBSSCL_DEBUG_CO
|
||||||
@@ -255,6 +329,7 @@ struct PostingPromise
|
|||||||
std::function<void()> callerLambda;
|
std::function<void()> callerLambda;
|
||||||
boost::asio::io_context &callerIoContext =
|
boost::asio::io_context &callerIoContext =
|
||||||
sscl::ComponentThread::getSelf()->getIoContext();
|
sscl::ComponentThread::getSelf()->getIoContext();
|
||||||
|
std::optional<ExplicitPostTarget> calleePostTarget;
|
||||||
std::coroutine_handle<> selfSchedHandle;
|
std::coroutine_handle<> selfSchedHandle;
|
||||||
std::coroutine_handle<void> callerSchedHandle;
|
std::coroutine_handle<void> callerSchedHandle;
|
||||||
PromiseChainLink *callerChainLink = nullptr;
|
PromiseChainLink *callerChainLink = nullptr;
|
||||||
@@ -280,33 +355,7 @@ struct TaggedPostingPromise
|
|||||||
: public PostingPromise<T>,
|
: public PostingPromise<T>,
|
||||||
public PromiseReturnOps<TaggedPostingPromise<T, ThreadTag>, T>
|
public PromiseReturnOps<TaggedPostingPromise<T, ThreadTag>, T>
|
||||||
{
|
{
|
||||||
TaggedPostingPromise() noexcept
|
using PostingPromise<T>::PostingPromise;
|
||||||
: PostingPromise<T>()
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <typename... TailArgs>
|
|
||||||
TaggedPostingPromise(
|
|
||||||
std::exception_ptr &_exceptionPtr,
|
|
||||||
std::function<void()> _callerLambda,
|
|
||||||
TailArgs &&... tailArgs) noexcept
|
|
||||||
: PostingPromise<T>(
|
|
||||||
_exceptionPtr,
|
|
||||||
std::move(_callerLambda),
|
|
||||||
std::forward<TailArgs>(tailArgs)...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <typename ObjectArg, typename... TailArgs>
|
|
||||||
requires (!std::same_as<std::remove_cvref_t<ObjectArg>, std::exception_ptr>)
|
|
||||||
TaggedPostingPromise(
|
|
||||||
ObjectArg &&,
|
|
||||||
std::exception_ptr &_exceptionPtr,
|
|
||||||
std::function<void()> _callerLambda,
|
|
||||||
TailArgs &&... tailArgs) noexcept
|
|
||||||
: PostingPromise<T>(
|
|
||||||
_exceptionPtr,
|
|
||||||
std::move(_callerLambda),
|
|
||||||
std::forward<TailArgs>(tailArgs)...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
auto initial_suspend() noexcept
|
auto initial_suspend() noexcept
|
||||||
{
|
{
|
||||||
@@ -314,8 +363,13 @@ struct TaggedPostingPromise
|
|||||||
std::cout << __func__ << ": " << std::this_thread::get_id() << " About to post selfSchedHandle to " << typeid(ThreadTag).name() << ".\n";
|
std::cout << __func__ << ": " << std::this_thread::get_id() << " About to post selfSchedHandle to " << typeid(ThreadTag).name() << ".\n";
|
||||||
std::cout << __func__ << ": " << std::this_thread::get_id() << " Returning InitialSuspendPostingInvoker.\n";
|
std::cout << __func__ << ": " << std::this_thread::get_id() << " Returning InitialSuspendPostingInvoker.\n";
|
||||||
#endif
|
#endif
|
||||||
|
boost::asio::io_context &postToIoContext =
|
||||||
|
this->calleePostTarget
|
||||||
|
? this->calleePostTarget->ioContext
|
||||||
|
: ThreadTag::io_context();
|
||||||
|
|
||||||
return typename PostingPromise<T>::InitialSuspendPostingInvoker(
|
return typename PostingPromise<T>::InitialSuspendPostingInvoker(
|
||||||
ThreadTag::io_context(),
|
postToIoContext,
|
||||||
this->selfSchedHandle);
|
this->selfSchedHandle);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user