Compare commits

...

6 Commits

Author SHA1 Message Date
Adrian Chadd
6510cdb4db Merge branch 'master' of github.com:/httperf/httperf into ahc_fix_select 2018-07-11 15:57:27 -07:00
Adrian Chadd
84f4376c6c Don't allow the fd count to exceed FD_SETSIZE. 2016-03-31 16:17:42 -07:00
Adrian Chadd
18db423b1d oops - just use 'sd' for the loop. 2016-03-31 11:08:59 -07:00
Adrian Chadd
1e5e8d1bc2 remove these; not used. 2016-03-31 10:54:36 -07:00
Adrian Chadd
c62cdb51b9 oops - remove double decl. 2016-03-31 10:43:22 -07:00
Adrian Chadd
f62f1c0bda Totally untested fix for select() logic going out of bounds. 2016-03-31 10:41:04 -07:00

View File

@ -49,6 +49,10 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/time.h> #include <sys/time.h>
#ifdef HAVE_SYS_SELECT_H #ifdef HAVE_SYS_SELECT_H
// You may need to override this!
// #define FD_SETSIZE 2048
#include <sys/select.h> #include <sys/select.h>
#endif #endif
#ifdef HAVE_KEVENT #ifdef HAVE_KEVENT
@ -1076,6 +1080,15 @@ core_connect(Conn * s)
goto failure; goto failure;
} }
if (sd > FD_SETSIZE) {
fprintf(stderr,
"%s.core_connect.socket: sd > FD_SETSIZE (%d)\n",
prog_name,
FD_SETSIZE);
close(sd);
goto failure;
}
if (fcntl(sd, F_SETFL, O_NONBLOCK) < 0) { if (fcntl(sd, F_SETFL, O_NONBLOCK) < 0) {
fprintf(stderr, "%s.core_connect.fcntl: %s\n", fprintf(stderr, "%s.core_connect.fcntl: %s\n",
prog_name, strerror(errno)); prog_name, strerror(errno));
@ -1445,59 +1458,18 @@ core_loop(void)
} }
} }
#else #else
void
core_loop(void) static void
check_conn(int sd, int is_readable, int is_writable)
{ {
int is_readable, is_writable, n, sd, bit, min_i, max_i, i = 0;
fd_set readable, writable;
fd_mask mask;
Any_Type arg;
Conn *conn; Conn *conn;
Any_Type arg;
while (running) { /* Don't bother doing anything if we're not ready */
struct timeval tv = select_timeout; if ((is_readable || is_writable) == 0) {
return;
timer_tick();
readable = rdfds;
writable = wrfds;
min_i = min_sd / NFDBITS;
max_i = max_sd / NFDBITS;
SYSCALL(SELECT, n = select(max_sd + 1, &readable, &writable, 0, &tv));
++iteration;
if (n <= 0) {
if (n < 0) {
fprintf(stderr, "%s.core_loop: select failed: %s\n", prog_name, strerror(errno));
exit(1);
}
continue;
} }
while (n > 0) {
/*
* find the index of the fdmask that has something
* going on:
*/
do {
++i;
if (i > max_i)
i = min_i;
assert(i <= max_i);
mask = readable.fds_bits[i] | writable.fds_bits[i];
} while (!mask);
bit = 0;
sd = i * NFDBITS + bit;
do {
if (mask & 1) {
--n;
is_readable = (FD_ISSET(sd, &readable) && FD_ISSET(sd, &rdfds));
is_writable = (FD_ISSET(sd, &writable) && FD_ISSET(sd, &wrfds));
if (is_readable || is_writable) {
/* /*
* only handle sockets that * only handle sockets that
* haven't timed out yet * haven't timed out yet
@ -1509,6 +1481,7 @@ core_loop(void)
timer_cancel(conn->watchdog); timer_cancel(conn->watchdog);
conn->watchdog = 0; conn->watchdog = 0;
} }
if (conn->state == S_CONNECTING) { if (conn->state == S_CONNECTING) {
#ifdef HAVE_SSL #ifdef HAVE_SSL
if (param.use_ssl) if (param.use_ssl)
@ -1527,17 +1500,49 @@ core_loop(void)
if (is_readable && conn->recvq) if (is_readable && conn->recvq)
do_recv(conn); do_recv(conn);
} }
conn_dec_ref(conn); conn_dec_ref(conn);
}
void
core_loop(void)
{
int is_readable, is_writable, n, sd;
fd_set readable, writable;
fd_mask mask;
while (running) {
struct timeval tv = select_timeout;
if (n > 0)
timer_tick(); timer_tick();
readable = rdfds;
writable = wrfds;
SYSCALL(SELECT, n = select(max_sd + 1, &readable, &writable, 0, &tv));
++iteration;
if (n <= 0) {
if (n < 0) {
fprintf(stderr, "%s.core_loop: select failed: %s\n", prog_name, strerror(errno));
exit(1);
} }
continue;
} }
mask = ((u_long) mask) >> 1;
++sd; /* XXX totally suboptimal loop, but less potentially problematic */
} while (mask);
for (sd = 0; sd <= max_sd; sd++) {
is_readable = (FD_ISSET(sd, &readable) && FD_ISSET(sd, &rdfds));
is_writable = (FD_ISSET(sd, &writable) && FD_ISSET(sd, &wrfds));
if (is_readable || is_writable)
check_conn(sd, is_readable, is_writable);
/* XXX TODO: totally can bail out if we've seen 'n' FDs */
} }
/* Do timer tick at the end of the connection check */
timer_tick();
} }
} }
#endif #endif