Update of /cvsroot/aolserver/aolserver/nsd
In directory sc8-pr-cvs11.sourceforge.net:/tmp/cvs-serv19049
Modified Files:
driver.c queue.c
Log Message:
Better fix for BUG #1615787 in aolserver 4.5. Although the original fix
apparently helped for www.openacs.org, it appears to simply change the timing,
but did not fix the problem itself. The problem was that under limited
resource configurations (e.g. maxthreads 5, maxconnections 3) and heavy
traffic, incoming requests were queued but not processed in new connection
threads. The situation was especially bad, when the number of queued
requests was larger than maxconnections, since after processing n requests
the server was idling with a high number of queued requests. New requests
were put to the end of the queue while old (maybe already timed-out) requests
are being served. The server appeared to hang.
The current fix cares for queued requests even when maxconns is exceeded.
A maybe better approach is to limit the number of queued requests or
to restart automatically threads when a thread exists due to maxconns
exceeded.
Index: driver.c
===================================================================
RCS file: /cvsroot/aolserver/aolserver/nsd/driver.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -C2 -d -r1.56 -r1.57
*** driver.c 15 Dec 2006 17:26:57 -0000 1.56
--- driver.c 19 Oct 2007 09:46:38 -0000 1.57
***************
*** 949,958 ****
/*
- * Register an at-ready callback to trigger the poll.
- */
-
- Ns_RegisterAtReady(TriggerDriver, drvPtr);
-
- /*
* Loop forever until signalled to shutdown and all
* connections are complete and gracefully closed.
--- 949,952 ----
***************
*** 1314,1318 ****
Ns_DStringPrintf(drvPtr->queryPtr,
"time %ld:%ld "
! "spins %ld accepts %u queued %u reads %u "
"dropped %u overflow %d timeout %u",
now.sec, now.usec,
--- 1308,1312 ----
Ns_DStringPrintf(drvPtr->queryPtr,
"time %ld:%ld "
! "spins %d accepts %u queued %u reads %u "
"dropped %u overflow %d timeout %u",
now.sec, now.usec,
Index: queue.c
===================================================================
RCS file: /cvsroot/aolserver/aolserver/nsd/queue.c,v
retrieving revision 1.38
retrieving revision 1.39
diff -C2 -d -r1.38 -r1.39
*** queue.c 13 Apr 2006 19:06:24 -0000 1.38
--- queue.c 19 Oct 2007 09:46:38 -0000 1.39
***************
*** 185,189 ****
--- 185,197 ----
create = 1;
}
+ /*
+ Note that in situations, where the maximum number of
+ connection threads is reached (poolPtr->threads.idle == 0 and create == 0)
+ the request is queued without resources to process these.
+ One has to take care about that one restarts the queue, when
+ resources become available again.
+ */
++poolPtr->queue.wait.num;
+
Ns_MutexUnlock(&poolPtr->lock);
if (create) {
***************
*** 370,374 ****
Ns_MutexLock(&poolPtr->lock);
! while (poolPtr->threads.maxconns <= 0 || ncons-- > 0) {
/*
--- 378,394 ----
Ns_MutexLock(&poolPtr->lock);
! /*
! The last test (poolPtr->queue.wait.num > 0) might lead to situations
! where a single connection thread processes more than maxconns
! connection requests. This condition fixes situations, where the
! driver accepts more connection requests than resources available.
! When e.g. the number of queued requests is higher than connections per threads,
! this might lead to situations, where there server comes to a halt.
! Maybe it is a good idea to limit the number of queued requests or
! to start a new thread automatically, when the current one exists due
! to max conns. However, the test with the queue.wait.num consition
! is better than a hang.
! */
! while (poolPtr->threads.maxconns <= 0 || ncons-- > 0 || poolPtr->queue.wait.num > 1) {
/*
***************
*** 386,394 ****
status = NS_OK;
! while (!poolPtr->shutdown
! && status == NS_OK
! && poolPtr->queue.wait.firstPtr == NULL) {
! status = Ns_CondTimedWait(&poolPtr->cond, &poolPtr->lock, timePtr);
! }
if (poolPtr->queue.wait.firstPtr == NULL) {
msg = "timeout waiting for connection";
--- 406,420 ----
status = NS_OK;
!
! if (poolPtr->queue.wait.num == 0) {
! /*
! nothing is queued, we wait for a queue entry
! */
! while (!poolPtr->shutdown
! && status == NS_OK
! && poolPtr->queue.wait.firstPtr == NULL) {
! status = Ns_CondTimedWait(&poolPtr->cond, &poolPtr->lock, timePtr);
! }
! }
if (poolPtr->queue.wait.firstPtr == NULL) {
msg = "timeout waiting for connection";
|