This patch corrects some problems in the ability of AB to handle
concurrent processing by:
- enabling nonblocking connect()s.
- preventing APR from performing blocking reads, allowing AB to
multiplex over its own set of descriptors.
Pre-patch: worker MPM with 2 children, 10 threads each: 10-20 req/sec
Post-patch: worker MPM with 2 children, 10 threads each: 750 req/sec
Post-patch: worker MPM with 2 children, 50 threads each: 735 req/sec
According to server-status I am now able to consistently occupy *all*
worker threads in the 10thr/child case, and almost all in the 50thr/child
case (my test hardware probably can't keep up). Actually, most of the
time they are all in the "closing connection" state.
** If you saw poor concurrent performance with the worker MPM while
testing with AB, please retest and submit your results.
-aaron
Index: support/ab.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/support/ab.c,v
retrieving revision 1.95
diff -u -r1.95 ab.c
--- support/ab.c 14 Apr 2002 09:21:43 -0000 1.95
+++ support/ab.c 23 Apr 2002 23:36:44 -0000
@@ -853,6 +853,10 @@
SOCK_STREAM, c->ctx)) != APR_SUCCESS) {
apr_err("socket", rv);
}
+ if ((rv = apr_setsocketopt(c->aprsock, APR_SO_NONBLOCK, 1))
+ != APR_SUCCESS) {
+ apr_err("socket nonblock", rv);
+ }
c->start = apr_time_now();
if ((rv = apr_connect(c->aprsock, destsa)) != APR_SUCCESS) {
if (APR_STATUS_IS_EINPROGRESS(rv)) {
@@ -941,16 +945,14 @@
char respcode[4]; /* 3 digits and null */
r = sizeof(buffer);
- apr_setsocketopt(c->aprsock, APR_SO_TIMEOUT, aprtimeout);
status = apr_recv(c->aprsock, buffer, &r);
- if (r == 0 || (status != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(status))) {
+ if (APR_STATUS_IS_EAGAIN(status))
+ return;
+ if (r == 0 || status != APR_SUCCESS) {
good++;
close_connection(c);
return;
}
-
- if (APR_STATUS_IS_EAGAIN(status))
- return;
totalread += r;
if (c->read == 0) {