/[svn]/ircd-hybrid/libio/comm/devpoll.c
ViewVC logotype

Contents of /ircd-hybrid/libio/comm/devpoll.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 281 - (show annotations)
Thu Nov 24 10:29:09 2005 UTC (14 years, 9 months ago) by adx
File MIME type: text/x-chdr
File size: 4337 byte(s)
+ hopefully fixed /dev/poll

1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * s_bsd_devpoll.c: /dev/poll compatible network routines.
4 *
5 * Originally by Adrian Chadd <adrian@creative.net.au>
6 * Copyright (C) 2002 Hybrid Development Team
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * USA
22 *
23 * $Id$
24 */
25
26 #include "stdinc.h"
27 #include <sys/ioctl.h>
28 /* HPUX uses devpoll.h and not sys/devpoll.h */
29 #ifdef HAVE_DEVPOLL_H
30 # include <devpoll.h>
31 #else
32 # ifdef HAVE_SYS_DEVPOLL_H
33 # include <sys/devpoll.h>
34 # else
35 # error "No devpoll.h found! Try ./configuring and letting the script choose for you."
36 # endif
37 #endif
38
39 static fde_t dpfd;
40
41 /*
42 * init_netio
43 *
44 * This is a needed exported function which will be called to initialise
45 * the network loop code.
46 */
47 void
48 init_netio(void)
49 {
50 int fd;
51
52 if ((fd = open("/dev/poll", O_RDWR)) < 0)
53 {
54 ilog(L_CRIT, "init_netio: Couldn't open /dev/poll - %d: %s",
55 errno, strerror(errno));
56 exit(115); /* Whee! */
57 }
58
59 fd_open(&dpfd, fd, 0, "/dev/poll file descriptor");
60 }
61
62 /*
63 * Write an update to the devpoll filter.
64 * See, we end up having to do a seperate (?) remove before we do an
65 * add of a new polltype, so we have to have this function seperate from
66 * the others.
67 */
68 static void
69 devpoll_write_update(int fd, int events)
70 {
71 struct pollfd pfd;
72
73 /* Build the pollfd entry */
74 pfd.revents = 0;
75 pfd.fd = fd;
76 pfd.events = events;
77
78 /* Write the thing to our poll fd */
79 if (write(dpfd.fd, &pfd, sizeof(pfd)) != sizeof(pfd))
80 ilog(L_NOTICE, "devpoll_write_update: dpfd write failed %d: %s",
81 errno, strerror(errno));
82 }
83
84 /*
85 * comm_setselect
86 *
87 * This is a needed exported function which will be called to register
88 * and deregister interest in a pending IO state for a given FD.
89 */
90 void
91 comm_setselect(fde_t *F, unsigned int type, PF *handler,
92 void *client_data, time_t timeout)
93 {
94 int new_events;
95
96 if ((type & COMM_SELECT_READ))
97 {
98 F->read_handler = handler;
99 F->read_data = client_data;
100 }
101
102 if ((type & COMM_SELECT_WRITE))
103 {
104 F->write_handler = handler;
105 F->write_data = client_data;
106 }
107
108 new_events = (F->read_handler ? POLLIN : 0) |
109 (F->write_handler ? POLLOUT : 0);
110
111 if (timeout != 0)
112 F->timeout = CurrentTime + (timeout / 1000);
113
114 if (new_events != F->evcache)
115 {
116 devpoll_write_update(F->fd, POLLREMOVE);
117 if ((F->evcache = new_events))
118 devpoll_write_update(F->fd, new_events);
119 }
120 }
121
122 /*
123 * comm_select
124 *
125 * Called to do the new-style IO, courtesy of squid (like most of this
126 * new IO code). This routine handles the stuff we've hidden in
127 * comm_setselect and fd_table[] and calls callbacks for IO ready
128 * events.
129 */
130 void
131 comm_select(void)
132 {
133 int num, i;
134 struct pollfd pollfds[128];
135 struct dvpoll dopoll;
136 PF *hdl;
137 fde_t *F;
138
139 dopoll.dp_timeout = SELECT_DELAY;
140 dopoll.dp_nfds = 128;
141 dopoll.dp_fds = &pollfds[0];
142 num = ioctl(dpfd.fd, DP_POLL, &dopoll);
143
144 set_time();
145
146 if (num < 0)
147 {
148 #ifdef HAVE_USLEEP
149 usleep(50000); /* avoid 99% CPU in comm_select */
150 #endif
151 return;
152 }
153
154 for (i = 0; i < num; i++)
155 {
156 F = lookup_fd(dopoll.dp_fds[i].fd);
157 if (F == NULL || !F->flags.open)
158 continue;
159
160 if ((dopoll.dp_fds[i].revents & POLLIN))
161 if ((hdl = F->read_handler) != NULL)
162 {
163 F->read_handler = NULL;
164 hdl(F, F->read_data);
165 if (!F->flags.open)
166 continue;
167 }
168
169 if ((dopoll.dp_fds[i].revents & POLLOUT))
170 if ((hdl = F->write_handler) != NULL)
171 {
172 F->write_handler = NULL;
173 hdl(F, F->write_data);
174 if (!F->flags.open)
175 continue;
176 }
177
178 comm_setselect(F, 0, NULL, NULL, 0);
179 }
180 }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28