ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/iom.h
Revision: 1.30
Committed: Thu Oct 25 10:44:14 2007 UTC (16 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.29: +71 -5 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 iom.h -- generic I/O multiplexer
3 Copyright (C) 2003-2006 Marc Lehmann <gvpe@schmorp.de>
4
5 This file is part of GVPE.
6
7 GVPE is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with gvpe; if not, write to the Free Software
19 Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #ifndef IOM_H__
23 #define IOM_H__
24
25 // required:
26 // - a vector template like simplevec or stl's vector
27 // - defines for all watcher types required in your app
28 // edit iom_conf.h as appropriate.
29 #include "iom_conf.h"
30
31 #if IOM_CHILD
32 # undef IOM_SIG
33 # define IOM_SIG 1
34 #endif
35
36 #include "callback.h"
37
38 typedef double tstamp;
39 extern tstamp NOW;
40
41 // TSTAMP_MAX must still fit into a positive struct timeval
42 #define TSTAMP_MAX (double)(1UL<<31)
43
44 //#define IOM_LIBEVENT "event.h" *NOT* a supported feature
45 #ifdef IOM_LIBEVENT
46 # include <sys/time.h>
47 # include IOM_LIBEVENT
48 # undef IOM_IO
49 # define IOM_IO 1
50 #endif
51
52 struct watcher;
53 #if IOM_IO
54 struct io_watcher;
55 #endif
56 #if IOM_TIME
57 struct time_watcher;
58 #endif
59 #if IOM_CHECK
60 struct check_watcher;
61 #endif
62 #if IOM_IDLE
63 struct idle_watcher;
64 #endif
65 #if IOM_SIG
66 struct sig_watcher;
67 #endif
68 #if IOM_CHILD
69 struct child_watcher;
70 #endif
71
72 template<class watcher>
73 struct io_manager_vec : vector<watcher *> {
74 void erase_unordered (unsigned int pos)
75 {
76 watcher *w = (*this)[this->size () - 1];
77 this->pop_back ();
78
79 if (!this->empty ())
80 if (((*this)[pos] = w)) // '=' is correct!
81 w->active = pos + 1;
82 }
83 };
84
85 // only used as a namespace, and for initialisation purposes
86 class io_manager {
87 template<class watcher>
88 static void reg (watcher &w, io_manager_vec<watcher> &queue);
89
90 template<class watcher>
91 static void unreg (watcher &w, io_manager_vec<watcher> &queue);
92
93 public:
94 #if IOM_TIME
95 // fetch time only
96 static tstamp now ();
97
98 // set NOW
99 static void set_now ();
100 #endif
101
102 // register a watcher
103 #ifndef IOM_LIBEVENT
104 #if IOM_IO
105 static void reg (io_watcher &w); static void unreg (io_watcher &w);
106 #endif
107 #if IOM_TIME
108 static void reg (time_watcher &w); static void unreg (time_watcher &w);
109 #endif
110 #if IOM_SIG
111 static void reg (sig_watcher &w); static void unreg (sig_watcher &w);
112 #endif
113 #if IOM_CHECK
114 static void reg (check_watcher &w); static void unreg (check_watcher &w);
115 #endif
116 #endif
117 #if IOM_IDLE
118 static void reg (idle_watcher &w); static void unreg (idle_watcher &w);
119 #endif
120 #if IOM_CHILD
121 static void reg (child_watcher &w); static void unreg (child_watcher &w);
122 #endif
123
124 static void loop ();
125 };
126
127 struct watcher {
128 int active; /* 0 == inactive, else index into respective vector */
129
130 bool is_active () { return active; }
131
132 watcher () : active (0) { }
133 };
134
135 #if IOM_IO
136 #ifdef IOM_LIBEVENT
137 enum { EVENT_UNDEF = -1, EVENT_NONE = 0, EVENT_READ = EV_READ, EVENT_WRITE = EV_WRITE };
138
139 void iom_io_c_callback (int fd, short events, void *data);
140
141 struct io_watcher : watcher, callback<void (io_watcher &, short)> {
142 struct event ev;
143 int fd;
144
145 void set (int fd_, short events_) { fd = fd_; event_set (&ev, fd_, events_, iom_io_c_callback, (void *)this); }
146
147 void set (short events_) { set (fd, events_); }
148 void start () { event_add (&ev, 0); active = 1; }
149 void start (int fd_, short events_) { set (fd_, events_); start (); }
150 void stop () { if (active) event_del (&ev); active = 0; }
151
152 template<class O, class M>
153 io_watcher (O object, M method)
154 : callback<void (io_watcher &, short)> (object, method)
155 { }
156 ~io_watcher () { stop (); }
157 };
158 #else
159 enum { EVENT_UNDEF = -1, EVENT_NONE = 0, EVENT_READ = 1, EVENT_WRITE = 2 };
160
161 struct io_watcher : watcher, callback<void (io_watcher &, short)> {
162 int fd;
163 short events;
164
165 void set (int fd_, short events_) { fd = fd_; events = events_; }
166
167 void set (short events_) { set (fd, events_); }
168 void start () { io_manager::reg (*this); }
169 void start (int fd_, short events_) { set (fd_, events_); start (); }
170 void stop () { io_manager::unreg (*this); }
171
172 template<class O, class M>
173 io_watcher (O object, M method)
174 : callback<void (io_watcher &, short)> (object, method)
175 { }
176 ~io_watcher () { stop (); }
177 };
178 #endif
179 #endif
180
181 #if IOM_TIME
182 #ifdef IOM_LIBEVENT
183 void iom_time_c_callback (int fd, short events, void *data);
184
185 struct time_watcher : watcher, callback<void (time_watcher &)> {
186 struct event ev;
187 tstamp at;
188
189 void trigger ();
190
191 void set (tstamp when) { at = when; }
192 void operator () () { trigger (); }
193 void start ()
194 {
195 struct timeval tv;
196 tv.tv_sec = (long)at;
197 tv.tv_usec = (long)((at - (tstamp)tv.tv_sec) * 1000000.);
198 evtimer_add (&ev, &tv);
199 active = 1;
200 }
201 void start (tstamp when) { set (when); start (); }
202 void stop () { if (active) evtimer_del (&ev); active = 0; }
203
204 template<class O, class M>
205 time_watcher (O object, M method)
206 : callback<void (time_watcher &)> (object, method), at (0)
207 {
208 evtimer_set (&ev, iom_time_c_callback, (void *)this);
209 }
210 ~time_watcher () { stop (); }
211 };
212 #else
213 struct time_watcher : watcher, callback<void (time_watcher &)> {
214 tstamp at;
215
216 void trigger ();
217
218 void set (tstamp when) { at = when; }
219 void operator () () { trigger (); }
220 void start () { io_manager::reg (*this); }
221 void start (tstamp when) { set (when); start (); }
222 void stop () { io_manager::unreg (*this); }
223
224 template<class O, class M>
225 time_watcher (O object, M method)
226 : callback<void (time_watcher &)> (object, method), at (0)
227 { }
228 ~time_watcher () { stop (); }
229 };
230 #endif
231 #endif
232
233 #if IOM_CHECK
234 // run before checking for new events
235 struct check_watcher : watcher, callback<void (check_watcher &)> {
236 void start () { io_manager::reg (*this); }
237 void stop () { io_manager::unreg (*this); }
238
239 template<class O, class M>
240 check_watcher (O object, M method)
241 : callback<void (check_watcher &)> (object, method)
242 { }
243 ~check_watcher () { stop (); }
244 };
245 #endif
246
247 #if IOM_IDLE
248 // run after checking for any i/o, but before waiting
249 struct idle_watcher : watcher, callback<void (idle_watcher &)> {
250 void start () { io_manager::reg (*this); }
251 void stop () { io_manager::unreg (*this); }
252
253 template<class O, class M>
254 idle_watcher (O object, M method)
255 : callback<void (idle_watcher &)> (object, method)
256 { }
257 ~idle_watcher () { stop (); }
258 };
259 #endif
260
261 #if IOM_SIG
262 struct sig_watcher : watcher, callback<void (sig_watcher &)> {
263 int signum;
264
265 void start (int signum);
266 void stop () { io_manager::unreg (*this); }
267
268 template<class O, class M>
269 sig_watcher (O object, M method)
270 : callback<void(sig_watcher &)> (object, method), signum (0)
271 { }
272 ~sig_watcher () { stop (); }
273 };
274 #endif
275
276 #if IOM_CHILD
277 struct child_watcher : watcher, callback<void (child_watcher &, int)> {
278 int /*pid_t*/ pid;
279
280 void start (int pid) { this->pid = pid; io_manager::reg (*this); }
281 void stop () { io_manager::unreg (*this); }
282
283 template<class O, class M>
284 child_watcher (O object, M method)
285 : callback<void (child_watcher &, int)> (object, method), pid (0)
286 { }
287 ~child_watcher () { stop (); }
288 };
289 #endif
290
291 #endif
292