Last active
February 2, 2022 03:43
-
-
Save dolphin8/f014a2ce861a858bbc995747ab96e9de to your computer and use it in GitHub Desktop.
using boost::asio with boost::context::callcc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <utility> | |
#include <boost/context/all.hpp> | |
#include <boost/asio.hpp> | |
#include <boost/date_time/posix_time/posix_time.hpp> | |
namespace spawn { | |
namespace asio = boost::asio; | |
namespace ctx = boost::context; | |
template <typename F> | |
struct yield_context { | |
F f; | |
ctx::continuation c1; | |
ctx::continuation c2; | |
yield_context(F&& f) : f(std::move(f)){} | |
}; | |
template <typename F> | |
struct yield_handler { | |
std::shared_ptr<yield_context<F>> y; | |
template <typename... T> | |
void operator()(T...) {y->c1 = y->c1.resume();} | |
void resume() {y->c2 = y->c2.resume();} | |
}; | |
template <typename F> | |
void spawn(asio::io_service& ios, F&& f) { | |
auto yc = std::make_shared<yield_context<F>>(std::move(f)); | |
ios.post([yc] { | |
yc->c1 = ctx::callcc([yc](auto&& cc) { | |
yc->c2 = std::move(cc); | |
yield_handler<F> yh{yc}; | |
yc->f(yh); | |
return std::move(yc->c2); | |
}); | |
}); | |
} | |
}; | |
namespace boost::asio { | |
template <typename F> | |
class async_result<::spawn::yield_handler<F>> { | |
public: | |
::spawn::yield_handler<F> y; | |
using type = void; | |
explicit async_result(::spawn::yield_handler<F>& _y) : y(_y) {} | |
type get() {y.resume();} | |
}; | |
} | |
int main(void) { | |
namespace asio = boost::asio; | |
using tcp = boost::asio::ip::tcp; | |
asio::io_service ios; | |
spawn::spawn(ios, [&](auto&& yield) { | |
tcp::acceptor acceptor{ios, {tcp::v4(), 1024}}; | |
for (;;) { | |
tcp::socket sock{ios}; | |
acceptor.async_accept(sock, yield); | |
spawn::spawn(ios, [&,sock=std::move(sock)](auto&& yield) mutable { | |
char buf[1024]; | |
sock.async_read_some(asio::buffer(buf), yield); | |
std::cout << buf; | |
asio::deadline_timer t{ios}; | |
t.expires_from_now(boost::posix_time::milliseconds{100}); | |
t.async_wait(yield); | |
asio::async_write(sock, asio::buffer("HTTP/1.1 200 OK\r\nContent-Length: 14\r\n\r\nHello, World!\n"), yield); | |
sock.close(); | |
}); | |
} | |
}); | |
ios.run(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment