4 * Partly based on a contributed code.
6 * See the included file LICENSE for details.
10 #include <sys/select.h>
13 #include <libtu/types.h>
14 #include <libtu/misc.h>
15 #include <libtu/dlist.h>
21 /*{{{ File descriptor management */
24 static WInputFd *input_fds=NULL;
26 static WInputFd *find_input_fd(int fd)
28 WInputFd *tmp=input_fds;
38 bool mainloop_register_input_fd(int fd, void *data,
39 void (*callback)(int fd, void *d))
43 if(find_input_fd(fd)!=NULL)
52 tmp->process_input_fn=callback;
54 LINK_ITEM(input_fds, tmp, next, prev);
59 void mainloop_unregister_input_fd(int fd)
61 WInputFd *tmp=find_input_fd(fd);
64 UNLINK_ITEM(input_fds, tmp, next, prev);
69 static void set_input_fds(fd_set *rfds, int *nfds)
71 WInputFd *tmp=input_fds;
74 FD_SET(tmp->fd, rfds);
81 static void check_input_fds(fd_set *rfds)
83 WInputFd *tmp=input_fds, *next=NULL;
87 if(FD_ISSET(tmp->fd, rfds))
88 tmp->process_input_fn(tmp->fd, tmp->data);
98 void mainloop_select()
110 set_input_fds(&rfds, &nfds);
112 mainloop_block_signals(&oldmask);
114 if(!mainloop_unhandled_signals())
115 ret=pselect(nfds+1, &rfds, NULL, NULL, NULL, &oldmask);
117 sigprocmask(SIG_SETMASK, &oldmask, NULL);
120 #warning "pselect() unavailable -- using dirty hacks"
122 struct timeval tv={0, 0};
124 /* If there are timers, make sure we return from select with
125 * some delay, if the timer signal happens right before
126 * entering select(). Race conditions with other signals
127 * we'll just have to ignore without pselect().
131 set_input_fds(&rfds, &nfds);
133 bool to=libmainloop_get_timeout(&tv);
135 if(mainloop_unhandled_signals()){
140 ret=select(nfds+1, &rfds, NULL, NULL, to ? &tv : NULL);
141 }while(ret<0 && errno==EINTR && !mainloop_unhandled_signals());
145 check_input_fds(&rfds);