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