Index: includes/cache.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/cache.inc,v retrieving revision 1.25.2.4 diff -u -p -r1.25.2.4 cache.inc --- includes/cache.inc 12 Mar 2010 01:51:47 -0000 1.25.2.4 +++ includes/cache.inc 24 Dec 2010 05:38:49 -0000 @@ -102,18 +102,61 @@ function _views_discover_default_views() if (!isset($cache)) { $index = views_cache_get('views_default_views_index', TRUE); + $rebuild_cache = TRUE; + $lock_name = __FUNCTION__; // Retrieve each cached default view - if (isset($index->data) && is_array($index->data)) { + if ($index->data && is_array($index->data)) { + $rebuild_cache = FALSE; $cache = array(); foreach ($index->data as $view_name) { - $data = views_cache_get('views_default:' . $view_name, TRUE); - if (isset($data->data) && is_object($data->data)) { + $cid = 'views_default:' . $view_name; + if ($cached = views_cache_get($cid, TRUE)) { $cache[$view_name] = $data->data; } + else { + // As soon as there is a cache miss on one item, try to acquire a + // lock. + if (!$lock_acquired = lock_acquire($lock_name)) { + lock_wait($lock_name); + // After waiting, try to fetch the default view from cache again. + // If available another process may have rebuilt it, so do not + // attempt to rebuild the cache. + if ($cached = views_cache_get($cid, TRUE)) { + $cache[$view_name] = $data->data; + } + // If the item is still not in the cache, try to acquire the lock + // again and rebuild the cache. + else { + $lock_acquired = lock_acquire($lock_name); + $rebuild_cache = TRUE; + break; + } + } + // If the lock was acquired, always rebuild the cache. + else { + $rebuild_cache = TRUE; + break; + } + } } } - // If missing index, rebuild the cache else { + if (!$lock_acquired = lock_acquire($lock_name)) { + lock_wait(); + if ($cached = views_cache_get('views_default_views_index', TRUE)) { + // Another process has rebuilt the cache while we waited. Re-run the + // function to avoid a full cache rebuild. + _views_discover_default_views(); + } + else { + // Try to re-acquire the lock and re-build the cache either way. + lock_acquire($lock_name); + $rebuild_cache = TRUE; + } + } + } + // Rebuild the cache if necessary. + if ($rebuild_cache) { views_include_default_views(); $cache = array(); @@ -147,6 +190,7 @@ function _views_discover_default_views() foreach ($cache as $name => $view) { views_cache_set('views_default:' . $name, $view, TRUE); } + lock_release($lock_name); } }