Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.626
diff -u -p -r1.626 theme.inc
--- includes/theme.inc	11 Dec 2010 02:06:25 -0000	1.626
+++ includes/theme.inc	20 Dec 2010 05:10:12 -0000
@@ -281,17 +281,37 @@ function _theme_registry_callback($callb
  */
 function _theme_load_registry($theme, $base_theme = NULL, $theme_engine = NULL) {
   // Check the theme registry cache; if it exists, use it.
-  $cache = cache_get("theme_registry:$theme->name", 'cache');
-  if (isset($cache->data)) {
-    $registry = $cache->data;
+  $cid = "theme_registry:$theme->name";
+
+  if ($cached = cache_get($cid, 'cache')) {
+    $registry = $cached->data;
   }
-  else {
-    // If not, build one and cache it.
+  elseif (module_load_all(NULL) {
+    // Rebuilding the theme registry is expensive, so use the locking system.
+    // However only do this if all modules are loaded, since the registry will
+    // never be cached during an incomplete bootstrap.
+    if (!lock_acquire($cid)) {
+      // If the lock acquire fails, wait, then try to fetch from cache again
+      // in case another process has rebuilt it in the meanwhile. If that
+      // fails, try to get the lock again, and proceed with the full rebuild
+      // either way.
+      lock_wait();
+      if ($cached = cache_get($cid, 'cache')) {
+        $registry = $cached->data;
+      }
+      else {
+        lock_acquire($cid);
+      }
+    }
+  }
+  if (!$cached) {
+    // Build and cache the theme registry..
     $registry = _theme_build_registry($theme, $base_theme, $theme_engine);
-   // Only persist this registry if all modules are loaded. This assures a
-   // complete set of theme hooks.
+    // Only persist this registry if all modules are loaded. This assures a
+    // complete set of theme hooks.
     if (module_load_all(NULL)) {
       _theme_save_registry($theme, $registry);
+      lock_release($cid);
     }
   }
   return $registry;
