Skip to content

Instantly share code, notes, and snippets.

@dolphin8
Last active February 2, 2022 03:43
Show Gist options
  • Save dolphin8/f014a2ce861a858bbc995747ab96e9de to your computer and use it in GitHub Desktop.
Save dolphin8/f014a2ce861a858bbc995747ab96e9de to your computer and use it in GitHub Desktop.
using boost::asio with boost::context::callcc
#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