Consider yourself beaten -- this has been bugging me for a while. :)
On 2007/03/26, at 5:31 PM, Adrian Chadd wrote:
On Sun, Mar 18, 2007, Martin Solciansky wrote:
hello,
we have been using squid-2.6.6 (with some security patches from
higher
versions and the kevent patch from .11) for some time now but few
weeks ago
we started getting:
2007/03/17 08:25:12| comm_select: kevent failure: (9) Bad file
descriptor
2007/03/17 08:25:12| Select loop Error. Retry 1
I'm pretty sure I know why it is: Squid isn't removing the entries
from
the kqueue array when a filedescriptor is closed and if the
filedescriptor
isn't reused fast enough it'll end up throwing the above error.
This error used to actually cause runtime leaks. I'm not sure if
Henrik's
recent work to mimic what libevent does has fixed it or not, but I
do know
the issue is still there.
The real fix is to delay close() filedescriptors until its time to
call
kevent: on close(), modify the event in the array to be EV_DELETE,
then
close() all the filedescriptors. This is however very horrible and
ugly.
The fix I came up with for one of my private projects was to record
the
kevent array offset of the registered read/write events, if any, and
rewrite them to be "null". Now, kqueue doesn't have any concept of an
event slot thats to be ignored (unfortunately!) so you fake it with:
* ident = 0 (fd = 0, for EV_READ and EV_WRITE filters)
* filter = EV_READ or EV_WRITE, whatever's appropriate for what you're
replacing
* flags = EV_ADD | EV_DISABLE
Kqueue doesn't mind if there's multiple filters added; it just
overrides
the currently registered one. The above is about as close to a NULL
filter
as you're going to get.
I've done this in my test code to support loads much higher than Squid
(~6k proxied req/sec (6k client sockets, 6k server sockets) with
~3000 to
~4000 concurrent connections. Its sane.)
If someone wants to beat me to fixing then please, by all means. :)
Adrian
--
Mark Nottingham mnot@xxxxxxxxxxxxx