]>
jfr.im git - solanum.git/blob - libratbox/src/devpoll.c
2 * ircd-ratbox: A slightly useful ircd.
3 * s_bsd_devpoll.c: /dev/poll compatible network routines.
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
8 * Copyright (C) 2002-2005 ircd-ratbox development team
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
25 * $Id: devpoll.c 25038 2008-01-23 16:03:08Z androsyn $
27 #include <libratbox_config.h>
28 #include <ratbox_lib.h>
29 #include <commio-int.h>
32 #if defined(HAVE_DEVPOLL) && (HAVE_DEVPOLL_H)
33 #include <sys/devpoll.h>
36 static void devpoll_update_events(int, short, PF
*);
40 static void devpoll_update_events(int, short, PF
*);
41 static void devpoll_write_update(int, int);
45 rb_setup_fd_devpoll(rb_fde_t
*F
)
52 * Write an update to the devpoll filter.
53 * See, we end up having to do a seperate (?) remove before we do an
54 * add of a new polltype, so we have to have this function seperate from
58 devpoll_write_update(int fd
, int events
)
60 struct pollfd pollfds
[1]; /* Just to be careful */
63 /* Build the pollfd entry */
64 pollfds
[0].revents
= 0;
66 pollfds
[0].events
= events
;
68 /* Write the thing to our poll fd */
69 retval
= write(dpfd
, &pollfds
[0], sizeof(struct pollfd
));
70 if(retval
!= sizeof(struct pollfd
))
71 rb_lib_log("devpoll_write_update: dpfd write failed %d: %s", errno
, strerror(errno
));
76 devpoll_update_events(int fd
, short filter
, PF
* handler
)
78 int update_required
= 0;
79 int cur_mask
= fdmask
[fd
];
86 cur_handler
= F
->read_handler
;
88 fdmask
[fd
] |= POLLRDNORM
;
90 fdmask
[fd
] &= ~POLLRDNORM
;
92 fdmask
[fd
] |= POLLWRNORM
;
95 cur_handler
= F
->write_handler
;
97 fdmask
[fd
] |= POLLWRNORM
;
99 fdmask
[fd
] &= ~POLLWRNORM
;
101 fdmask
[fd
] |= POLLRDNORM
;
108 if(cur_handler
== NULL
&& handler
!= NULL
)
110 else if(cur_handler
!= NULL
&& handler
== NULL
)
112 if(cur_mask
!= fdmask
[fd
])
117 * Ok, we can call devpoll_write_update() here now to re-build the
118 * fd struct. If we end up with nothing on this fd, it won't write
123 devpoll_write_update(fd
, POLLREMOVE
);
124 devpoll_write_update(fd
, fdmask
[fd
]);
127 devpoll_write_update(fd
, POLLREMOVE
);
135 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
136 /* Public functions */
142 * This is a needed exported function which will be called to initialise
143 * the network loop code.
146 rb_init_netio_devpoll(void)
148 dpfd
= open("/dev/poll", O_RDWR
);
153 maxfd
= getdtablesize() - 2; /* This makes more sense than HARD_FDLIMIT */
154 fdmask
= rb_malloc(sizeof(fdmask
) * maxfd
+ 1);
155 rb_open(dpfd
, RB_FD_UNKNOWN
, "/dev/poll file descriptor");
161 * This is a needed exported function which will be called to register
162 * and deregister interest in a pending IO state for a given FD.
165 rb_setselect_devpoll(rb_fde_t
*F
, unsigned int type
, PF
* handler
,
168 lrb_assert(IsFDOpen(F
));
170 if(type
& RB_SELECT_READ
)
172 devpoll_update_events(fd
, RB_SELECT_READ
, handler
);
173 F
->read_handler
= handler
;
174 F
->read_data
= client_data
;
176 if(type
& RB_SELECT_WRITE
)
178 devpoll_update_events(fd
, RB_SELECT_WRITE
, handler
);
179 F
->write_handler
= handler
;
180 F
->write_data
= client_data
;
185 * Check all connections for new connections and input data that is to be
186 * processed. Also check for connections with data queued and whether we can
193 * Called to do the new-style IO, courtesy of squid (like most of this
194 * new IO code). This routine handles the stuff we've hidden in
195 * rb_setselect and fd_table[] and calls callbacks for IO ready
200 rb_select_devpoll(long delay
)
203 struct pollfd pollfds
[maxfd
];
204 struct dvpoll dopoll
;
210 dopoll
.dp_timeout
= delay
;
211 dopoll
.dp_nfds
= maxfd
;
212 dopoll
.dp_fds
= &pollfds
[0];
213 num
= ioctl(dpfd
, DP_POLL
, &dopoll
);
216 if(rb_ignore_errno(errno
))
226 for (i
= 0; i
< num
; i
++)
228 int fd
= dopoll
.dp_fds
[i
].fd
;
230 rb_fde_t
*F
= rb_find_fd(fd
);
231 if((dopoll
.dp_fds
[i
].
232 revents
& (POLLRDNORM
| POLLIN
| POLLHUP
|
234 && (dopoll
.dp_fds
[i
].events
& (POLLRDNORM
| POLLIN
)))
236 if((hdl
= F
->read_handler
) != NULL
)
238 F
->read_handler
= NULL
;
239 hdl(F
, F
->read_data
);
241 * this call used to be with a NULL pointer, BUT
242 * in the devpoll case we only want to update the
243 * poll set *if* the handler changes state (active ->
244 * NULL or vice versa.)
246 devpoll_update_events(fd
,
247 RB_SELECT_READ
, F
->read_handler
);
252 continue; /* Read handler closed us..go on to do something more useful */
253 if((dopoll
.dp_fds
[i
].
254 revents
& (POLLWRNORM
| POLLOUT
| POLLHUP
|
256 && (dopoll
.dp_fds
[i
].events
& (POLLWRNORM
| POLLOUT
)))
258 if((hdl
= F
->write_handler
) != NULL
)
260 F
->write_handler
= NULL
;
261 hdl(F
, F
->write_data
);
262 /* See above similar code in the read case */
263 devpoll_update_events(fd
,
264 RB_SELECT_WRITE
, F
->write_handler
);
272 /* XXX Get here, we broke! */
276 #else /* /dev/poll not supported */
278 rb_init_netio_devpoll(void)
284 rb_setselect_devpoll(rb_fde_t
*F
, unsigned int type
, PF
* handler
, void *client_data
)
291 rb_select_devpoll(long delay
)
298 rb_setup_fd_devpoll(rb_fde_t
*F
)