ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/select.C
Revision: 1.7
Committed: Sun Sep 16 18:54:45 2007 UTC (16 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +7 -2 lines
Log Message:
#defines to enum

File Contents

# Content
1 /*
2 * select.C: select(2) socket engine.
3 *
4 * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
5 * Rights to this code are as documented in COPYING.
6 *
7 *
8 * Portions of this file were derived from sources bearing the following license:
9 * Rights to this code are documented in doc/pod/license.pod.
10 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
11 */
12
13 static char const rcsid[] = "$Id: select.C,v 1.6 2007-09-05 11:23:15 pippijn Exp $";
14
15 #include "atheme.h"
16 #include "internal.h"
17 #include "datastream.h"
18
19 fd_set readfds, writefds;
20
21 /*
22 * init_socket_queues()
23 *
24 * inputs:
25 * none
26 *
27 * outputs:
28 * none
29 *
30 * side effects:
31 * when using select, we don't need to do anything here.
32 */
33 void
34 init_socket_queues (void)
35 {
36 return;
37 }
38
39 /*
40 * update_select_sets()
41 *
42 * inputs:
43 * none
44 *
45 * outputs:
46 * none
47 *
48 * side effects:
49 * registered sockets are prepared for the select() loop.
50 */
51 static void
52 update_select_sets (void)
53 {
54 connection_t::list_type::iterator it = connection_t::list.begin ();
55 connection_t::list_type::iterator et = connection_t::list.end ();
56 connection_t *cptr;
57
58 FD_ZERO (&readfds);
59 FD_ZERO (&writefds);
60
61 while (it != et)
62 {
63 cptr = *it;
64
65 if (cptr->is_connecting ())
66 FD_SET (cptr->fd, &writefds);
67
68 else if (cptr->is_listening ())
69 FD_SET (cptr->fd, &readfds);
70
71 if (sendq_nonempty (cptr))
72 FD_SET (cptr->fd, &writefds);
73
74 else
75 FD_SET (cptr->fd, &readfds);
76
77 ++it;
78 }
79 }
80
81 /*
82 * connection_t::select()
83 *
84 * inputs:
85 * delay in nanoseconds
86 *
87 * outputs:
88 * none
89 *
90 * side effects:
91 * registered sockets and their associated handlers are acted on.
92 */
93 void
94 connection_t::select (time_t delay)
95 {
96 int sr;
97 connection_t::list_type::iterator it = connection_t::list.begin ();
98 connection_t::list_type::iterator et = connection_t::list.end ();
99 connection_t *cptr;
100 timeval to;
101
102 update_select_sets ();
103 to.tv_sec = 0;
104 to.tv_usec = delay;
105
106 if ((sr = select (system_state.maxfd + 1, &readfds, &writefds, NULL, &to)) > 0)
107 {
108 /* Iterate twice, so we don't touch freed memory if
109 * a connection is closed.
110 * -- jilles */
111 while (it != et)
112 {
113 cptr = *it;
114
115 if (FD_ISSET (cptr->fd, &writefds))
116 {
117 if (cptr->is_connecting ())
118 cptr.callback.connected (cptr);
119 else
120 cptr->write_handler (cptr);
121 }
122
123 ++it;
124 }
125
126 for (it = connection_t::list.begin (), et = connection_t::list.end (); it != et; ++it)
127 {
128 cptr = *it;
129
130 if (FD_ISSET (cptr->fd, &readfds))
131 {
132 cptr->read_handler (cptr);
133 }
134 }
135
136 for (it = connection_t::list.begin (), et = connection_t::list.end (); it != et; ++it)
137 {
138 cptr = *it;
139 if (cptr->flags & CF_DEAD)
140 cptr->close ();
141 }
142 }
143 else
144 {
145 if (sr == 0)
146 {
147 /* select() timed out */
148 }
149 else if ((sr == -1) && (errno == EINTR))
150 {
151 /* some signal interrupted us, restart select() */
152 }
153 else if (sr == -1)
154 {
155 return;
156 }
157 }
158 }
159
160 /* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs
161 * vim:ts=8
162 * vim:sw=8
163 * vim:noexpandtab
164 */