Core handlers are not threadsafe
|Reported by:||tdterry||Owned by:||tdterry|
|Severity:||Keywords:||wsgi, basehandler, mod_python, threadsafe, threading|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
I have found an incomplete-initialization bug the
WSGIHandler when running under Apache mpm_worker with mod_wsgi. Code review shows this is a potential problem with all of the handlers.
On the first request the
WSGIHandler.__call__(...), we set up the middleware. There is a lock wrapping the load of the middleware, but the logic still allows incomplete initialization on other threads. Below is the block of code in question from django/core/handlers/wsgi.py (line 226):
if self._request_middleware is None: self.initLock.acquire() # Check that middleware is still uninitialised. if self._request_middleware is None: self.load_middleware() self.initLock.release()
- Initial start or restart of the Apache instance
- Thread T1 - a request comes in.
- Thread T1 - acquires the
- Thread T2 - a request comes in (T1 is part of the way through
- Thread T2 -
None, but it's not completely loaded either, continues with the request
- Thread T1 - completes
self.load_middleware(), release the lock
The attached patch changes
BaseHandler.load_middleware() to do an atomic set of all four middleware lists.
self._request_middleware is set last to signal the completion of middleware loading.