I am setting up a (receiving) thread that uses std::getline on a fifo (named pipe). The peer may or may not be present (actually I do not get to the getline until I know there is a peer) and may or may not send data. Eventually, I may decide to shutdown the operation of the FIFO.
I need to be able to cleanup the receiving thread. But for this std::getline must return. I was hoping that doing a close on the std::ifstream would suffice. But it appears not to be the case.
I have this minimal case that hangs at the line rr.get()
void test() {
std::filesystem::path path1("/tmp/f1");
int retval = mkfifo(path1.string().c_str(), (unsigned int)0660);
// Open TX side
std::ofstream txStream;
std::future<void> tt = std::async([&]() {
txStream.open(path1, std::ios::binary | std::ios::out | std::ios::trunc);
return;
});
// Open RX side
std::ifstream rxStream;
rxStream.open(path1, std::ios::binary | std::ios::in);
// Setup getline
std::future<void> rr = std::async([&]() {
std::string line = "XX";
std::getline(rxStream, line);
std::cout << " Line is: " << line << std::endl;
});
std::this_thread::sleep_for(250ms);
rxStream.close();
if (tt.valid() == true) {
tt.get();
std::cout << "Done Tx" << std::endl;
} else {
std::cout << "Tx task not valid" << std::endl;
}
if (rr.valid() == true) {
rr.get();
std::cout << "Done Rx" << std::endl;
} else {
std::cout << "Rx task not valid" << std::endl;
}
}
Is there an alternative and reliable way to unblock std::getline?