Index: django/test/client.py
===================================================================
--- django/test/client.py	(revision 6809)
+++ django/test/client.py	(working copy)
@@ -29,10 +29,9 @@
         from django.conf import settings
         from django.core import signals
 
-        # Set up middleware if needed. We couldn't do this earlier, because
-        # settings weren't available.
-        if self._request_middleware is None:
-            self.load_middleware()
+        # Perform state setup to ensure middleware is registered, among
+        # other things.
+        self.state.ensure_state()
 
         dispatcher.send(signal=signals.request_started)
         try:
Index: django/conf/global_settings.py
===================================================================
--- django/conf/global_settings.py	(revision 6809)
+++ django/conf/global_settings.py	(working copy)
@@ -131,6 +131,9 @@
 EMAIL_HOST_PASSWORD = ''
 EMAIL_USE_TLS = False
 
+# List of functions to be called to setup the runtime environment
+RUNTIME_SETUP_FUNCTIONS = ()
+
 # List of strings representing installed apps.
 INSTALLED_APPS = ()
 
Index: django/core/handlers/wsgi.py
===================================================================
--- django/core/handlers/wsgi.py	(revision 6809)
+++ django/core/handlers/wsgi.py	(working copy)
@@ -180,20 +180,14 @@
     raw_post_data = property(_get_raw_post_data)
 
 class WSGIHandler(BaseHandler):
-    initLock = Lock()
     request_class = WSGIRequest
 
     def __call__(self, environ, start_response):
         from django.conf import settings
 
-        # Set up middleware if needed. We couldn't do this earlier, because
-        # settings weren't available.
-        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()
+        # Perform state setup to ensure middleware is registered, among
+        # other things.
+        self.state.ensure_state()
 
         dispatcher.send(signal=signals.request_started)
         try:
Index: django/core/handlers/base.py
===================================================================
--- django/core/handlers/base.py	(revision 6809)
+++ django/core/handlers/base.py	(working copy)
@@ -1,16 +1,56 @@
 from django.core import signals
 from django.dispatch import dispatcher
+from django.utils.setup import setup_runtime
 from django import http
 import sys
+import threading
+import logging
 
-class BaseHandler(object):
-    # Changes that are always applied to a response (in this order).
-    response_fixes = [http.fix_location_header,
-            http.conditional_content_removal]
+class HandlerState(object): 
+    """ 
+    A cache that stores/ensures state required for handling requests. 
+    This includes loading the middleware and performing runtime setup.
+    """ 
+    # Use the Borg pattern to share state between all instances. Details at 
+    # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66531. 
+    __shared_state = dict( 
+        request_middleware = [], 
+        view_middleware = [], 
+        response_middleware = [], 
+        exception_middleware = [], 
+        runtime_setup = False,  # Flag to monitor whether generic runtime environment setup has occured 
 
+        # -- Variables used to setup the state -- 
+        loaded = False,         # Flag to monitor the state of the cache 
+        write_lock = threading.RLock(),
+    )
+    
     def __init__(self):
-        self._request_middleware = self._view_middleware = self._response_middleware = self._exception_middleware = None
+        self.__dict__ = self.__shared_state
+        
+    def ensure_state(self): 
+        """ 
+        Fill in all the cache information, and perform any setup that is 
+        necessary. This method is threadsafe, in the sense that every caller 
+        will see the same state upon return, and if the cache is already 
+        initialised, it does no work. 
+        """ 
+        if self.loaded: 
+            return 
+        self.write_lock.acquire() 
+        try: 
+            if self.loaded: 
+                return 
 
+            setup_runtime() 
+            self.runtime_setup = True 
+ 
+            self.load_middleware() 
+ 
+            self.loaded = True 
+        finally: 
+            self.write_lock.release()
+
     def load_middleware(self):
         """
         Populate middleware lists from settings.MIDDLEWARE_CLASSES.
@@ -19,10 +59,7 @@
         """
         from django.conf import settings
         from django.core import exceptions
-        self._request_middleware = []
-        self._view_middleware = []
-        self._response_middleware = []
-        self._exception_middleware = []
+
         for middleware_path in settings.MIDDLEWARE_CLASSES:
             try:
                 dot = middleware_path.rindex('.')
@@ -44,14 +81,27 @@
                 continue
 
             if hasattr(mw_instance, 'process_request'):
-                self._request_middleware.append(mw_instance.process_request)
+                self.request_middleware.append(mw_instance.process_request)
             if hasattr(mw_instance, 'process_view'):
-                self._view_middleware.append(mw_instance.process_view)
+                self.view_middleware.append(mw_instance.process_view)
             if hasattr(mw_instance, 'process_response'):
-                self._response_middleware.insert(0, mw_instance.process_response)
+                self.response_middleware.insert(0, mw_instance.process_response)
             if hasattr(mw_instance, 'process_exception'):
-                self._exception_middleware.insert(0, mw_instance.process_exception)
+                self.exception_middleware.insert(0, mw_instance.process_exception)            
 
+handler_state = HandlerState() 
+	 
+class BaseHandler(object): 
+    state = handler_state 
+    _request_middleware = handler_state.request_middleware 
+    _view_middleware = handler_state.view_middleware 
+    _response_middleware = handler_state.response_middleware 
+    _exception_middleware = handler_state.exception_middleware
+
+    # Changes that are always applied to a response (in this order).
+    response_fixes = [http.fix_location_header,
+            http.conditional_content_removal]
+
     def get_response(self, request):
         "Returns an HttpResponse object for the given HttpRequest"
         from django.core import exceptions, urlresolvers
Index: django/core/handlers/modpython.py
===================================================================
--- django/core/handlers/modpython.py	(revision 6809)
+++ django/core/handlers/modpython.py	(working copy)
@@ -146,9 +146,9 @@
         # that use settings now can work
         from django.conf import settings
 
-        # if we need to set up middleware, now that settings works we can do it now.
-        if self._request_middleware is None:
-            self.load_middleware()
+        # Perform state setup to ensure middleware is registered, among
+        # other things.
+        self.state.ensure_state()
 
         dispatcher.send(signal=signals.request_started)
         try:
Index: django/core/management/commands/shell.py
===================================================================
--- django/core/management/commands/shell.py	(revision 6809)
+++ django/core/management/commands/shell.py	(working copy)
@@ -1,5 +1,6 @@
 import os
 from django.core.management.base import NoArgsCommand
+from django.utils.setup import setup_runtime
 from optparse import make_option
 
 class Command(NoArgsCommand):
@@ -12,6 +13,8 @@
     requires_model_validation = False
 
     def handle_noargs(self, **options):
+        setup_runtime() # Perform some setup that may be necessary to get the runtime environment ready
+
         # XXX: (Temporary) workaround for ticket #1796: force early loading of all
         # models from installed apps.
         from django.db.models.loading import get_models
