4 * Partly based on a contributed code.
6 * See the included file LICENSE for details.
10 #include <sys/select.h>
14 #include <libtu/types.h>
15 #include <libtu/misc.h>
16 #include <libtu/dlist.h>
22 /*{{{ File descriptor management */
25 static WInputFd
*input_fds
=NULL
;
27 static WInputFd
*find_input_fd(int fd
)
29 WInputFd
*tmp
=input_fds
;
39 bool mainloop_register_input_fd(int fd
, void *data
,
40 void (*callback
)(int fd
, void *d
))
44 if(find_input_fd(fd
)!=NULL
)
53 tmp
->process_input_fn
=callback
;
55 LINK_ITEM(input_fds
, tmp
, next
, prev
);
60 void mainloop_unregister_input_fd(int fd
)
62 WInputFd
*tmp
=find_input_fd(fd
);
65 UNLINK_ITEM(input_fds
, tmp
, next
, prev
);
70 static void set_input_fds(fd_set
*rfds
, int *nfds
)
72 WInputFd
*tmp
=input_fds
;
75 FD_SET(tmp
->fd
, rfds
);
82 static void check_input_fds(fd_set
*rfds
)
84 WInputFd
*tmp
=input_fds
, *next
=NULL
;
88 if(FD_ISSET(tmp
->fd
, rfds
))
89 tmp
->process_input_fn(tmp
->fd
, tmp
->data
);
99 void mainloop_select()
106 #if _POSIX_SELECT || _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
111 set_input_fds(&rfds
, &nfds
);
113 mainloop_block_signals(&oldmask
);
115 if(!mainloop_unhandled_signals())
116 ret
=pselect(nfds
+1, &rfds
, NULL
, NULL
, NULL
, &oldmask
);
118 sigprocmask(SIG_SETMASK
, &oldmask
, NULL
);
121 #warning "pselect() unavailable -- using dirty hacks"
123 struct timeval tv
={0, 0};
126 /* If there are timers, make sure we return from select with
127 * some delay, if the timer signal happens right before
128 * entering select(). Race conditions with other signals
129 * we'll just have to ignore without pselect().
134 set_input_fds(&rfds
, &nfds
);
136 to
=libmainloop_get_timeout(&tv
);
138 if(mainloop_unhandled_signals()){
143 ret
=select(nfds
+1, &rfds
, NULL
, NULL
, to
? &tv
: NULL
);
144 }while(ret
<0 && errno
==EINTR
&& !mainloop_unhandled_signals());
148 check_input_fds(&rfds
);