Strange behavior from poll() when interrupted by signal

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Strange behavior from poll() when interrupted by signal

Yarin-3
Hello,

As the documentation explains, when poll() is interrupted by a signal, it should return -1/EINTR.
However, I'm getting a return indicating that all of the polling descriptors are ready, but when I check their flags out, none of them are
ready. (Note that the same code behaves as expected on Linux)

This is on the Generic 4.7 release kernel.

Here's a snippet of code that I wrote to deal smoothly this behavior: (specifically, the last line)


   pollfd wait_fd[2];
   wait_fd[0].fd = sock_fd;
   wait_fd[0].events = POLLOUT;
   wait_fd[1].fd = abort_fd;
   wait_fd[1].events = POLLIN;
   int rfds;
   do
      rfds = poll(wait_fd, 2, NULL);
   while((rfds < 0 && errno == EINTR) || (rfds > 0 && !wait_fd[0].revents && !wait_fd[1].revents));


The thing is, I have no idea if this this is a feature or bug, or what. :-P

Thanks for any input,

Yarin

Reply | Threaded
Open this post in threaded view
|

Re: Strange behavior from poll() when interrupted by signal

Remco-2
Yarin wrote:

> Hello,
>
> As the documentation explains, when poll() is interrupted by a signal, it
> should return -1/EINTR. However, I'm getting a return indicating that all
> of the polling descriptors are ready, but when I check their flags out,
> none of them are ready. (Note that the same code behaves as expected on
> Linux)
>
>       rfds = poll(wait_fd, 2, NULL);

What does that NULL do ?

Reply | Threaded
Open this post in threaded view
|

Re: Strange behavior from poll() when interrupted by signal

Joachim Schipper-2
In reply to this post by Yarin-3
On Sun, Dec 12, 2010 at 01:00:17PM -0600, Yarin wrote:
> As the documentation explains, when poll() is interrupted by a signal, it should return -1/EINTR.
> However, I'm getting a return indicating that all of the polling descriptors are ready, but when I check their flags out, none of them are
> ready. (Note that the same code behaves as expected on Linux)

> Here's a snippet of code that I wrote to deal smoothly this behavior: (specifically, the last line)

>    pollfd wait_fd[2];
>    wait_fd[0].fd = sock_fd;
>    wait_fd[0].events = POLLOUT;
>    wait_fd[1].fd = abort_fd;
>    wait_fd[1].events = POLLIN;
>    int rfds;
>    do
>       rfds = poll(wait_fd, 2, NULL);
                                ^^^^
>    while((rfds < 0 && errno == EINTR) || (rfds > 0 && !wait_fd[0].revents && !wait_fd[1].revents));

This is not valid - poll takes an int argument here. NULL is interpreted
as 0 (return immediately) on most platforms, which means you're
busy-waiting. And that poll() will usually return 0 ("timeout reached").
This matches your observations, as far as I can tell.

I *think* you meant:

  while ((rfds = poll(wait_fd, 2, INFTIM)) == -1 && errno == EINTR);
  if (rfds == -1)
  err(1, "Poll failed");

Note that poll cannot return 0 here.

                Joachim

--
TFMotD: poll (2) - synchronous I/O multiplexing
http://www.joachimschipper.nl/