In my application, I have a thread which just runs std::getline() constantly to get user input, to then send it to a server via a socket. I've made a signal handler to close the program properly when I receive SIGINT. The signal calls a function named stop(), which closes the socket, and then I try to join my input thread. I have a problem stopping this thread, which I don't know how to solve.
atomic<bool> running = true;
int sock; //socket descriptor
void stop() {
    running = false; 
    close(sock);
}
wstring message = L"";
thread inputThread = thread([&]{
    while(running) {
        getline(wcin, message, L'\n');
        if (message.size() > 0) {
            send(sock, reinterpret_cast<const void*>(message.data()), (message.size()+1) * sizeof(wchar_t), 0);
        }
    }
});
The problem is that getline() blocks the thread even when running is false, preventing the thread from joining properly. send() does not block it, because the socket is already closed by that time. How do I close this thread, or how do I interrupt getline()?
I've tried using close(STDIN_FILENO); in the stop() function, but this seemed to not help, it does not end the thread.
Your current approach may work quite fine with normal files, as these getline() would return in a relatively predictable time and each occurence of the loop is an opportunity to leave it.  The only issue is that you don't check if the read was successful or if we're aleady at the end fo the file.
If getline() ought to read from an input device like cin, you cannot prevent the function from being blocked waiting for input in absence of any fatal error. The approach is then to read the input only if we're sure there is some input to read.
Unfortunately, there is no universal and portable way to deal with such situations. The simplest approach could just be to check for available input as explained in this SO answer or here. If no input is available, you'd just loop once more giving the opportunity of stopping the thread.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With