ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/iom.C
Revision: 1.3
Committed: Fri Mar 21 21:21:02 2003 UTC (21 years, 2 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +0 -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     void io_manager::reg (int fd, short events, io_watcher *w)
46     {
47     pollfd pfd;
48    
49     pfd.fd = fd;
50     pfd.events = events;
51    
52     pfs.push_back (pfd);
53     iow.push_back (w);
54     }
55    
56     void io_manager::unreg (io_watcher *w)
57     {
58     unsigned int sz = iow.size ();
59     unsigned int i = find (iow.begin (), iow.end (), w) - iow.begin ();
60    
61     if (i != sz)
62     {
63     if (sz == 1)
64     {
65     pfs.clear ();
66     iow.clear ();
67     }
68     else if (i == sz - 1)
69     {
70     iow.pop_back ();
71     pfs.pop_back ();
72     }
73     else
74     {
75     iow[i] = iow[sz - 1]; iow.pop_back ();
76     pfs[i] = pfs[sz - 1]; pfs.pop_back ();
77     }
78     }
79     }
80    
81     void io_manager::reg (time_watcher *w)
82     {
83     tw.push_back (w);
84     push_heap (tw.begin (), tw.end (), lowest_first);
85     }
86    
87     void io_manager::unreg (time_watcher *w)
88     {
89     unsigned int sz = tw.size ();
90     unsigned int i = find (tw.begin (), tw.end (), w) - tw.begin ();
91    
92     if (i != sz)
93     {
94     if (sz == 1)
95     tw.clear ();
96     else
97     {
98     if (i != sz - 1)
99     tw[i] = tw[sz - 1];
100    
101     tw.pop_back ();
102     make_heap (tw.begin (), tw.end (), lowest_first);
103     }
104     }
105     }
106    
107     inline void set_now (void)
108     {
109     struct timeval tv;
110    
111     gettimeofday (&tv, 0);
112    
113 pcg 1.2 NOW = (tstamp)tv.tv_sec + (tstamp)tv.tv_usec / 1000000;
114 pcg 1.1 }
115    
116     void io_manager::loop ()
117     {
118     set_now ();
119    
120 pcg 1.2 while (!(iow.empty () && tw.empty ()))
121 pcg 1.1 {
122 pcg 1.2 int timeout = tw.empty ()
123     ? 3600 * 1000 // wake up at least every hour
124     : (int) ((tw[0]->at - NOW) * 1000);
125 pcg 1.1
126 pcg 1.2 printf ("s%d t%d #%d\n", pfs.size (), timeout, tw.size ());
127 pcg 1.1
128     if (timeout >= 0)
129     {
130     int fds = poll (&pfs[0], pfs.size (), timeout);
131    
132     set_now ();
133    
134     for (unsigned int i = iow.size (); fds && i--; )
135     if (pfs[i].revents)
136     {
137     --fds;
138     iow[i]->call (pfs[i].revents);
139     }
140     }
141    
142     while (!tw.empty () && tw[0]->at <= NOW)
143     {
144     pop_heap (tw.begin (), tw.end (), lowest_first);
145 pcg 1.2 (*(tw.end () - 1))->trigger ();
146 pcg 1.1 push_heap (tw.begin (), tw.end (), lowest_first);
147     }
148     }
149     }
150    
151     io_manager::io_manager ()
152     {
153     set_now ();
154     }
155    
156     io_manager::~io_manager ()
157     {
158     //
159     }
160