2025-09-09 11:50:19 -04:00
|
|
|
#ifndef ASYNCHRONOUS_CONTINUATION_H
|
|
|
|
|
#define ASYNCHRONOUS_CONTINUATION_H
|
|
|
|
|
|
|
|
|
|
#include <functional>
|
|
|
|
|
#include <memory>
|
2025-09-11 18:37:48 -04:00
|
|
|
#include <componentThread.h>
|
2025-09-18 23:03:39 -04:00
|
|
|
#include <lockSet.h>
|
2025-09-11 18:37:48 -04:00
|
|
|
|
|
|
|
|
namespace smo {
|
2025-09-09 11:50:19 -04:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* AsynchronousContinuation - Template base class for async sequence management
|
|
|
|
|
*
|
|
|
|
|
* This template provides a common pattern for managing asynchronous operations
|
|
|
|
|
* that need to maintain object lifetime through a sequence of callbacks.
|
|
|
|
|
*
|
|
|
|
|
* The template parameter OriginalCbFnT represents the signature of the original
|
|
|
|
|
* callback that will be invoked when the async sequence completes.
|
|
|
|
|
*/
|
|
|
|
|
template <class OriginalCbFnT>
|
|
|
|
|
class AsynchronousContinuation
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit AsynchronousContinuation(OriginalCbFnT originalCbFn)
|
|
|
|
|
: originalCbFn(std::move(originalCbFn))
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
/** EXPLANATION:
|
|
|
|
|
* Each numbered segmented sequence persists the lifetime of the
|
|
|
|
|
* continuation object by taking a copy of its shared_ptr.
|
|
|
|
|
*/
|
|
|
|
|
typedef void (SegmentFn)(
|
|
|
|
|
std::shared_ptr<AsynchronousContinuation<OriginalCbFnT>>
|
|
|
|
|
lifetimePreservingConveyance);
|
|
|
|
|
|
2025-09-17 16:32:20 -04:00
|
|
|
public:
|
2025-09-09 11:50:19 -04:00
|
|
|
OriginalCbFnT originalCbFn;
|
|
|
|
|
};
|
|
|
|
|
|
2025-09-17 16:32:20 -04:00
|
|
|
/**
|
|
|
|
|
* NonPostedAsynchronousContinuation - For continuations that don't post
|
|
|
|
|
* callbacks
|
|
|
|
|
*
|
|
|
|
|
* Note: We intentionally do not create a
|
|
|
|
|
* LockedNonPostedAsynchronousContinuation because the only way to implement
|
|
|
|
|
* non-posted locking would be via busy-spinning or sleeplocks. This would
|
|
|
|
|
* eliminate the throughput advantage from our Qspinning mechanism, which
|
|
|
|
|
* relies on re-posting to the io_service queue when locks are unavailable.
|
|
|
|
|
*/
|
|
|
|
|
template <class OriginalCbFnT>
|
|
|
|
|
class NonPostedAsynchronousContinuation
|
|
|
|
|
: public AsynchronousContinuation<OriginalCbFnT>
|
2025-09-11 18:37:48 -04:00
|
|
|
{
|
|
|
|
|
public:
|
2025-09-17 16:32:20 -04:00
|
|
|
explicit NonPostedAsynchronousContinuation(OriginalCbFnT originalCbFn)
|
|
|
|
|
: AsynchronousContinuation<OriginalCbFnT>(originalCbFn)
|
2025-09-11 18:37:48 -04:00
|
|
|
{}
|
|
|
|
|
|
2025-09-18 22:10:17 -04:00
|
|
|
/**
|
|
|
|
|
* @brief Call the original callback with perfect forwarding
|
|
|
|
|
* (immediate execution)
|
|
|
|
|
*
|
|
|
|
|
* This implementation calls the original callback immediately without
|
|
|
|
|
* posting to any thread or queue. Used for non-posted continuations.
|
|
|
|
|
*
|
|
|
|
|
* @param args Arguments to forward to the original callback
|
|
|
|
|
*/
|
|
|
|
|
template<typename... Args>
|
|
|
|
|
void callOriginalCb(Args&&... args)
|
|
|
|
|
{
|
|
|
|
|
if (AsynchronousContinuation<OriginalCbFnT>::originalCbFn)
|
|
|
|
|
{
|
|
|
|
|
AsynchronousContinuation<OriginalCbFnT>::originalCbFn(
|
|
|
|
|
std::forward<Args>(args)...);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-09-11 18:37:48 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <class OriginalCbFnT>
|
2025-09-17 16:32:20 -04:00
|
|
|
class PostedAsynchronousContinuation
|
|
|
|
|
: public AsynchronousContinuation<OriginalCbFnT>
|
2025-09-11 18:37:48 -04:00
|
|
|
{
|
|
|
|
|
public:
|
2025-09-17 16:32:20 -04:00
|
|
|
PostedAsynchronousContinuation(
|
2025-09-11 18:37:48 -04:00
|
|
|
const std::shared_ptr<ComponentThread> &caller,
|
|
|
|
|
OriginalCbFnT originalCbFn)
|
|
|
|
|
: AsynchronousContinuation<OriginalCbFnT>(originalCbFn),
|
2025-09-17 16:32:20 -04:00
|
|
|
caller(caller)
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
template<typename... Args>
|
|
|
|
|
void callOriginalCb(Args&&... args)
|
|
|
|
|
{
|
2025-09-18 22:10:17 -04:00
|
|
|
if (AsynchronousContinuation<OriginalCbFnT>::originalCbFn)
|
|
|
|
|
{
|
2025-09-17 16:32:20 -04:00
|
|
|
caller->getIoService().post(
|
|
|
|
|
std::bind(
|
|
|
|
|
AsynchronousContinuation<OriginalCbFnT>::originalCbFn,
|
|
|
|
|
std::forward<Args>(args)...));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
std::shared_ptr<ComponentThread> caller;
|
|
|
|
|
};
|
|
|
|
|
|
2025-09-11 18:37:48 -04:00
|
|
|
} // namespace smo
|
|
|
|
|
|
2025-09-09 11:50:19 -04:00
|
|
|
#endif // ASYNCHRONOUS_CONTINUATION_H
|