ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/poll.C
Revision: 1.1
Committed: Thu Jul 19 08:24:59 2007 UTC (16 years, 10 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Log Message:
initial import. the most important changes since Atheme are:
- fixed many memory leaks
- fixed many bugs
- converted to C++ and use more STL containers
- added a (not very enhanced yet) perl module
- greatly improved XML-RPC speed
- added a JSON-RPC module with code from json-cpp
- added a valgrind memcheck module to operserv
- added a more object oriented base64 implementation
- added a specialised unit test framework
- improved stability
- use gettimeofday() if available
- reworked adding/removing commands
- MemoServ IGNORE DEL can now remove indices

File Contents

# Content
1 /*
2 * poll.C: poll(2) socket engine.
3 * Rights to this code are documented in doc/LICENSE.
4 *
5 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
6 */
7
8 static char const rcsid[] = "$Id";
9
10 #include <sys/poll.h>
11
12 #include "atheme.h"
13 #include "internal.h"
14 #include "datastream.h"
15
16 extern list_t connection_list; /* this lives in connection.c */
17
18 /*
19 * linux does not provide POLLWRNORM by default, and we're not _XOPEN_SOURCE.
20 * so.... we have to do this crap below.
21 */
22 #ifndef POLLRDNORM
23 #define POLLRDNORM POLLIN
24 #endif
25 #ifndef POLLWRNORM
26 #define POLLWRNORM POLLOUT
27 #endif
28
29 struct pollfd pollfds[FD_SETSIZE]; /* XXX We need a define indicating MAXCONN. */
30
31 /*
32 * init_socket_queues()
33 *
34 * inputs:
35 * none
36 *
37 * outputs:
38 * none
39 *
40 * side effects:
41 * when using select, we don't need to do anything here.
42 */
43 void
44 init_socket_queues (void)
45 {
46 memset (&pollfds, 0, sizeof (struct pollfd) * FD_SETSIZE);
47 }
48
49 /*
50 * update_poll_fds()
51 *
52 * inputs:
53 * none
54 *
55 * outputs:
56 * none
57 *
58 * side effects:
59 * registered sockets are prepared for the poll() loop.
60 */
61 static void
62 update_poll_fds (void)
63 {
64 node_t *n;
65 connection_t *cptr;
66 int slot = 0;
67
68 LIST_FOREACH (n, connection_list.head)
69 {
70 cptr = static_cast<connection_t *> (n->data);
71
72 cptr->pollslot = slot;
73
74 if (CF_IS_CONNECTING (cptr) || sendq_nonempty (cptr))
75 {
76 pollfds[slot].fd = cptr->fd;
77 pollfds[slot].events |= POLLWRNORM;
78 pollfds[slot].revents = 0;
79 }
80 else
81 {
82 pollfds[slot].fd = cptr->fd;
83 pollfds[slot].events |= POLLRDNORM;
84 pollfds[slot].revents = 0;
85 }
86 slot++;
87 }
88 }
89
90 /*
91 * connection_select()
92 *
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 connection_select (time_t delay)
104 {
105 int sr;
106 node_t *n, *tn;
107 connection_t *cptr;
108 int slot;
109
110 update_poll_fds ();
111
112 if ((sr = poll (pollfds, connection_list.count, delay / 100)) > 0)
113 {
114 /* Iterate twice, so we don't touch freed memory if
115 * a connection is closed.
116 * -- jilles */
117 LIST_FOREACH_SAFE (n, tn, connection_list.head)
118 {
119 cptr = static_cast<connection_t *> (n->data);
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 LIST_FOREACH_SAFE (n, tn, connection_list.head)
133 {
134 cptr = static_cast<connection_t *> (n->data);
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 hook_call_event ("connected", cptr);
144 else
145 cptr->write_handler (cptr);
146 }
147 }
148
149 LIST_FOREACH_SAFE (n, tn, connection_list.head)
150 {
151 cptr = static_cast<connection_t *> (n->data);
152 if (cptr->flags & CF_DEAD)
153 connection_close (cptr);
154 }
155 }
156 }
157
158 /* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs
159 * vim:ts=8
160 * vim:sw=8
161 * vim:noexpandtab
162 */