Package: libfcgi0ldbl Version: 2.4.0-8.1 Severity: normal Tags: patch
This bug was originally reported in Ubuntu: https://bugs.launchpad.net/ubuntu/+source/libfcgi/+bug/933417 --- BEGIN UBUNTU BUG DESCRIPTION --- libfcgi uses select syscall, when some applications tryes to use more than 1024 connections from web-server it crashes. There is a solutions for this problem: use poll in os_unix.c instead of select. Patch with this change is attached to this bug. This patch was written in Yandex and successfully used for a several months. LIBFCGI_OS_CLOSE_POLL_TIMEOUT and LIBFCGI_IS_AF_UNIX_KEEPER_POLL_TIMEOUT environment variables are added to control poll timeouts in Os_Close and is_af_unix_keeper functions accordingly. $ lsb_release -rd Description: Ubuntu 10.04.2 LTS Release: 10.04 --- END UBUNTU BUG DESCRIPTION --- I will attach the patch as well. I am not sure how to forward it to upstream, as their developer information seems fairly sparse and hard to find. -- System Information: Debian Release: wheezy/sid APT prefers precise-updates APT policy: (500, 'precise-updates'), (500, 'precise-security'), (500, 'precise'), (100, 'precise-backports') Architecture: amd64 (x86_64) Kernel: Linux 3.2.0-26-generic (SMP w/4 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages libfcgi0ldbl depends on: ii libc6 2.15-0ubuntu10 ii libgcc1 1:4.6.3-1ubuntu5 ii libstdc++6 4.6.3-1ubuntu5 libfcgi0ldbl recommends no packages. libfcgi0ldbl suggests no packages. -- no debconf information
diff --git a/libfcgi/os_unix.c b/libfcgi/os_unix.c index 73e6a7f..af35aee 100755 --- a/libfcgi/os_unix.c +++ b/libfcgi/os_unix.c @@ -42,6 +42,7 @@ static const char rcsid[] = "$Id: os_unix.c,v 1.37 2002/03/05 19:14:49 robs Exp #include <sys/time.h> #include <sys/un.h> #include <signal.h> +#include <poll.h> #ifdef HAVE_NETDB_H #include <netdb.h> @@ -103,6 +104,9 @@ static int volatile maxFd = -1; static int shutdownPending = FALSE; static int shutdownNow = FALSE; +static int libfcgiOsClosePollTimeout = 2000; +static int libfcgiIsAfUnixKeeperPollTimeout = 2000; + void OS_ShutdownPending() { shutdownPending = TRUE; @@ -168,6 +172,16 @@ int OS_LibInit(int stdioFds[3]) if(libInitialized) return 0; + char *libfcgiOsClosePollTimeoutStr = getenv( "LIBFCGI_OS_CLOSE_POLL_TIMEOUT" ); + if(libfcgiOsClosePollTimeoutStr) { + libfcgiOsClosePollTimeout = atoi(libfcgiOsClosePollTimeoutStr); + } + + char *libfcgiIsAfUnixKeeperPollTimeoutStr = getenv( "LIBFCGI_IS_AF_UNIX_KEEPER_POLL_TIMEOUT" ); + if(libfcgiIsAfUnixKeeperPollTimeoutStr) { + libfcgiIsAfUnixKeeperPollTimeout = atoi(libfcgiIsAfUnixKeeperPollTimeoutStr); + } + asyncIoTable = (AioInfo *)malloc(asyncIoTableSize * sizeof(AioInfo)); if(asyncIoTable == NULL) { errno = ENOMEM; @@ -755,19 +769,16 @@ int OS_Close(int fd) if (shutdown(fd, 1) == 0) { - struct timeval tv; - fd_set rfds; + struct pollfd pfd; int rv; char trash[1024]; - FD_ZERO(&rfds); + pfd.fd = fd; + pfd.events = POLLIN; do { - FD_SET(fd, &rfds); - tv.tv_sec = 2; - tv.tv_usec = 0; - rv = select(fd + 1, &rfds, NULL, NULL, &tv); + rv = poll(&pfd, 1, libfcgiOsClosePollTimeout); } while (rv > 0 && read(fd, trash, sizeof(trash)) > 0); } @@ -1116,13 +1127,11 @@ static int is_reasonable_accept_errno (const int error) */ static int is_af_unix_keeper(const int fd) { - struct timeval tval = { READABLE_UNIX_FD_DROP_DEAD_TIMEVAL }; - fd_set read_fds; - - FD_ZERO(&read_fds); - FD_SET(fd, &read_fds); + struct pollfd pfd; + pfd.fd = fd; + pfd.events = POLLIN; - return select(fd + 1, &read_fds, NULL, NULL, &tval) >= 0 && FD_ISSET(fd, &read_fds); + return poll(&pfd, 1, libfcgiIsAfUnixKeeperPollTimeout) >= 0 && (pfd.revents & POLLIN); } /*