Add awaiters for DeviceManager continuations
This commit is contained in:
@@ -0,0 +1,93 @@
|
|||||||
|
#ifndef CPS_CALLBACK_AREQ_H
|
||||||
|
#define CPS_CALLBACK_AREQ_H
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <coroutine>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <boost/asio/io_service.hpp>
|
||||||
|
#include <boost/asio/post.hpp>
|
||||||
|
#include <spinscale/cps/callback.h>
|
||||||
|
|
||||||
|
namespace smo {
|
||||||
|
namespace cpsBoundary {
|
||||||
|
|
||||||
|
/** Eager-start CPS callback → coroutine adapter (mirrors
|
||||||
|
* PuppetThread::ViralThreadLifetimeMgmtInvoker).
|
||||||
|
*/
|
||||||
|
template <typename Result, typename CallbackFn, typename StartFn>
|
||||||
|
class CpsCallbackAReq
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct AsyncState
|
||||||
|
{
|
||||||
|
std::atomic<bool> settled{false};
|
||||||
|
Result result{};
|
||||||
|
std::coroutine_handle<> callerSchedHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
CpsCallbackAReq(
|
||||||
|
boost::asio::io_service &resumeIoService,
|
||||||
|
StartFn startFn)
|
||||||
|
: asyncState(std::make_shared<AsyncState>()),
|
||||||
|
resumeIoService(resumeIoService)
|
||||||
|
{
|
||||||
|
startFn(sscl::cps::Callback<CallbackFn>{
|
||||||
|
nullptr,
|
||||||
|
[this](auto &&...args)
|
||||||
|
{
|
||||||
|
storeResult(std::forward<decltype(args)>(args)...);
|
||||||
|
signalSettledAndResumeCaller();
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool await_ready() const noexcept
|
||||||
|
{
|
||||||
|
return asyncState->settled.load(std::memory_order_acquire);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool await_suspend(std::coroutine_handle<> callerSchedHandle) noexcept
|
||||||
|
{
|
||||||
|
if (asyncState->settled.load(std::memory_order_acquire)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
asyncState->callerSchedHandle = callerSchedHandle;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result await_resume() noexcept
|
||||||
|
{
|
||||||
|
return asyncState->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename... Args>
|
||||||
|
void storeResult(Args &&...args)
|
||||||
|
{
|
||||||
|
asyncState->result = Result{std::forward<Args>(args)...};
|
||||||
|
}
|
||||||
|
|
||||||
|
void signalSettledAndResumeCaller() noexcept
|
||||||
|
{
|
||||||
|
asyncState->settled.store(true, std::memory_order_release);
|
||||||
|
|
||||||
|
std::coroutine_handle<> handle = asyncState->callerSchedHandle;
|
||||||
|
if (!handle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::asio::post(
|
||||||
|
resumeIoService,
|
||||||
|
[handle]() { handle.resume(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<AsyncState> asyncState;
|
||||||
|
boost::asio::io_service &resumeIoService;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cpsBoundary
|
||||||
|
} // namespace smo
|
||||||
|
|
||||||
|
#endif // CPS_CALLBACK_AREQ_H
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
#ifndef STIM_BUFF_DEVICE_AREQ_H
|
||||||
|
#define STIM_BUFF_DEVICE_AREQ_H
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <coroutine>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <boost/asio/io_service.hpp>
|
||||||
|
#include <boost/asio/post.hpp>
|
||||||
|
#include <spinscale/cps/callback.h>
|
||||||
|
#include <stimBuffApis/stimBuffApiLib.h>
|
||||||
|
#include <user/deviceAttachmentSpec.h>
|
||||||
|
#include <user/senseApiDesc.h>
|
||||||
|
|
||||||
|
namespace smo {
|
||||||
|
namespace cpsBoundary {
|
||||||
|
|
||||||
|
struct StimBuffDeviceOpResult
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
std::shared_ptr<device::DeviceAttachmentSpec> deviceSpec;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AttachStimBuffDeviceAReq
|
||||||
|
{
|
||||||
|
struct AsyncState
|
||||||
|
{
|
||||||
|
std::atomic<bool> settled{false};
|
||||||
|
StimBuffDeviceOpResult result;
|
||||||
|
std::coroutine_handle<> callerSchedHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
AttachStimBuffDeviceAReq(
|
||||||
|
const std::shared_ptr<device::DeviceAttachmentSpec> &spec,
|
||||||
|
stim_buff::StimBuffApiLib &lib,
|
||||||
|
const std::shared_ptr<sscl::ComponentThread> &threadForAttachment,
|
||||||
|
boost::asio::io_service &resumeIoService)
|
||||||
|
: asyncState(std::make_shared<AsyncState>()),
|
||||||
|
resumeIoService(resumeIoService)
|
||||||
|
{
|
||||||
|
lib.stimBuffApiDesc.sal_mgmt_libOps.attachDeviceReq(
|
||||||
|
spec, threadForAttachment,
|
||||||
|
{nullptr,
|
||||||
|
[asyncState = asyncState, &resumeIoService = resumeIoService](
|
||||||
|
bool success,
|
||||||
|
std::shared_ptr<device::DeviceAttachmentSpec> deviceSpec)
|
||||||
|
{
|
||||||
|
asyncState->result = StimBuffDeviceOpResult{
|
||||||
|
success, deviceSpec};
|
||||||
|
|
||||||
|
asyncState->settled.store(
|
||||||
|
true, std::memory_order_release);
|
||||||
|
|
||||||
|
std::coroutine_handle<> handle =
|
||||||
|
asyncState->callerSchedHandle;
|
||||||
|
|
||||||
|
if (!handle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::asio::post(
|
||||||
|
resumeIoService,
|
||||||
|
[handle]() { handle.resume(); });
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool await_ready() const noexcept
|
||||||
|
{
|
||||||
|
return asyncState->settled.load(std::memory_order_acquire);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool await_suspend(std::coroutine_handle<> callerSchedHandle) noexcept
|
||||||
|
{
|
||||||
|
if (asyncState->settled.load(std::memory_order_acquire)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
asyncState->callerSchedHandle = callerSchedHandle;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
StimBuffDeviceOpResult await_resume() noexcept
|
||||||
|
{
|
||||||
|
return asyncState->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<AsyncState> asyncState;
|
||||||
|
boost::asio::io_service &resumeIoService;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DetachStimBuffDeviceAReq
|
||||||
|
{
|
||||||
|
struct AsyncState
|
||||||
|
{
|
||||||
|
std::atomic<bool> settled{false};
|
||||||
|
StimBuffDeviceOpResult result;
|
||||||
|
std::coroutine_handle<> callerSchedHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
DetachStimBuffDeviceAReq(
|
||||||
|
const std::shared_ptr<device::DeviceAttachmentSpec> &spec,
|
||||||
|
stim_buff::StimBuffApiLib &lib,
|
||||||
|
boost::asio::io_service &resumeIoService)
|
||||||
|
: asyncState(std::make_shared<AsyncState>()),
|
||||||
|
resumeIoService(resumeIoService)
|
||||||
|
{
|
||||||
|
lib.stimBuffApiDesc.sal_mgmt_libOps.detachDeviceReq(
|
||||||
|
spec,
|
||||||
|
{nullptr,
|
||||||
|
[asyncState = asyncState, &resumeIoService = resumeIoService](
|
||||||
|
bool success,
|
||||||
|
std::shared_ptr<device::DeviceAttachmentSpec> deviceSpec)
|
||||||
|
{
|
||||||
|
asyncState->result = StimBuffDeviceOpResult{
|
||||||
|
success, deviceSpec};
|
||||||
|
|
||||||
|
asyncState->settled.store(
|
||||||
|
true, std::memory_order_release);
|
||||||
|
|
||||||
|
std::coroutine_handle<> handle =
|
||||||
|
asyncState->callerSchedHandle;
|
||||||
|
|
||||||
|
if (!handle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::asio::post(
|
||||||
|
resumeIoService,
|
||||||
|
[handle]() { handle.resume(); });
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool await_ready() const noexcept
|
||||||
|
{
|
||||||
|
return asyncState->settled.load(std::memory_order_acquire);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool await_suspend(std::coroutine_handle<> callerSchedHandle) noexcept
|
||||||
|
{
|
||||||
|
if (asyncState->settled.load(std::memory_order_acquire)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
asyncState->callerSchedHandle = callerSchedHandle;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
StimBuffDeviceOpResult await_resume() noexcept
|
||||||
|
{
|
||||||
|
return asyncState->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<AsyncState> asyncState;
|
||||||
|
boost::asio::io_service &resumeIoService;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cpsBoundary
|
||||||
|
} // namespace smo
|
||||||
|
|
||||||
|
#endif // STIM_BUFF_DEVICE_AREQ_H
|
||||||
Reference in New Issue
Block a user