Simon Ninon
Simon Ninon

Reputation: 2451

Pipe + select: select never woken up

I'm building a small io service that checks read and write availability of some fds.

To do that, I have a thread dedicated to the select without any timeout so that the select only wakes up when a fd becomes available.

However, I sometimes want to force select to be woken up on specific events. To do so, I simply use a pipe, watch for its read availability and write on it when I want to wake up the select call.

This works most of the time, but it sometimes happens that nothing happen when I write to the pipe. So the select call remains blocked indefinitely.

Here is a part of the code I use:

Select thread:

FD_ZERO(&rd_set);
//! set some other fds...
FD_SET(m_notif_pipe_fds[0], &rd_set);
select(max_fd + 1, &rd_set, &wr_set, nullptr, nullptr);
if (FD_ISSET(m_notif_pipe_fds[0], &rd_set)) {
  char buf[1024];
  read(m_notif_pipe_fds[0], buf, 1024);
}

Notify thread:

write(m_notif_pipe_fds[1], "a", 1);

The max_fd variable has effectively been set to the highest fd value (not the number of fd to watch which is a common error).

Any idea?

Upvotes: 2

Views: 334

Answers (1)

user2807083
user2807083

Reputation: 2982

I'd suggest you to make your pipe non-blocking

int flags = fcntl(m_notif_pipe_fd[1], F_GETFL, 0);
assert(flags != -1);    
fcntl(m_notif_pipe_fd[1], F_SETFL, flags | O_NONBLOCK);

and set pipe buffer size to 1

int pipe_sz = fcntl(m_notif_pipe_fd[1], F_SETPIPE_SZ, 1);

See this question

Upvotes: 2

Related Questions