ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/iom.C
Revision: 1.2
Committed: Fri Mar 21 21:17:02 2003 UTC (21 years, 2 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +9 -8 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 #include <unistd.h>
2     /*
3     iom.C -- I/O multiplexor
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 <sys/time.h>
23    
24     #include <algorithm>
25     #include <functional>
26    
27     #include "slog.h"
28    
29     #include "iom.h"
30    
31     inline bool lowest_first (const time_watcher *a, const time_watcher *b)
32     {
33     return a->at > b->at;
34     }
35    
36 pcg 1.2 tstamp NOW;
37 pcg 1.1
38     io_manager iom;
39    
40 pcg 1.2 void time_watcher::set (tstamp when)
41 pcg 1.1 {
42     iom.unreg (this);
43     at = when;
44     iom.reg (this);
45     }
46    
47     void io_manager::reg (int fd, short events, io_watcher *w)
48     {
49     pollfd pfd;
50    
51     pfd.fd = fd;
52     pfd.events = events;
53    
54     pfs.push_back (pfd);
55     iow.push_back (w);
56     }
57    
58     void io_manager::unreg (io_watcher *w)
59     {
60     unsigned int sz = iow.size ();
61     unsigned int i = find (iow.begin (), iow.end (), w) - iow.begin ();
62    
63     if (i != sz)
64     {
65     if (sz == 1)
66     {
67     pfs.clear ();
68     iow.clear ();
69     }
70     else if (i == sz - 1)
71     {
72     iow.pop_back ();
73     pfs.pop_back ();
74     }
75     else
76     {
77     iow[i] = iow[sz - 1]; iow.pop_back ();
78     pfs[i] = pfs[sz - 1]; pfs.pop_back ();
79     }
80     }
81     }
82    
83     void io_manager::reg (time_watcher *w)
84     {
85     tw.push_back (w);
86     push_heap (tw.begin (), tw.end (), lowest_first);
87     }
88    
89     void io_manager::unreg (time_watcher *w)
90     {
91     unsigned int sz = tw.size ();
92     unsigned int i = find (tw.begin (), tw.end (), w) - tw.begin ();
93    
94     if (i != sz)
95     {
96     if (sz == 1)
97     tw.clear ();
98     else
99     {
100     if (i != sz - 1)
101     tw[i] = tw[sz - 1];
102    
103     tw.pop_back ();
104     make_heap (tw.begin (), tw.end (), lowest_first);
105     }
106     }
107     }
108    
109     inline void set_now (void)
110     {
111     struct timeval tv;
112    
113     gettimeofday (&tv, 0);
114    
115 pcg 1.2 NOW = (tstamp)tv.tv_sec + (tstamp)tv.tv_usec / 1000000;
116 pcg 1.1 }
117    
118     void io_manager::loop ()
119     {
120     set_now ();
121    
122 pcg 1.2 while (!(iow.empty () && tw.empty ()))
123 pcg 1.1 {
124 pcg 1.2 int timeout = tw.empty ()
125     ? 3600 * 1000 // wake up at least every hour
126     : (int) ((tw[0]->at - NOW) * 1000);
127 pcg 1.1
128 pcg 1.2 printf ("s%d t%d #%d\n", pfs.size (), timeout, tw.size ());
129 pcg 1.1
130     if (timeout >= 0)
131     {
132     int fds = poll (&pfs[0], pfs.size (), timeout);
133    
134     set_now ();
135    
136     for (unsigned int i = iow.size (); fds && i--; )
137     if (pfs[i].revents)
138     {
139     --fds;
140     iow[i]->call (pfs[i].revents);
141     }
142     }
143    
144     while (!tw.empty () && tw[0]->at <= NOW)
145     {
146     pop_heap (tw.begin (), tw.end (), lowest_first);
147 pcg 1.2 (*(tw.end () - 1))->trigger ();
148 pcg 1.1 push_heap (tw.begin (), tw.end (), lowest_first);
149     }
150     }
151     }
152    
153     io_manager::io_manager ()
154     {
155     set_now ();
156     }
157    
158     io_manager::~io_manager ()
159     {
160     //
161     }
162