0

I want to poll stdin asynchronously for terminal keyboard events, hence the following

/* class tui contains a member 'stdin_' of type 'asio::stream_descriptor',
   initialized as such : stdin_{io_strand_,STDIN_FILENO}
*/
void tui::a_read_loop(){
    stdin_.async_read_some(buffer_,[this](const auto& ec, size_t n){
        if(ec==asio::error::operation_aborted);//canceled
        else{
            //...treat input...
            a_read_loop();//chainloop
        }
    });
}

moreover, I am putting the terminal in raw mode as such:

termattr.c_cflag|=CS8;
termattr.c_iflag|=IGNBRK;
termattr.c_iflag&=~(tcflag_t)(ICRNL|INLCR|IXOFF|IXON|IXANY);
termattr.c_lflag&=~(tcflag_t)(ECHO|ECHOE|ECHOK|ECHONL|ICANON|IEXTEN|ISIG);
termattr.c_oflag|=OPOST;
termattr.c_cc[VMIN]=1;
termattr.c_cc[VTIME]=0;
tcsetattr(STDIN_FILENO,TCSAFLUSH,&termattr);
std::setvbuf(stdin,nullptr,_IONBF,0);

so I can catch any event immediately.

This works, mostly, except it crashes when, apparently, too much input is thrown at it and it can't cope fast enough:

terminate called after throwing an instance of 'std::system_error'
  what():  cannot write to file: Resource temporarily unavailable

The above exception is not raised from inside any handler, but seemingly from the asynchronous task itself, and crashes the asio::thread_pool on which it is beeing executed.

From my investigation, I found this could be related to EAGAIN beeing encountered despite asio::stream_descriptor no enjoying it. I have tried many combinations of settings (eg of non_blocking and native_non_blocking) and still obtain the error under heavy load.

Moreover the above code has another issue which I couln't figure out: sometimes it may happen that buffer_ contains 2 consecutive key codes, and since I am not aware of any way to parse them and know the correct length of one particular event, I just can't detect that.

What is the proper way of asynchronously read from stdin event by event using asio::stream_descriptor ?

2

0

Browse other questions tagged or ask your own question.