Description |
RSN-421
There is a nasty little deadlock in com.caucho.server.log.AccessLog.log(HttpServletRequest,HttpServletResponse) starting at AccessLog, line 304. The scenario that triggered it is I've exhausted the ThreadPool servicing TCP request. All those request servicing threads will eventually call AccessLog.flush. So the first thread to get to AccessLog.flush acquires the monitor on the _bufferLock object, it then calls AccessLogWriter.write(AccessLogBuffer). This is were the deadlock begins in ernest. In a previous run <code>if (_writeQueue.size() < _maxQueueLength)</code> and <code>if (! _hasThread)</code> in AccessLogWriter.write is true therefore, <code>_hasThread = true; ThreadPool.schedule(this);</code> got executed. During the deadlock run <code>if (_writeQueue.size() < _maxQueueLength)</code> is false so the thread executes <code>_writeQueue.wait();</code>. Since the Thread pool is exhausted there are no threads ever available to every purge _writeQueue which means the first thread is _waiting_ forever which means it never releases the monitor it acquired on _bufferLock which means all the other threads are stalled forever waiting to acquire _bufferLock's monitor which will never get released because the first thread is _waiting_ forever.
I've attached the Thread dump that aided me in deriving the explanation I've just presented. |