ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/iom.h
Revision: 1.26
Committed: Thu Jan 19 11:56:00 2006 UTC (18 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-7_1
Changes since 1.25: +1 -1 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 struct watcher;
45 #if IOM_IO
46 struct io_watcher;
47 #endif
48 #if IOM_TIME
49 struct time_watcher;
50 #endif
51 #if IOM_CHECK
52 struct check_watcher;
53 #endif
54 #if IOM_IDLE
55 struct idle_watcher;
56 #endif
57 #if IOM_SIG
58 struct sig_watcher;
59 #endif
60 #if IOM_CHILD
61 struct child_watcher;
62 #endif
63
64 template<class watcher>
65 struct io_manager_vec : vector<watcher *> {
66 void erase_unordered (unsigned int pos)
67 {
68 watcher *w = (*this)[this->size () - 1];
69 this->pop_back ();
70
71 if (!this->empty ())
72 if (((*this)[pos] = w)) // '=' is correct!
73 w->active = pos + 1;
74 }
75 };
76
77 // only used as a namespace, and for initialisation purposes
78 class io_manager {
79 template<class watcher>
80 static void reg (watcher &w, io_manager_vec<watcher> &queue);
81
82 template<class watcher>
83 static void unreg (watcher &w, io_manager_vec<watcher> &queue);
84
85 public:
86 #if IOM_TIME
87 // fetch time only
88 static tstamp now ();
89
90 // set NOW
91 static void set_now ();
92 #endif
93
94 // register a watcher
95 #if IOM_IO
96 static void reg (io_watcher &w); static void unreg (io_watcher &w);
97 #endif
98 #if IOM_TIME
99 static void reg (time_watcher &w); static void unreg (time_watcher &w);
100 #endif
101 #if IOM_CHECK
102 static void reg (check_watcher &w); static void unreg (check_watcher &w);
103 #endif
104 #if IOM_IDLE
105 static void reg (idle_watcher &w); static void unreg (idle_watcher &w);
106 #endif
107 #if IOM_SIG
108 static void reg (sig_watcher &w); static void unreg (sig_watcher &w);
109 #endif
110 #if IOM_CHILD
111 static void reg (child_watcher &w); static void unreg (child_watcher &w);
112 #endif
113
114 static void loop ();
115 };
116
117 struct watcher {
118 int active; /* 0 == inactive, else index into respective vector */
119
120 watcher () : active (0) { }
121 };
122
123 #if IOM_IO
124 enum { EVENT_UNDEF = -1, EVENT_NONE = 0, EVENT_READ = 1, EVENT_WRITE = 2 };
125
126 struct io_watcher : watcher, callback2<void, io_watcher &, short> {
127 int fd;
128 short events;
129
130 void set (int fd_, short events_) { fd = fd_; events = events_; }
131
132 void set (short events_) { set (fd, events_); }
133 void start () { io_manager::reg (*this); }
134 void start (int fd_, short events_) { set (fd_, events_); io_manager::reg (*this); }
135 void stop () { io_manager::unreg (*this); }
136
137 template<class O1, class O2>
138 io_watcher (O1 *object, void (O2::*method) (io_watcher &, short))
139 : callback2<void, io_watcher &, short> (object, method)
140 { }
141 ~io_watcher () { stop (); }
142 };
143 #endif
144
145 #if IOM_TIME
146 struct time_watcher : watcher, callback1<void, time_watcher &> {
147 tstamp at;
148
149 void trigger ();
150
151 void set (tstamp when) { at = when; }
152 void operator () () { trigger (); }
153 void start () { io_manager::reg (*this); }
154 void start (tstamp when) { set (when); io_manager::reg (*this); }
155 void stop () { io_manager::unreg (*this); }
156
157 template<class O1, class O2>
158 time_watcher (O1 *object, void (O2::*method) (time_watcher &))
159 : callback1<void, time_watcher &> (object, method), at (0)
160 { }
161 ~time_watcher () { stop (); }
162 };
163 #endif
164
165 #if IOM_CHECK
166 // run before checking for new events
167 struct check_watcher : watcher, callback1<void, check_watcher &> {
168 void start () { io_manager::reg (*this); }
169 void stop () { io_manager::unreg (*this); }
170
171 template<class O1, class O2>
172 check_watcher (O1 *object, void (O2::*method) (check_watcher &))
173 : callback1<void, check_watcher &> (object, method)
174 { }
175 ~check_watcher () { stop (); }
176 };
177 #endif
178
179 #if IOM_IDLE
180 // run after checking for any i/o, but before waiting
181 struct idle_watcher : watcher, callback1<void, idle_watcher &> {
182 void start () { io_manager::reg (*this); }
183 void stop () { io_manager::unreg (*this); }
184
185 template<class O1, class O2>
186 idle_watcher (O1 *object, void (O2::*method) (idle_watcher &))
187 : callback1<void, idle_watcher &> (object, method)
188 { }
189 ~idle_watcher () { stop (); }
190 };
191 #endif
192
193 #if IOM_SIG
194 struct sig_watcher : watcher, callback1<void, sig_watcher &> {
195 int signum;
196
197 void start (int signum);
198 void stop () { io_manager::unreg (*this); }
199
200 template<class O1, class O2>
201 sig_watcher (O1 *object, void (O2::*method) (sig_watcher &))
202 : callback1<void, sig_watcher &> (object, method), signum (0)
203 { }
204 ~sig_watcher () { stop (); }
205 };
206 #endif
207
208 #if IOM_CHILD
209 struct child_watcher : watcher, callback2<void, child_watcher &, int> {
210 int /*pid_t*/ pid;
211
212 void start (int pid) { this->pid = pid; io_manager::reg (*this); }
213 void stop () { io_manager::unreg (*this); }
214
215 template<class O1, class O2>
216 child_watcher (O1 *object, void (O2::*method) (child_watcher &, int status))
217 : callback2<void, child_watcher &, int> (object, method), pid (0)
218 { }
219 ~child_watcher () { stop (); }
220 };
221 #endif
222
223 #endif
224