9

I'm using Linux as my programming platform. I am using poll(2) to know if my device is triggering an event.

The first call of poll is ok; it blocks and waits for the event to happen. But in the second poll function call, it will return; but it captures the event. Below is my code.

ret = poll( fds, 1, 2000); //2 secs timeout

if( fds[0].revents & POLLIN && ret > 0)
{
   printf("event occur\n");
}

It seems the queue/buffer is not empty. I'm just assuming.

What do you think is the problem?

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
domlao
  • 15,663
  • 34
  • 95
  • 134

5 Answers5

13

Obviously if you are polling incoming data you should consume available data (calling read()) or it will still be there and poll will return immediately. Symmetrically no operation is really necessary for POLLOUT, but you usually want to call the next write() as soon as possible. So as a rule of thumb POLLIN -> read, POLLOUT -> write.

You should also reset you pollfd struct before calling poll again.

fds[0].fd = sck;
fds[0].events = POLLIN;
fds[0].revents = 0;
ret = poll( fds, 1, 2000); //2 secs timeout

if( fds[0].revents & POLLIN && ret > 0)
{
   printf("event occur\n");
}

If you do not reset it each time, garbage from previous call can change poll behavior (well, not really, this is just a portability issue).

In production code you must also check for return value, as poll may have been interrupted for another reason than the expected event (like a signal). Then you usually want to call it again instead of reading data that is not available (as a reminder the poll return value is the number of events, 0 timeout, -1 some error, whose number is in errno).

Errors on files descriptors provided to poll may also occur. They will not make poll return an error but will set POLLERR, POLLHUP or POLLNVAL in the revent field of the pollfd structure for that file descriptor. If these events are set calling read will return some error code that you can check.

kriss
  • 23,497
  • 17
  • 97
  • 116
  • thanks. actually I always reset the values in my structure, and I think the best solution is to read the available data. – domlao Jun 11 '10 at 08:56
  • Thanks, but it seems I am getting an error in my read function call, it seems it return a -1 value, the errno said that argument is invalid, but im sure the parameters are correct. – domlao Jun 11 '10 at 09:32
  • I added a few lines on error checking. The most likely if that your first poll stops on timeout or error. I usually use a switch statement after each poll to manage error and timeout case, default being for normal case where some events occured. Anyway, if read fail you should have an error. Is your file descriptor okay ? Maybe open failed, or was not for reading, or file was closed... well, no need to guess, check the error. – kriss Jun 11 '10 at 09:37
  • I indeed have special handling with `POLLOUT`: I set that flag only when I have data in my buffer that I need to send through the socket (or other `fd`). That way I wake up _immediately_ (not if the socket buffer is full) and can do the write, but remove the flag from the poll fds when I have nothing to write to the `fd`. – Alexis Wilke May 30 '22 at 17:14
6

if you have an POLLIN event, which means "There is data to read" - do you call some read() function on your fd before poll()'ing again ?

zed_0xff
  • 32,417
  • 7
  • 53
  • 72
  • Thanks, but I don't need to read that data. The important to me is that there is an event. Do you think I need to read that. Is there any way I can just clear the buffer? – domlao Jun 11 '10 at 08:08
  • @domlao To clear the buffer you need to read from the `fd`. You can ignore the data you read, of course, so discarding it immediately. To avoid the even again, make sure you read until the buffer is empty. – Alexis Wilke May 30 '22 at 17:16
4

Its considered good practice to check for POLLHUP or POLLNVAL prior to reading the file descriptor. However, I believe that read() would just fail if that was the case, unless polling a file descriptor that expected to block for protracted periods, like a modem. In that case, you'd hang (depending on what you passed to open()).

You are probably not:

  • Reading the event FD at all before the next poll(), or,
  • Reading all of the available data.

If you have initialized the struct pollfd array prior to calling poll(), there should not be any 'garbage' to speak of.

Still, its probably a good idea to also check and be sure there is something worth bothering read() to do prior to calling it.

Tim Post
  • 33,371
  • 15
  • 110
  • 174
  • Thanks, I did some reading of the data, but it seems the read return a zero value, which means there is no data read. – domlao Jun 11 '10 at 09:16
  • @sasayins, is the FD something like a modem? What exactly are you polling? – Tim Post Jun 11 '10 at 10:19
4

poll gives you an event if there's data/events to read/errors/when you can write.

If you get an event saying "there's data to read" and you don't read anything - there will still be "data to read" the next time you call poll and you get another event.

nos
  • 223,662
  • 58
  • 417
  • 506
0
  1. poll() returns either 0 for timeout or -1 if error occurs. In addition revents can be checked for POLLERR.

    if( poll_return == 0 || poll_return == -1 || ((int)recvpoll.revents & POLLERR) ) return 0 ;
    
  2. If you are opening a file descriptor through fork process, then close previous file descriptor and open new one.

thatguy
  • 21,059
  • 6
  • 30
  • 40