I'm trying to read asynchronously from stdin using ASIO on windows.
To this end, I tried to use an asio::windows::object_handle
.
I would expect that after async_wait
ing on the STDIN handle, ::ReadFile
on the same handle should not block.
However, it seems that this is not the case. In the following program, I would expect echos of my input from the first coroutine, interlaced with the test n
printouts from the second.
Instead, the ::ReadFile
call is blocking the io_context.run()
, so the test n
prints only happen after I presss return in the console.
#include <sdkddkver.h>
#include <chrono>
#include <iostream>
#include "asio/asio.hpp"
int main() {
using namespace std::chrono_literals;
asio::io_context ctx;
asio::high_resolution_timer timer(ctx);
asio::windows::object_handle stdin_handle(ctx,
::GetStdHandle(STD_INPUT_HANDLE));
/// stdin loop
asio::co_spawn(
ctx,
[&]() -> asio::awaitable<void> {
for (;;) {
co_await stdin_handle.async_wait(asio::use_awaitable);
char buf[100];
DWORD n;
// this is blocking?
ReadFile(stdin_handle.native_handle(), buf, sizeof(buf), &n, NULL);
std::cout << "input (" << n << "): " << std::string_view(buf, n);
}
},
asio::detached);
/// stdout loop
asio::co_spawn(
ctx,
[&]() -> asio::awaitable<void> {
for (int i = 0; i < 10; i++) {
std::cout << "test " << i << "\n";
timer.expires_after(1s);
co_await timer.async_wait(asio::use_awaitable);
}
},
asio::detached);
ctx.run();
return 0;
}
What am I doing wrong? Does object_handle::async_wait
wait for things other than actual input? How do I accomplish this?