LivoxProto1: port to sscl::co framework
Code now actually looks a lot cleaner, tbh.
This commit is contained in:
@@ -2,31 +2,110 @@
|
||||
#define ADAPTERS_BOOST_ASIO_DEADLINE_TIMER_AREQ_H
|
||||
|
||||
#include <boostAsioLinkageFix.h>
|
||||
#include <functional>
|
||||
|
||||
#include <atomic>
|
||||
#include <coroutine>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include <boost/asio/deadline_timer.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include <adapters/smo/cpsCallbackAReq.h>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
namespace adapters::boostAsio {
|
||||
|
||||
using TimerWaitCbFn = std::function<void(bool success)>;
|
||||
/** Coroutine awaiter: true if the delay elapsed, false if cancelled/aborted. */
|
||||
class DeadlineTimerAReq
|
||||
{
|
||||
public:
|
||||
struct AsyncState
|
||||
{
|
||||
std::atomic<bool> settled{false};
|
||||
bool timerExpiredNormally = false;
|
||||
std::coroutine_handle<> callerSchedHandle;
|
||||
std::shared_ptr<boost::asio::deadline_timer> timer;
|
||||
};
|
||||
|
||||
inline auto deadlineTimerWaitAReq(
|
||||
DeadlineTimerAReq(
|
||||
boost::asio::io_service &resumeIoService,
|
||||
const boost::posix_time::milliseconds delay,
|
||||
std::optional<std::shared_ptr<boost::asio::deadline_timer>> &timerOut)
|
||||
: asyncState(std::make_shared<AsyncState>()),
|
||||
resumeIoService(resumeIoService)
|
||||
{
|
||||
asyncState->timer =
|
||||
std::make_shared<boost::asio::deadline_timer>(resumeIoService);
|
||||
timerOut = asyncState->timer;
|
||||
|
||||
asyncState->timer->expires_from_now(delay);
|
||||
asyncState->timer->async_wait(
|
||||
[this](const boost::system::error_code &error)
|
||||
{
|
||||
onTimer(error);
|
||||
});
|
||||
}
|
||||
|
||||
bool await_ready() const noexcept
|
||||
{
|
||||
return asyncState->settled.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
bool await_suspend(std::coroutine_handle<> caller) noexcept
|
||||
{
|
||||
if (asyncState->settled.load(std::memory_order_acquire)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
asyncState->callerSchedHandle = caller;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool await_resume() const noexcept
|
||||
{
|
||||
return asyncState->timerExpiredNormally;
|
||||
}
|
||||
|
||||
private:
|
||||
void onTimer(const boost::system::error_code &error)
|
||||
{
|
||||
if (asyncState->settled.exchange(true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
asyncState->timerExpiredNormally = !error;
|
||||
signalSettledAndResumeCaller();
|
||||
}
|
||||
|
||||
void signalSettledAndResumeCaller()
|
||||
{
|
||||
std::coroutine_handle<> handle = asyncState->callerSchedHandle;
|
||||
if (!handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
boost::asio::post(resumeIoService, handle);
|
||||
}
|
||||
|
||||
std::shared_ptr<AsyncState> asyncState;
|
||||
boost::asio::io_service &resumeIoService;
|
||||
};
|
||||
|
||||
inline auto getDeadlineTimerAReqAwaiter(
|
||||
boost::asio::io_service &ioService,
|
||||
const boost::posix_time::milliseconds delay)
|
||||
{
|
||||
return smo::cpsBoundary::CpsCallbackAReq<bool, TimerWaitCbFn, std::function<void(sscl::cps::Callback<TimerWaitCbFn>)>>(
|
||||
ioService,
|
||||
[&ioService, delay](sscl::cps::Callback<TimerWaitCbFn> cb)
|
||||
{
|
||||
auto timer = std::make_shared<boost::asio::deadline_timer>(ioService);
|
||||
timer->expires_from_now(delay);
|
||||
timer->async_wait(
|
||||
[timer, cb](const boost::system::error_code &error) mutable
|
||||
{
|
||||
cb.callbackFn(!error);
|
||||
});
|
||||
});
|
||||
std::optional<std::shared_ptr<boost::asio::deadline_timer>> timerOut;
|
||||
return DeadlineTimerAReq(ioService, delay, timerOut);
|
||||
}
|
||||
|
||||
inline auto getDeadlineTimerAReqAwaiter(
|
||||
boost::asio::io_service &ioService,
|
||||
const boost::posix_time::milliseconds delay,
|
||||
std::optional<std::shared_ptr<boost::asio::deadline_timer>> &timerOut)
|
||||
{
|
||||
return DeadlineTimerAReq(ioService, delay, timerOut);
|
||||
}
|
||||
|
||||
} // namespace adapters::boostAsio
|
||||
|
||||
Reference in New Issue
Block a user