17f664254SPatrick Williams /* 27f664254SPatrick Williams // Copyright (c) 2018 Intel Corporation 37f664254SPatrick Williams // 47f664254SPatrick Williams // Licensed under the Apache License, Version 2.0 (the "License"); 57f664254SPatrick Williams // you may not use this file except in compliance with the License. 67f664254SPatrick Williams // You may obtain a copy of the License at 77f664254SPatrick Williams // 87f664254SPatrick Williams // http://www.apache.org/licenses/LICENSE-2.0 97f664254SPatrick Williams // 107f664254SPatrick Williams // Unless required by applicable law or agreed to in writing, software 117f664254SPatrick Williams // distributed under the License is distributed on an "AS IS" BASIS, 127f664254SPatrick Williams // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137f664254SPatrick Williams // See the License for the specific language governing permissions and 147f664254SPatrick Williams // limitations under the License. 157f664254SPatrick Williams */ 167f664254SPatrick Williams #pragma once 177f664254SPatrick Williams 187f664254SPatrick Williams #include <systemd/sd-event.h> 197f664254SPatrick Williams 2038ab5ecfSEd Tanous #include <boost/asio/io_context.hpp> 2138ab5ecfSEd Tanous #include <boost/asio/posix/stream_descriptor.hpp> 22*93f5e283SPeter Foley #include <boost/asio/post.hpp> 2338ab5ecfSEd Tanous #include <boost/system/error_code.hpp> 247f664254SPatrick Williams 257f664254SPatrick Williams namespace sdbusplus 267f664254SPatrick Williams { 277f664254SPatrick Williams 287f664254SPatrick Williams namespace asio 297f664254SPatrick Williams { 307f664254SPatrick Williams /* A simple class to integrate the sd_event_loop into the boost::asio io_context 317f664254SPatrick Williams * in case a boost::asio user needs sd_events 327f664254SPatrick Williams */ 337f664254SPatrick Williams class sd_event_wrapper 347f664254SPatrick Williams { 357f664254SPatrick Williams public: sd_event_wrapper(boost::asio::io_context & io)367f664254SPatrick Williams sd_event_wrapper(boost::asio::io_context& io) : 377f664254SPatrick Williams evt(nullptr), descriptor(io), io(io) 387f664254SPatrick Williams { 397f664254SPatrick Williams sd_event_default(&evt); 407f664254SPatrick Williams if (evt) 417f664254SPatrick Williams { 427f664254SPatrick Williams descriptor.assign(sd_event_get_fd(evt)); 437f664254SPatrick Williams async_run(); 447f664254SPatrick Williams } 457f664254SPatrick Williams } sd_event_wrapper(sd_event * evt,boost::asio::io_context & io)467f664254SPatrick Williams sd_event_wrapper(sd_event* evt, boost::asio::io_context& io) : 477f664254SPatrick Williams evt(evt), descriptor(io), io(io) 487f664254SPatrick Williams { 497f664254SPatrick Williams if (evt) 507f664254SPatrick Williams { 517f664254SPatrick Williams sd_event_ref(evt); 527f664254SPatrick Williams descriptor.assign(sd_event_get_fd(evt)); 537f664254SPatrick Williams async_run(); 547f664254SPatrick Williams } 557f664254SPatrick Williams } ~sd_event_wrapper()567f664254SPatrick Williams ~sd_event_wrapper() 577f664254SPatrick Williams { 587f664254SPatrick Williams // sd_event really wants to close the descriptor on its own 597f664254SPatrick Williams // so this class must merely release it 607f664254SPatrick Williams descriptor.release(); 617f664254SPatrick Williams sd_event_unref(evt); 627f664254SPatrick Williams } 637f664254SPatrick Williams // process one event step in the queue 647f664254SPatrick Williams // return true if the queue is still alive run()657f664254SPatrick Williams void run() 667f664254SPatrick Williams { 677f664254SPatrick Williams int ret; 687f664254SPatrick Williams int state = sd_event_get_state(evt); 697f664254SPatrick Williams switch (state) 707f664254SPatrick Williams { 717f664254SPatrick Williams case SD_EVENT_INITIAL: 727f664254SPatrick Williams ret = sd_event_prepare(evt); 737f664254SPatrick Williams if (ret > 0) 747f664254SPatrick Williams { 757f664254SPatrick Williams async_run(); 767f664254SPatrick Williams } 777f664254SPatrick Williams else if (ret == 0) 787f664254SPatrick Williams { 797f664254SPatrick Williams async_wait(); 807f664254SPatrick Williams } 817f664254SPatrick Williams break; 827f664254SPatrick Williams case SD_EVENT_ARMED: 837f664254SPatrick Williams ret = sd_event_wait(evt, 0); 847f664254SPatrick Williams if (ret >= 0) 857f664254SPatrick Williams { 867f664254SPatrick Williams async_run(); 877f664254SPatrick Williams } 887f664254SPatrick Williams break; 897f664254SPatrick Williams case SD_EVENT_PENDING: 907f664254SPatrick Williams ret = sd_event_dispatch(evt); 917f664254SPatrick Williams if (ret > 0) 927f664254SPatrick Williams { 937f664254SPatrick Williams async_run(); 947f664254SPatrick Williams } 957f664254SPatrick Williams break; 967f664254SPatrick Williams case SD_EVENT_FINISHED: 977f664254SPatrick Williams break; 987f664254SPatrick Williams default: 997f664254SPatrick Williams // throw something? 1007f664254SPatrick Williams // doing nothing will break out of the async loop 1017f664254SPatrick Williams break; 1027f664254SPatrick Williams } 1037f664254SPatrick Williams } get() const1047f664254SPatrick Williams sd_event* get() const 1057f664254SPatrick Williams { 1067f664254SPatrick Williams return evt; 1077f664254SPatrick Williams } 1087f664254SPatrick Williams 1097f664254SPatrick Williams private: async_run()1107f664254SPatrick Williams void async_run() 1117f664254SPatrick Williams { 112936cb89eSEd Tanous boost::asio::post(io, [this]() { run(); }); 1137f664254SPatrick Williams } async_wait()1147f664254SPatrick Williams void async_wait() 1157f664254SPatrick Williams { 1167f664254SPatrick Williams descriptor.async_wait(boost::asio::posix::stream_descriptor::wait_read, 1177f664254SPatrick Williams [this](const boost::system::error_code& error) { 1187f664254SPatrick Williams if (!error) 1197f664254SPatrick Williams { 1207f664254SPatrick Williams run(); 1217f664254SPatrick Williams } 1227f664254SPatrick Williams }); 1237f664254SPatrick Williams } 1247f664254SPatrick Williams sd_event* evt; 1257f664254SPatrick Williams boost::asio::posix::stream_descriptor descriptor; 1267f664254SPatrick Williams boost::asio::io_context& io; 1277f664254SPatrick Williams }; 1287f664254SPatrick Williams 1297f664254SPatrick Williams } // namespace asio 1307f664254SPatrick Williams 1317f664254SPatrick Williams } // namespace sdbusplus 132