ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/iom.C
Revision: 1.5
Committed: Wed Mar 26 01:58:46 2003 UTC (21 years, 2 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.4: +2 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 /*
2     iom.C -- I/O multiplexor
3    
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8    
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12     GNU General Public License for more details.
13    
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17     */
18    
19     #include "config.h"
20    
21     #include <sys/time.h>
22    
23     #include <algorithm>
24     #include <functional>
25    
26     #include "slog.h"
27     #include "iom.h"
28    
29     inline bool lowest_first (const time_watcher *a, const time_watcher *b)
30     {
31     return a->at > b->at;
32     }
33    
34 pcg 1.2 tstamp NOW;
35 pcg 1.1
36     io_manager iom;
37    
38 pcg 1.2 void time_watcher::set (tstamp when)
39 pcg 1.1 {
40     iom.unreg (this);
41     at = when;
42     iom.reg (this);
43     }
44    
45 pcg 1.4 void time_watcher::trigger ()
46     {
47     iom.unreg (this);
48     call (at);
49     iom.reg (this);
50     }
51    
52     void time_watcher::start ()
53     {
54     iom.unreg (this);
55     iom.reg (this);
56     }
57    
58 pcg 1.1 void io_manager::reg (int fd, short events, io_watcher *w)
59     {
60     pollfd pfd;
61    
62     pfd.fd = fd;
63     pfd.events = events;
64    
65     pfs.push_back (pfd);
66     iow.push_back (w);
67     }
68    
69 pcg 1.5 void io_manager::unreg (const io_watcher *w)
70 pcg 1.1 {
71     unsigned int sz = iow.size ();
72     unsigned int i = find (iow.begin (), iow.end (), w) - iow.begin ();
73    
74     if (i != sz)
75     {
76     if (sz == 1)
77     {
78     pfs.clear ();
79     iow.clear ();
80     }
81     else if (i == sz - 1)
82     {
83     iow.pop_back ();
84     pfs.pop_back ();
85     }
86     else
87     {
88     iow[i] = iow[sz - 1]; iow.pop_back ();
89     pfs[i] = pfs[sz - 1]; pfs.pop_back ();
90     }
91     }
92     }
93    
94     void io_manager::reg (time_watcher *w)
95     {
96     tw.push_back (w);
97     push_heap (tw.begin (), tw.end (), lowest_first);
98     }
99    
100 pcg 1.5 void io_manager::unreg (const time_watcher *w)
101 pcg 1.1 {
102     unsigned int sz = tw.size ();
103     unsigned int i = find (tw.begin (), tw.end (), w) - tw.begin ();
104    
105     if (i != sz)
106     {
107 pcg 1.4 if (i != sz - 1)
108     tw[i] = tw[sz - 1];
109 pcg 1.1
110 pcg 1.4 tw.pop_back ();
111     make_heap (tw.begin (), tw.end (), lowest_first);
112 pcg 1.1 }
113     }
114    
115     inline void set_now (void)
116     {
117     struct timeval tv;
118    
119     gettimeofday (&tv, 0);
120    
121 pcg 1.2 NOW = (tstamp)tv.tv_sec + (tstamp)tv.tv_usec / 1000000;
122 pcg 1.1 }
123    
124     void io_manager::loop ()
125     {
126     set_now ();
127    
128 pcg 1.4 for (;;)
129 pcg 1.1 {
130 pcg 1.4 while (tw[0]->at <= NOW)
131     {
132     pop_heap (tw.begin (), tw.end (), lowest_first);
133     time_watcher *w = *(tw.end () - 1);
134 pcg 1.1
135 pcg 1.4 if (w->at >= 0)
136     {
137     w->call (w->at);
138     push_heap (tw.begin (), tw.end (), lowest_first);
139     }
140     else
141     tw.pop_back ();
142     }
143 pcg 1.1
144 pcg 1.4 int timeout = (int) ((tw[0]->at - NOW) * 1000);
145 pcg 1.1
146 pcg 1.4 int fds = poll (&pfs[0], pfs.size (), timeout);
147 pcg 1.1
148 pcg 1.4 set_now ();
149 pcg 1.1
150 pcg 1.4 for (unsigned int i = iow.size (); fds > 0 && i--; )
151     if (pfs[i].revents)
152     {
153     --fds;
154     iow[i]->call (pfs[i].revents);
155     }
156 pcg 1.1 }
157     }
158    
159 pcg 1.4 void io_manager::idle_cb (tstamp &ts)
160     {
161     ts = NOW + 86400; // wake up every day, for no good reason
162     }
163    
164 pcg 1.1 io_manager::io_manager ()
165     {
166     set_now ();
167 pcg 1.4 idle = new time_watcher (this, &io_manager::idle_cb);
168     idle->start (0);
169 pcg 1.1 }
170    
171     io_manager::~io_manager ()
172     {
173     //
174     }
175