I have a
std::thread that uses Boost's asio to read from a serial port:
port.open("COM9"); // Yeay no port enumeration support!
asio::read_until(port, buf, "\n");
auto it = asio::buffers_begin(buf.data());
string line(it, it + buf.size());
catch (std::exception e)
cout << "Serial thread error: " << e.what() << endl;
// Arrange it so that `quit = true;` happens when Ctrl-C is pressed.
int main(int argc, char *argv)
When I press Ctrl-C I want to cleanly exit the thread, so that all destructors are called appropriately (some drivers on Windows hate it if you don't close their resources properly).
Unfortunately as you can see, the current code blocks in
read_until() so when you press Ctrl-C nothing will happen until a new line of text is received.
One solution is to use polling, something like this:
asio::async_read_until(port, buf, "\n", ...);
But I'd rather not use polling. It is pretty inelegant. The only solution I can currently see is to have a
std::condition_variable quitOrIoFinished that is triggered either when
quit is set to true, or when the read finishes. But I didn't write asio so I can't give it a condition variable to wait on.
Is there any clean sane solution? In Go I would just use a
select to wait on multiple channels, whe