ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/poll.C
Revision: 1.2
Committed: Sat Jul 21 01:29:12 2007 UTC (16 years, 10 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
- moved to new documentation system
- fixed small build error

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     * 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     */