Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <boost/asio.hpp>
- #include <boost/asio/spawn.hpp>
- #include <iostream>
- #include <memory>
- #include <deque>
- class Suspender
- {
- private:
- using handler_type = boost::asio::handler_type<boost::asio::yield_context, void()>::type;
- using result_type = boost::asio::async_result<handler_type>;
- class HandlerWrapper
- {
- private:
- std::shared_ptr<handler_type> _handler;
- public:
- HandlerWrapper(boost::asio::yield_context yield) :
- _handler(std::make_shared<handler_type>(yield))
- {}
- HandlerWrapper(const HandlerWrapper &that) = default;
- HandlerWrapper(HandlerWrapper &&that) = default;
- void operator()()
- {
- return _handler->operator()();
- }
- handler_type &operator*()
- {
- return *_handler;
- }
- };
- std::deque<HandlerWrapper> _handlers;
- public:
- Suspender() = default;
- void suspend(boost::asio::yield_context yield)
- {
- _handlers.emplace_back(yield);
- result_type result{ *_handlers.back() };
- result.get();
- }
- void resume(boost::asio::io_service &service)
- {
- std::cout << "Resuming one of " << _handlers.size() << " waiting coroutines" << std::endl;
- if (_handlers.empty()) {
- return;
- }
- service.post(_handlers.front());
- _handlers.pop_front();
- }
- };
- int main()
- {
- boost::asio::io_service service;
- Suspender suspender;
- boost::asio::spawn(service, [&suspender](boost::asio::yield_context yield) {
- std::cout << "Suspending" << std::endl;
- suspender.suspend(yield);
- std::cout << "Woke up" << std::endl;
- });
- boost::asio::spawn(service, [&service, &suspender](boost::asio::yield_context yield) {
- suspender.resume(service);
- });
- service.run();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement