ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/s_bsd_devpoll.c
Revision: 1155
Committed: Tue Aug 9 20:27:45 2011 UTC (14 years ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/src/s_bsd_devpoll.c
File size: 4475 byte(s)
Log Message:
- recreate "trunk"

File Contents

# User Rev Content
1 adx 30 /*
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 knight 31 * $Id$
24 adx 30 */
25    
26     #include "stdinc.h"
27 stu 908 #if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_DEVPOLL
28 adx 30 #include <sys/ioctl.h>
29     /* HPUX uses devpoll.h and not sys/devpoll.h */
30     #ifdef HAVE_DEVPOLL_H
31     # include <devpoll.h>
32     #else
33     # ifdef HAVE_SYS_DEVPOLL_H
34     # include <sys/devpoll.h>
35     # else
36     # error "No devpoll.h found! Try ./configuring and letting the script choose for you."
37     # endif
38     #endif
39     #include "fdlist.h"
40     #include "ircd.h"
41     #include "s_bsd.h"
42     #include "s_log.h"
43    
44     static fde_t dpfd;
45    
46     /*
47     * init_netio
48     *
49     * This is a needed exported function which will be called to initialise
50     * the network loop code.
51     */
52     void
53     init_netio(void)
54     {
55     int fd;
56    
57     if ((fd = open("/dev/poll", O_RDWR)) < 0)
58     {
59     ilog(L_CRIT, "init_netio: Couldn't open /dev/poll - %d: %s",
60     errno, strerror(errno));
61     exit(115); /* Whee! */
62     }
63    
64     fd_open(&dpfd, fd, 0, "/dev/poll file descriptor");
65     }
66    
67     /*
68     * Write an update to the devpoll filter.
69     * See, we end up having to do a seperate (?) remove before we do an
70     * add of a new polltype, so we have to have this function seperate from
71     * the others.
72     */
73     static void
74     devpoll_write_update(int fd, int events)
75     {
76     struct pollfd pfd;
77    
78     /* Build the pollfd entry */
79     pfd.revents = 0;
80     pfd.fd = fd;
81     pfd.events = events;
82    
83     /* Write the thing to our poll fd */
84     if (write(dpfd.fd, &pfd, sizeof(pfd)) != sizeof(pfd))
85     ilog(L_NOTICE, "devpoll_write_update: dpfd write failed %d: %s",
86     errno, strerror(errno));
87     }
88    
89     /*
90     * comm_setselect
91     *
92     * This is a needed exported function which will be called to register
93     * and deregister interest in a pending IO state for a given FD.
94     */
95     void
96     comm_setselect(fde_t *F, unsigned int type, PF *handler,
97     void *client_data, time_t timeout)
98     {
99     int new_events;
100    
101     if ((type & COMM_SELECT_READ))
102     {
103     F->read_handler = handler;
104     F->read_data = client_data;
105     }
106    
107     if ((type & COMM_SELECT_WRITE))
108     {
109     F->write_handler = handler;
110     F->write_data = client_data;
111     }
112    
113 adx 282 new_events = (F->read_handler ? POLLIN : 0) |
114     (F->write_handler ? POLLOUT : 0);
115 adx 30
116     if (timeout != 0)
117     F->timeout = CurrentTime + (timeout / 1000);
118    
119     if (new_events != F->evcache)
120     {
121     devpoll_write_update(F->fd, POLLREMOVE);
122     if ((F->evcache = new_events))
123     devpoll_write_update(F->fd, new_events);
124     }
125     }
126    
127     /*
128     * comm_select
129     *
130     * Called to do the new-style IO, courtesy of squid (like most of this
131     * new IO code). This routine handles the stuff we've hidden in
132     * comm_setselect and fd_table[] and calls callbacks for IO ready
133     * events.
134     */
135     void
136     comm_select(void)
137     {
138     int num, i;
139     struct pollfd pollfds[128];
140     struct dvpoll dopoll;
141     PF *hdl;
142     fde_t *F;
143    
144     dopoll.dp_timeout = SELECT_DELAY;
145     dopoll.dp_nfds = 128;
146     dopoll.dp_fds = &pollfds[0];
147     num = ioctl(dpfd.fd, DP_POLL, &dopoll);
148    
149     set_time();
150    
151     if (num < 0)
152     {
153     #ifdef HAVE_USLEEP
154     usleep(50000); /* avoid 99% CPU in comm_select */
155     #endif
156     return;
157     }
158    
159     for (i = 0; i < num; i++)
160     {
161     F = lookup_fd(dopoll.dp_fds[i].fd);
162     if (F == NULL || !F->flags.open)
163     continue;
164    
165 adx 282 if ((dopoll.dp_fds[i].revents & POLLIN))
166 adx 30 if ((hdl = F->read_handler) != NULL)
167     {
168     F->read_handler = NULL;
169     hdl(F, F->read_data);
170 adx 242 if (!F->flags.open)
171     continue;
172 adx 30 }
173    
174 adx 282 if ((dopoll.dp_fds[i].revents & POLLOUT))
175 adx 30 if ((hdl = F->write_handler) != NULL)
176     {
177     F->write_handler = NULL;
178     hdl(F, F->write_data);
179 adx 242 if (!F->flags.open)
180     continue;
181 adx 30 }
182    
183     comm_setselect(F, 0, NULL, NULL, 0);
184     }
185     }
186 stu 908 #endif

Properties

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