ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/src/poll.C
Revision: 1.4
Committed: Tue Aug 28 17:08:12 2007 UTC (16 years, 10 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

# Content
1 /*
2 * poll.C: poll(2) socket engine.
3 * Rights to this code are documented in doc/pod/license.pod.
4 *
5 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
6 */
7
8 static char const rcsid[] = "$Id: poll.C,v 1.3 2007-07-21 13:23:22 pippijn Exp $";
9
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 pollfd pollfds[FD_SETSIZE]; /* XXX We need a define indicating MAXCONN. */
28
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 memset (&pollfds, 0, sizeof (pollfd) * FD_SETSIZE);
45 }
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 connection_vector::iterator it = connlist.begin ();
63 connection_vector::iterator et = connlist.end ();
64 int slot = 0;
65
66 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 }
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 connection_vector::iterator it = connlist.begin ();
106 connection_vector::iterator et = connlist.end ();
107 int slot;
108
109 update_poll_fds ();
110
111 if ((sr = poll (pollfds, connlist.size (), delay / 100)) > 0)
112 {
113 /* Iterate twice, so we don't touch freed memory if
114 * a connection is closed.
115 * -- jilles */
116 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 }
156 }