Index: trac/env.py
===================================================================
--- trac/env.py	(revision 3747)
+++ trac/env.py	(working copy)
@@ -181,9 +181,9 @@
         """Return a database connection from the connection pool."""
         return DatabaseManager(self).get_connection()
 
-    def shutdown(self):
+    def shutdown(self, tid=None):
         """Close the environment."""
-        DatabaseManager(self).shutdown()
+        DatabaseManager(self).shutdown(tid)
 
     def get_repository(self, authname=None):
         """Return the version control repository configured for this
Index: trac/db/api.py
===================================================================
--- trac/db/api.py	(revision 3747)
+++ trac/db/api.py	(working copy)
@@ -70,9 +70,9 @@
             self._cnx_pool = ConnectionPool(5, connector, **args)
         return self._cnx_pool.get_cnx()
 
-    def shutdown(self):
+    def shutdown(self, tid=None):
         if self._cnx_pool:
-            self._cnx_pool.shutdown()
+            self._cnx_pool.shutdown(tid)
             self._cnx_pool = None
 
     def _get_connector(self): ### FIXME: Make it public?
Index: trac/db/pool.py
===================================================================
--- trac/db/pool.py	(revision 3747)
+++ trac/db/pool.py	(working copy)
@@ -19,6 +19,7 @@
 except ImportError:
     import dummy_threading as threading
     threading._get_ident = lambda: 0
+import sys
 import time
 
 from trac.db.util import ConnectionWrapper
@@ -87,6 +88,7 @@
                                                 'connection within %d seconds' \
                                                 % timeout
                     else:
+                        print>>sys.stderr, '[%d] wait for connection...' % tid
                         self._available.wait()
             self._active[tid] = [1, cnx]
             return PooledConnection(self, cnx)
@@ -103,21 +105,34 @@
                 if num > 1:
                     self._active[tid][0] = num - 1
                 else:
-                    del self._active[tid]
-                    if cnx not in self._dormant:
-                        cnx.rollback()
-                        if cnx.poolable:
-                            self._dormant.append(cnx)
-                        else:
-                            self._cursize -= 1
-                        self._available.notify()
+                    self._cleanup(tid)
         finally:
             self._available.release()
 
-    def shutdown(self):
+    def _cleanup(self, tid):
+        # Note: self._available *must* be acquired
+        if tid in self._active:
+            cnx = self._active.pop(tid)[1]
+            if cnx not in self._dormant:
+                cnx.rollback()
+                if cnx.poolable:
+                    self._dormant.append(cnx)
+                else:
+                    cnx.close()
+                    self._cursize -= 1
+                self._available.notify()
+
+    def shutdown(self, tid=None):
         self._available.acquire()
         try:
-            for cnx in self._dormant:
-                cnx.cnx.close()
+            if tid:
+                cleanup_list = [tid]
+            else:
+                cleanup_list = self._active.keys()
+            for tid in cleanup_list:
+                self._cleanup(tid)
+            if not tid:
+                for cnx in self._dormant:
+                    cnx.close()
         finally:
             self._available.release()
Index: trac/web/main.py
===================================================================
--- trac/web/main.py	(revision 3747)
+++ trac/web/main.py	(working copy)
@@ -228,6 +228,8 @@
                         req.display(template, content_type or 'text/html')
                     else:
                         self._post_process_request(req)
+                except RequestDone:
+                    raise
                 except:
                     err = sys.exc_info()
                     try:
@@ -348,7 +350,6 @@
 
     req = Request(environ, start_response)
     try:
-        db = env.get_db_cnx()
         try:
             try:
                 dispatcher = RequestDispatcher(env)
@@ -357,7 +358,8 @@
                 pass
             return req._response or []
         finally:
-            db.close()
+            if environ.get('wsgi.multithread', False):
+                env.shutdown(threading._get_ident())
 
     except HTTPException, e:
         env.log.warn(e)

