]> git.decadent.org.uk Git - ion3.git/blob - libmainloop/select.c
[svn-upgrade] Integrating new upstream version, ion3 (20070506)
[ion3.git] / libmainloop / select.c
1 /*
2  * ion/libmainloop/mainloop.c
3  * 
4  * Partly based on a contributed code.
5  *
6  * See the included file LICENSE for details.
7  */
8
9 #include <libtu/types.h>
10 #include <libtu/misc.h>
11 #include <libtu/dlist.h>
12
13 #include "select.h"
14
15
16 /*{{{ File descriptor management */
17
18
19 static WInputFd *input_fds=NULL;
20
21 static WInputFd *find_input_fd(int fd)
22 {
23     WInputFd *tmp=input_fds;
24     
25     while(tmp){
26         if(tmp->fd==fd)
27             break;
28         tmp=tmp->next;
29     }
30     return tmp;
31 }
32
33 bool mainloop_register_input_fd(int fd, void *data,
34                                 void (*callback)(int fd, void *d))
35 {
36     WInputFd *tmp;
37     
38     if(find_input_fd(fd)!=NULL)
39         return FALSE;
40     
41     tmp=ALLOC(WInputFd);
42     if(tmp==NULL)
43         return FALSE;
44     
45     tmp->fd=fd;
46     tmp->data=data;
47     tmp->process_input_fn=callback;
48     
49     LINK_ITEM(input_fds, tmp, next, prev);
50     
51     return TRUE;
52 }
53
54 void mainloop_unregister_input_fd(int fd)
55 {
56     WInputFd *tmp=find_input_fd(fd);
57     
58     if(tmp!=NULL){
59         UNLINK_ITEM(input_fds, tmp, next, prev);
60         free(tmp);
61     }
62 }
63
64 static void set_input_fds(fd_set *rfds, int *nfds)
65 {
66     WInputFd *tmp=input_fds;
67     
68     while(tmp){
69         FD_SET(tmp->fd, rfds);
70         if(tmp->fd>*nfds)
71             *nfds=tmp->fd;
72         tmp=tmp->next;
73     }
74 }
75
76 static void check_input_fds(fd_set *rfds)
77 {
78     WInputFd *tmp=input_fds, *next=NULL;
79     
80     while(tmp){
81         next=tmp->next;
82         if(FD_ISSET(tmp->fd, rfds))
83             tmp->process_input_fn(tmp->fd, tmp->data);
84         tmp=next;
85     }
86 }
87
88 /*}}}*/
89
90
91 /*{{{ Select */
92
93 void mainloop_select()
94 {
95     fd_set rfds;
96     int nfds=0;
97             
98     FD_ZERO(&rfds);
99     
100     set_input_fds(&rfds, &nfds);
101     
102     if(select(nfds+1, &rfds, NULL, NULL, NULL)>0)
103         check_input_fds(&rfds);
104 }
105
106
107 /*}}}*/