| Michael F. Robbins on Mon, 24 Jun 2002 14:00:11 +0200 |
|
I'm writing a c++ app to read a command stream from a fifo. Commands
are delimited by newlines. The app must be able to process other tasks
(running in a while loop) if there is no data incoming from the fifo.
Right now, I'm using ifstream's rdbuf()->fd() to get the file descriptor
so I can use poll() on the fifo. When there is a read event, I do an
ifstream::getline() on the input stream class. The problem occurs when
the sending program sends two lines at once, i.e. before the listener
task is run again. The getline() is only called once for each poll()
that returns positive, however sometimes really two or more getline()s
are needed. I would have thought that checking for the POLLIN event
would have returned true since there were more data left to read.
However, my guess is that the ifstream class has an internal buffer
which has the next command inside, so the poll() returns false.
Any ideas? Right now I'm looking at setting O_NDELAY on the file
descriptor. This would certainly allow a simple read() function to work
on it, but would the getline() work correctly?
Here's the code in question:
------
// includes omitted for sanity
int main(int argc, char *argv[])
{
ifstream fifoIn("/path/to/fifo");
int fifoInID = fifoIn.rdbuf()->fd();
pollfd fifoInPollFD = {0, 0, 0};
fifoInPollFD.fd = fifoInID;
fifoInPollFD.events = POLLIN;
char lastCommandC[1024];
String lastCommand;
while(1) {
// Other stuff must be free to happen here
// if there are no new commands
// Check for tasks on message queue and process them.
fifoInPollFD.events = POLLIN;
fifoInPollFD.revents = 0;
// 10 millisecond timeout
if(poll(&fifoInPollFD, 1, 10) > 0) {
// Grab a line, stick it in lastCommandC, and
// convert it to a String class
fifoIn.getline(lastCommandC, sizeof lastCommandC, '\n');
lastCommandC[sizeof lastCommandC - 1] = '\0';
lastCommand = lastCommandC;
// No, this is not the error. The dispatch function
// is defined and works well.
cerr << "Dispatch: " << lastCommand << endl;
dispatch(lastCommand);
if(fifoIn.eof()) {
cerr << "eof on input fifo" << endl;
exit(0);
}
}
} // close while loop
return 0;
}
------
Thanks,
Michael F. Robbins
mike@gamerack.com
Attachment:
signature.asc
|
|