mirror of
https://github.com/libssh2/libssh2.git
synced 2026-10-24 03:48:58 +03:00
session: drop alloca() use from libssh2_poll()
Use fixed stack buffer when requested 256 sockets or less. Allocate from
heap otherwise.
There is no other `alloca()` user, so drop detecting it via autotools
(CMake never got support for this). Also re-enable a warning option that
was incompatible with autotools's `AC_FUNC_ALLOCA` code.
This patch may reduce performance when polling 257+ sockets (due to
calloc/free), and comes with higher stack use ('256 * sizeof(struct
pollfd)') than before this patch, when using `poll()` (typically on Unix
platforms except Darwin and Interix).
Note: `libssh2_poll()` is deprecated since v1.2.0 (2009-08-10).
Follow-up to 209d06d6c9
Closes #2041
This commit is contained in:
@@ -631,11 +631,7 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS],
|
||||
|
||||
dnl Only gcc 15 or later
|
||||
if test "$compiler_num" -ge "1500"; then
|
||||
dnl AC_FUNC_ALLOCA is incompatible with this option. It triggers
|
||||
dnl detecting macro STACK_DIRECTION (which we do not use here).
|
||||
dnl autoconf (as of v2.73) puts this macro into libssh2_config.h
|
||||
dnl indented by tabs.
|
||||
# CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [leading-whitespace=spaces])
|
||||
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [leading-whitespace=spaces])
|
||||
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [trailing-whitespace=any])
|
||||
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unterminated-string-initialization])
|
||||
fi
|
||||
|
||||
@@ -398,8 +398,6 @@ if test "$ac_cv_func_select" != "yes"; then
|
||||
])
|
||||
fi
|
||||
|
||||
AC_FUNC_ALLOCA
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
|
||||
|
||||
@@ -52,12 +52,6 @@
|
||||
/* Define to 1 if using `alloca.c'. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||
#define HAVE_ALLOCA 1
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
#define HAVE_ALLOCA_H 1
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
|
||||
|
||||
@@ -47,9 +47,6 @@
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
@@ -1519,16 +1516,18 @@ int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout)
|
||||
unsigned int i, active_fds;
|
||||
#ifdef HAVE_POLL
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
#ifdef HAVE_ALLOCA
|
||||
struct pollfd *sockets = alloca(sizeof(struct pollfd) * nfds);
|
||||
#else
|
||||
struct pollfd sockets[256];
|
||||
struct pollfd sockets_stack[256];
|
||||
struct pollfd *sockets_heap = NULL;
|
||||
struct pollfd *sockets;
|
||||
|
||||
if(nfds > 256) {
|
||||
sockets = sockets_heap = calloc(nfds, sizeof(struct pollfd));
|
||||
if(!sockets)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
sockets = sockets_stack;
|
||||
|
||||
if(nfds > 256)
|
||||
/* systems without alloca use a fixed-size array, this can be fixed if
|
||||
we really want to, at least if the compiler is a C99 capable one */
|
||||
return -1;
|
||||
#endif /* HAVE_ALLOCA */
|
||||
/* Setup sockets for polling */
|
||||
for(i = 0; i < nfds; i++) {
|
||||
fds[i].revents = 0;
|
||||
@@ -1556,6 +1555,8 @@ int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout)
|
||||
break;
|
||||
|
||||
default:
|
||||
if(sockets_heap)
|
||||
free(sockets_heap);
|
||||
if(session)
|
||||
ssh2_err(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
|
||||
"Invalid descriptor passed to libssh2_poll()");
|
||||
@@ -1646,7 +1647,6 @@ int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout)
|
||||
#if defined(HAVE_POLL) || defined(HAVE_SELECT)
|
||||
int sysret;
|
||||
#endif
|
||||
|
||||
active_fds = 0;
|
||||
|
||||
for(i = 0; i < nfds; i++) {
|
||||
@@ -1717,8 +1717,8 @@ int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout)
|
||||
are ready */
|
||||
timeout_remaining = 0;
|
||||
}
|
||||
#ifdef HAVE_POLL
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
{
|
||||
struct timeval tv_begin, tv_end;
|
||||
|
||||
@@ -1768,14 +1768,15 @@ int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(HAVE_SELECT)
|
||||
|
||||
tv.tv_sec = timeout_remaining / 1000;
|
||||
#ifdef libssh2_usec_t
|
||||
tv.tv_usec = (libssh2_usec_t)((timeout_remaining % 1000) * 1000);
|
||||
#else
|
||||
tv.tv_usec = (timeout_remaining % 1000) * 1000;
|
||||
#endif
|
||||
|
||||
{
|
||||
struct timeval tv_begin, tv_end;
|
||||
|
||||
@@ -1833,6 +1834,11 @@ int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout)
|
||||
* timeout_remaining) is equal to 0 */
|
||||
} while(timeout_remaining > 0 && !active_fds);
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
if(sockets_heap)
|
||||
free(sockets_heap);
|
||||
#endif
|
||||
|
||||
return active_fds;
|
||||
}
|
||||
#endif /* LIBSSH2_NO_DEPRECATED */
|
||||
|
||||
Reference in New Issue
Block a user