#ifndef STIM_BUFF_DEVICE_AREQ_H #define STIM_BUFF_DEVICE_AREQ_H #include #include #include #include #include #include #include #include #include namespace smo { namespace cpsBoundary { struct StimBuffDeviceOpResult { bool success = false; std::shared_ptr deviceSpec; }; struct AttachStimBuffDeviceAReq { struct AsyncState { std::atomic settled{false}; StimBuffDeviceOpResult result; std::coroutine_handle<> callerSchedHandle; }; AttachStimBuffDeviceAReq( const std::shared_ptr &spec, stim_buff::StimBuffApiLib &lib, const std::shared_ptr &threadForAttachment, boost::asio::io_service &resumeIoService) : asyncState(std::make_shared()), resumeIoService(resumeIoService) { lib.stimBuffApiDesc.sal_mgmt_libOps.attachDeviceReq( spec, threadForAttachment, {nullptr, [asyncState = asyncState, &resumeIoService = resumeIoService]( bool success, std::shared_ptr 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; boost::asio::io_service &resumeIoService; }; struct DetachStimBuffDeviceAReq { struct AsyncState { std::atomic settled{false}; StimBuffDeviceOpResult result; std::coroutine_handle<> callerSchedHandle; }; DetachStimBuffDeviceAReq( const std::shared_ptr &spec, stim_buff::StimBuffApiLib &lib, boost::asio::io_service &resumeIoService) : asyncState(std::make_shared()), resumeIoService(resumeIoService) { lib.stimBuffApiDesc.sal_mgmt_libOps.detachDeviceReq( spec, {nullptr, [asyncState = asyncState, &resumeIoService = resumeIoService]( bool success, std::shared_ptr 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; boost::asio::io_service &resumeIoService; }; } // namespace cpsBoundary } // namespace smo #endif // STIM_BUFF_DEVICE_AREQ_H