Asynchronously read STDIN in Drogon/Trantor

I haven't blogged in quite a while. I've been busy on other stuff but they are just non blogable. At least for now. I hope one day I can publish them. Anyway, I was working on some web related code in Drogon and I need to read stdin so the user can control the application. Problem being, C++'s std::cin blocks. Nothing on the same thread can execute while it's waiting for the user for input. This might not be an issue for most CLI applications - it is one for mine. I need some background task running.

The solution turns out uses some fairlt unknown and low level API to interface with the poller. My solution is not fool proof (for instance, it'll block if stdin gets flushed and there's no newline in it). But good enough for my use case.

#include <drogin/utils/coroutine.h>
#include <drogin/drogon.h>
#include <trantor/net/Channel.h>

Task<std::string> asyncReadLineStdin()
    // CallbackAwaiter is a struct in Drogon that allows easy wrapping
    // from a callback into coroutine
    struct Awaiter : public CallbackAwaiter<std::string>
        trantor::Channel channel;

        // Create a channel to notify on stdin (0, per UNIX standard)
        Awaiter() : channel(app().getLoop(), 0) {}

        void await_suspend(std::coroutine_handle<> coro)
            // Tell Trantor we want to get a notification wehn stdin 
            // is readable
            channel.setReadCallback([this, coro]() {
                // when stdin is readable. We read a line from it
                std::string line;
                std::getline(std::cin, line);
                // Read the line. Set it as the coroutine's return value
                // We are no longer interested in stdin. Remove the channel
                // resume the coroutine

    // make sure we are on the main loop, else adding the channel will fail
    co_await switchThreadCoro(app().getLoop());
    std::string res = co_await Awaiter();
    co_return res;
Author's profile. Photo taken in VRChat by my friend Tast+
Martin Chang
Systems software, HPC, GPGPU and AI. I mostly write stupid C++ code. Sometimes does AI research. Chronic VRChat addict

I run TLGS, a major search engine on Gemini. Used by Buran by default.

  • marty1885 \at
  • Matrix:
  • Jami: a72b62ac04a958ca57739247aa1ed4fe0d11d2df