ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/iom.C
Revision: 1.7
Committed: Fri Dec 19 06:17:03 2003 UTC (20 years, 5 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: rel-1-3, rel-1-2
Changes since 1.6: +55 -20 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 /*
2     iom.C -- generic I/O multiplexor
3     Copyright (C) 2003 Marc Lehmann <pcg@goof.com>
4    
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9    
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     GNU General Public License for more details.
14    
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18     */
19    
20     #include "../config.h"
21    
22     #include <cstdio>
23    
24     #include <sys/select.h>
25     #include <sys/time.h>
26    
27     #include "iom.h"
28    
29     tstamp NOW;
30     bool iom_valid;
31     io_manager iom;
32    
33 pcg 1.4 template<class watcher>
34     void io_manager::reg (watcher *w, simplevec<watcher *> &queue)
35     {
36     if (find (queue.begin (), queue.end (), w) == queue.end ())
37     queue.push_back (w);
38     }
39    
40     template<class watcher>
41     void io_manager::unreg (watcher *w, simplevec<watcher *> &queue)
42     {
43     queue.erase (find (queue.begin (), queue.end (), w));
44     }
45    
46     #if IOM_IO
47     io_watcher::~io_watcher ()
48     {
49     if (iom_valid)
50     iom.unreg (this);
51     }
52    
53     void io_manager::reg (io_watcher *w)
54     {
55     reg (w, iow);
56     }
57    
58     void io_manager::unreg (io_watcher *w)
59     {
60     unreg (w, iow);
61     }
62    
63     #endif
64    
65     #if IOM_TIME
66 pcg 1.1 void time_watcher::trigger ()
67     {
68     call (*this);
69    
70     iom.reg (this);
71     }
72    
73     time_watcher::~time_watcher ()
74     {
75     if (iom_valid)
76     iom.unreg (this);
77 pcg 1.3
78     at = TSTAMP_CANCEL;
79 pcg 1.1 }
80    
81 pcg 1.4 void io_manager::reg (time_watcher *w)
82 pcg 1.1 {
83 pcg 1.4 reg (w, tw);
84 pcg 1.1 }
85    
86 pcg 1.4 void io_manager::unreg (time_watcher *w)
87 pcg 1.1 {
88 pcg 1.4 unreg (w, tw);
89 pcg 1.1 }
90 pcg 1.4 #endif
91 pcg 1.1
92 pcg 1.4 #if IOM_CHECK
93     check_watcher::~check_watcher ()
94 pcg 1.1 {
95 pcg 1.4 if (iom_valid)
96     iom.unreg (this);
97 pcg 1.1 }
98    
99 pcg 1.4 void io_manager::reg (check_watcher *w)
100 pcg 1.1 {
101 pcg 1.4 reg (w, cw);
102 pcg 1.1 }
103    
104 pcg 1.4 void io_manager::unreg (check_watcher *w)
105 pcg 1.1 {
106 pcg 1.4 unreg (w, cw);
107 pcg 1.1 }
108 pcg 1.4 #endif
109 pcg 1.1
110 pcg 1.7 #if IOM_IDLE
111     idle_watcher::~idle_watcher ()
112     {
113     if (iom_valid)
114     iom.unreg (this);
115     }
116    
117     void io_manager::reg (idle_watcher *w)
118     {
119     reg (w, iw);
120     }
121    
122     void io_manager::unreg (idle_watcher *w)
123     {
124     unreg (w, iw);
125     }
126     #endif
127    
128 pcg 1.4 #if IOM_TIME
129 pcg 1.1 inline void set_now (void)
130     {
131     struct timeval tv;
132    
133     gettimeofday (&tv, 0);
134    
135     NOW = (tstamp)tv.tv_sec + (tstamp)tv.tv_usec / 1000000;
136 pcg 1.4 #endif
137 pcg 1.1 }
138    
139     void io_manager::loop ()
140     {
141 pcg 1.4 #if IOM_TIME
142 pcg 1.1 set_now ();
143 pcg 1.4 #endif
144 pcg 1.1
145     for (;;)
146     {
147 pcg 1.5 struct timeval *to = 0;
148     struct timeval tval;
149 pcg 1.1
150 pcg 1.7 #if IOM_IDLE
151     if (iw.size ())
152     {
153     tval.tv_sec = 0;
154     tval.tv_usec = 0;
155     to = &tval;
156     }
157     else
158     #endif
159 pcg 1.1 {
160 pcg 1.7 #if IOM_TIME
161     time_watcher *w;
162 pcg 1.1
163 pcg 1.7 for (;tw.size ();)
164     {
165     w = tw[0];
166 pcg 1.1
167 pcg 1.7 for (time_watcher **i = tw.begin (); i < tw.end (); ++i)
168     if ((*i)->at < w->at)
169     w = *i;
170    
171     if (w->at > NOW)
172     {
173     double diff = w->at - NOW;
174     tval.tv_sec = (int)diff;
175     tval.tv_usec = (int)((diff - tval.tv_sec) * 1000000);
176     to = &tval;
177     break;
178     }
179     else if (w->at >= 0)
180     w->call (*w);
181     else
182     unreg (w);
183 pcg 1.5 }
184 pcg 1.7 #endif
185 pcg 1.1 }
186 pcg 1.6
187     #if IOM_CHECK
188     for (int i = 0; i < cw.size (); ++i)
189     cw[i]->call (*cw[i]);
190 pcg 1.4 #endif
191 pcg 1.1
192 pcg 1.4 #if IOM_IO
193 pcg 1.1 fd_set rfd, wfd;
194    
195     FD_ZERO (&rfd);
196     FD_ZERO (&wfd);
197    
198     int fds = 0;
199    
200     for (io_watcher **w = iow.begin (); w < iow.end (); ++w)
201 pcg 1.2 {
202     if ((*w)->events & EVENT_READ ) FD_SET ((*w)->fd, &rfd);
203     if ((*w)->events & EVENT_WRITE) FD_SET ((*w)->fd, &wfd);
204 pcg 1.1
205 pcg 1.5 if ((*w)->fd >= fds) fds = (*w)->fd + 1;
206 pcg 1.2 }
207 pcg 1.1
208 pcg 1.5 if (!to && !fds)
209     break; // no events
210    
211     fds = select (fds, &rfd, &wfd, 0, to);
212 pcg 1.4 # if IOM_TIME
213 pcg 1.1 set_now ();
214 pcg 1.4 # endif
215 pcg 1.1
216     if (fds > 0)
217 pcg 1.4 for (int i = 0; i < iow.size (); ++i)
218 pcg 1.1 {
219 pcg 1.4 io_watcher *w = iow[i];
220 pcg 1.1
221 pcg 1.4 short revents = w->events;
222    
223     if (!FD_ISSET (w->fd, &rfd)) revents &= ~EVENT_READ;
224     if (!FD_ISSET (w->fd, &wfd)) revents &= ~EVENT_WRITE;
225 pcg 1.1
226     if (revents)
227 pcg 1.4 w->call (*w, revents);
228 pcg 1.1 }
229 pcg 1.7 #if IOM_IDLE
230     else if (iw.size ())
231     for (int i = 0; i < iw.size (); ++i)
232     iw[i]->call (*iw[i]);
233     #endif
234    
235 pcg 1.4 #elif IOM_TIME
236 pcg 1.5 if (!to)
237     break;
238    
239 pcg 1.4 select (0, 0, 0, 0, &to);
240     set_now ();
241 pcg 1.5 #else
242     break;
243 pcg 1.4 #endif
244 pcg 1.5 }
245 pcg 1.1 }
246    
247     io_manager::io_manager ()
248     {
249 pcg 1.5 #if IOM_TIME
250 pcg 1.1 set_now ();
251 pcg 1.5 #endif
252 pcg 1.1
253     iom_valid = true;
254     }
255    
256     io_manager::~io_manager ()
257     {
258     iom_valid = false;
259     }
260