Reputation: 2451
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
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