ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/src/poll.C
Revision: 1.6
Committed: Wed Sep 5 11:23:15 2007 UTC (16 years, 10 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.5: +8 -8 lines
Log Message:
removed GPLed code and put license back to BSD

File Contents

# User Rev Content
1 pippijn 1.1 /*
2     * poll.C: poll(2) socket engine.
3 pippijn 1.2 * Rights to this code are documented in doc/pod/license.pod.
4 pippijn 1.1 *
5 pippijn 1.4 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
6 pippijn 1.1 */
7    
8 pippijn 1.6 static char const rcsid[] = "$Id: poll.C,v 1.5 2007-08-30 19:56:26 pippijn Exp $";
9 pippijn 1.1
10     #include <sys/poll.h>
11    
12     #include "atheme.h"
13     #include "internal.h"
14     #include "datastream.h"
15 pippijn 1.5 #include "connection.h"
16 pippijn 1.1
17     /*
18     * linux does not provide POLLWRNORM by default, and we're not _XOPEN_SOURCE.
19     * so.... we have to do this crap below.
20     */
21     #ifndef POLLRDNORM
22     #define POLLRDNORM POLLIN
23     #endif
24     #ifndef POLLWRNORM
25     #define POLLWRNORM POLLOUT
26     #endif
27    
28 pippijn 1.4 pollfd pollfds[FD_SETSIZE]; /* XXX We need a define indicating MAXCONN. */
29 pippijn 1.1
30     /*
31     * init_socket_queues()
32     *
33     * inputs:
34     * none
35     *
36     * outputs:
37     * none
38     *
39     * side effects:
40     * when using select, we don't need to do anything here.
41     */
42     void
43     init_socket_queues (void)
44     {
45 pippijn 1.4 memset (&pollfds, 0, sizeof (pollfd) * FD_SETSIZE);
46 pippijn 1.1 }
47    
48     /*
49     * update_poll_fds()
50     *
51     * inputs:
52     * none
53     *
54     * outputs:
55     * none
56     *
57     * side effects:
58     * registered sockets are prepared for the poll() loop.
59     */
60     static void
61     update_poll_fds (void)
62     {
63 pippijn 1.6 connection_t::list_type::iterator it = connection_t::list.begin ();
64     connection_t::list_type::iterator et = connection_t::list.end ();
65 pippijn 1.1 int slot = 0;
66    
67 pippijn 1.4 while (it != et)
68     {
69     connection_t *cptr = *it;
70    
71     cptr->pollslot = slot;
72    
73 pippijn 1.5 if (cptr->is_connecting () || sendq_nonempty (cptr))
74 pippijn 1.4 {
75     pollfds[slot].fd = cptr->fd;
76     pollfds[slot].events |= POLLWRNORM;
77     pollfds[slot].revents = 0;
78     }
79     else
80     {
81     pollfds[slot].fd = cptr->fd;
82     pollfds[slot].events |= POLLRDNORM;
83     pollfds[slot].revents = 0;
84     }
85     slot++;
86     ++it;
87     }
88 pippijn 1.1 }
89    
90     /*
91 pippijn 1.5 * connection_t::select()
92 pippijn 1.1 *
93     * inputs:
94     * delay in microseconds
95     *
96     * outputs:
97     * none
98     *
99     * side effects:
100     * registered sockets and their associated handlers are acted on.
101     */
102     void
103 pippijn 1.5 connection_t::select (time_t delay)
104 pippijn 1.1 {
105     int sr;
106 pippijn 1.6 connection_t::list_type::iterator it = connection_t::list.begin ();
107     connection_t::list_type::iterator et = connection_t::list.end ();
108 pippijn 1.1 int slot;
109    
110     update_poll_fds ();
111    
112 pippijn 1.6 if ((sr = poll (pollfds, connection_t::list.size (), delay / 100)) > 0)
113 pippijn 1.1 {
114     /* Iterate twice, so we don't touch freed memory if
115     * a connection is closed.
116     * -- jilles */
117 pippijn 1.4 while (it != et)
118     {
119     connection_t *cptr = *it;
120     ++it; // increment here or continue will cause an endless loop
121     slot = cptr->pollslot;
122    
123     if (pollfds[slot].revents == 0)
124     continue;
125    
126     if (pollfds[slot].revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
127     {
128     pollfds[slot].events &= ~(POLLRDNORM | POLLIN | POLLHUP | POLLERR);
129     cptr->read_handler (cptr);
130     }
131     }
132    
133 pippijn 1.6 for (it = connection_t::list.begin (), et = connection_t::list.end (); it != et; ++it)
134 pippijn 1.4 {
135     connection_t *cptr = *it;
136     slot = cptr->pollslot;
137    
138     if (pollfds[slot].revents == 0)
139     continue;
140     if (pollfds[slot].revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
141     {
142     pollfds[slot].events &= ~(POLLWRNORM | POLLOUT | POLLHUP | POLLERR);
143 pippijn 1.5 if (cptr->is_connecting ())
144 pippijn 1.4 cptr->callback.connected (cptr);
145     else
146     cptr->write_handler (cptr);
147     }
148     }
149    
150 pippijn 1.6 for (it = connection_t::list.begin (), et = connection_t::list.end (); it != et; ++it)
151 pippijn 1.4 {
152     connection_t *cptr = *it;
153     if (cptr->flags & CF_DEAD)
154 pippijn 1.5 cptr->close ();
155 pippijn 1.4 }
156 pippijn 1.1 }
157     }