#ifndef ASYNCHRONOUS_CONTINUATION_H #define ASYNCHRONOUS_CONTINUATION_H #include #include #include #include namespace smo { /** * 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 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> lifetimePreservingConveyance); public: OriginalCbFnT originalCbFn; }; /** * 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 NonPostedAsynchronousContinuation : public AsynchronousContinuation { public: explicit NonPostedAsynchronousContinuation(OriginalCbFnT originalCbFn) : AsynchronousContinuation(originalCbFn) {} /** * @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 void callOriginalCb(Args&&... args) { if (AsynchronousContinuation::originalCbFn) { AsynchronousContinuation::originalCbFn( std::forward(args)...); } } }; template class PostedAsynchronousContinuation : public AsynchronousContinuation { public: PostedAsynchronousContinuation( const std::shared_ptr &caller, OriginalCbFnT originalCbFn) : AsynchronousContinuation(originalCbFn), caller(caller) {} template void callOriginalCb(Args&&... args) { if (AsynchronousContinuation::originalCbFn) { caller->getIoService().post( std::bind( AsynchronousContinuation::originalCbFn, std::forward(args)...)); } } public: std::shared_ptr caller; }; template class SerializedAsynchronousContinuation : public PostedAsynchronousContinuation { public: SerializedAsynchronousContinuation( const std::shared_ptr &caller, OriginalCbFnT originalCbFn, std::vector> requiredLocks = {}) : PostedAsynchronousContinuation(caller, originalCbFn), requiredLocks(*this, std::move(requiredLocks)) {} template void callOriginalCb(Args&&... args) { requiredLocks.release(); PostedAsynchronousContinuation::callOriginalCb( std::forward(args)...); } public: LockSet requiredLocks; }; } // namespace smo #endif // ASYNCHRONOUS_CONTINUATION_H