ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/poll.C
Revision: 1.4
Committed: Tue Aug 28 17:08:12 2007 UTC (16 years, 9 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.3: +69 -75 lines
Log Message:
- changed name
- updated the example config to the new system
- added more documentation
- enhanced documentation generators
- added a link to the pdf to the website
- added an RSS feed generator
- transitioned hooks to c++ callbacks
- did various merges with upstream along the way
- added const where appropriate
- removed the old block allocator
- fixed most memory leaks
- transitioned some dictionaries to std::map
- transitioned some lists to std::vector
- made some free functions members where appropriate
- renamed string to dynstr and added a static string ststr
- use NOW instead of time (NULL) if possible
- completely reworked database backends, crypto handlers and protocol handlers
  to use an object factory
- removed the old module system. ermyth does not do any dynamic loading anymore
- fixed most of the build system
- reworked how protocol commands work

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