You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
4.9 KiB
139 lines
4.9 KiB
diff --git a/support/ab.c b/support/ab.c |
|
index f54c402..93c9066 100644 |
|
--- a/support/ab.c |
|
+++ b/support/ab.c |
|
@@ -344,6 +344,7 @@ apr_time_t start, lasttime, stoptime; |
|
char _request[2048]; |
|
char *request = _request; |
|
apr_size_t reqlen; |
|
+int requests_initialized = 0; |
|
|
|
/* one global throw-away buffer to read stuff into */ |
|
char buffer[8192]; |
|
@@ -1253,12 +1254,18 @@ static void start_connect(struct connection * c) |
|
else { |
|
set_conn_state(c, STATE_UNCONNECTED); |
|
apr_socket_close(c->aprsock); |
|
- err_conn++; |
|
- if (bad++ > 10) { |
|
+ if (good == 0 && destsa->next) { |
|
+ destsa = destsa->next; |
|
+ err_conn = 0; |
|
+ } |
|
+ else if (bad++ > 10) { |
|
fprintf(stderr, |
|
"\nTest aborted after 10 failures\n\n"); |
|
apr_err("apr_socket_connect()", rv); |
|
} |
|
+ else { |
|
+ err_conn++; |
|
+ } |
|
|
|
start_connect(c); |
|
return; |
|
@@ -1339,6 +1346,7 @@ static void read_connection(struct connection * c) |
|
apr_status_t status; |
|
char *part; |
|
char respcode[4]; /* 3 digits and null */ |
|
+ int i; |
|
|
|
r = sizeof(buffer); |
|
#ifdef USE_SSL |
|
@@ -1362,6 +1370,13 @@ static void read_connection(struct connection * c) |
|
good++; |
|
close_connection(c); |
|
} |
|
+ else if (scode == SSL_ERROR_SYSCALL |
|
+ && c->read == 0 |
|
+ && destsa->next |
|
+ && c->state == STATE_CONNECTING |
|
+ && good == 0) { |
|
+ return; |
|
+ } |
|
else if (scode != SSL_ERROR_WANT_WRITE |
|
&& scode != SSL_ERROR_WANT_READ) { |
|
/* some fatal error: */ |
|
@@ -1387,8 +1402,8 @@ static void read_connection(struct connection * c) |
|
} |
|
/* catch legitimate fatal apr_socket_recv errors */ |
|
else if (status != APR_SUCCESS) { |
|
- err_recv++; |
|
if (recverrok) { |
|
+ err_recv++; |
|
bad++; |
|
close_connection(c); |
|
if (verbosity >= 1) { |
|
@@ -1396,7 +1411,12 @@ static void read_connection(struct connection * c) |
|
fprintf(stderr,"%s: %s (%d)\n", "apr_socket_recv", apr_strerror(status, buf, sizeof buf), status); |
|
} |
|
return; |
|
- } else { |
|
+ } else if (destsa->next && c->state == STATE_CONNECTING |
|
+ && c->read == 0 && good == 0) { |
|
+ return; |
|
+ } |
|
+ else { |
|
+ err_recv++; |
|
apr_err("apr_socket_recv", status); |
|
} |
|
} |
|
@@ -1523,6 +1543,16 @@ static void read_connection(struct connection * c) |
|
} |
|
c->bread += c->cbx - (s + l - c->cbuff) + r - tocopy; |
|
totalbread += c->bread; |
|
+ |
|
+ /* We have received the header, so we know this destination socket |
|
+ * address is working, so initialize all remaining requests. */ |
|
+ if (!requests_initialized) { |
|
+ for (i = 1; i < concurrency; i++) { |
|
+ con[i].socknum = i; |
|
+ start_connect(&con[i]); |
|
+ } |
|
+ requests_initialized = 1; |
|
+ } |
|
} |
|
} |
|
else { |
|
@@ -1734,11 +1764,10 @@ static void test(void) |
|
apr_signal(SIGINT, output_results); |
|
#endif |
|
|
|
- /* initialise lots of requests */ |
|
- for (i = 0; i < concurrency; i++) { |
|
- con[i].socknum = i; |
|
- start_connect(&con[i]); |
|
- } |
|
+ /* initialise first connection to determine destination socket address |
|
+ * which should be used for next connections. */ |
|
+ con[0].socknum = 0; |
|
+ start_connect(&con[0]); |
|
|
|
do { |
|
apr_int32_t n; |
|
@@ -1786,14 +1815,20 @@ static void test(void) |
|
if ((rtnev & APR_POLLIN) || (rtnev & APR_POLLPRI) || (rtnev & APR_POLLHUP)) |
|
read_connection(c); |
|
if ((rtnev & APR_POLLERR) || (rtnev & APR_POLLNVAL)) { |
|
- bad++; |
|
- err_except++; |
|
- /* avoid apr_poll/EINPROGRESS loop on HP-UX, let recv discover ECONNREFUSED */ |
|
- if (c->state == STATE_CONNECTING) { |
|
- read_connection(c); |
|
+ if (destsa->next && c->state == STATE_CONNECTING && good == 0) { |
|
+ destsa = destsa->next; |
|
+ start_connect(c); |
|
} |
|
else { |
|
- start_connect(c); |
|
+ bad++; |
|
+ err_except++; |
|
+ /* avoid apr_poll/EINPROGRESS loop on HP-UX, let recv discover ECONNREFUSED */ |
|
+ if (c->state == STATE_CONNECTING) { |
|
+ read_connection(c); |
|
+ } |
|
+ else { |
|
+ start_connect(c); |
|
+ } |
|
} |
|
continue; |
|
}
|
|
|