Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.450
diff -u -p -r1.450 bootstrap.inc
--- includes/bootstrap.inc	1 Dec 2010 07:54:50 -0000	1.450
+++ includes/bootstrap.inc	3 Dec 2010 03:33:17 -0000
@@ -725,43 +725,6 @@ function drupal_get_filename($type, $nam
 }
 
 /**
- * Load the persistent variable table.
- *
- * The variable table is composed of values that have been saved in the table
- * with variable_set() as well as those explicitly specified in the configuration
- * file.
- */
-function variable_initialize($conf = array()) {
-  // NOTE: caching the variables improves performance by 20% when serving
-  // cached pages.
-  if ($cached = cache_get('variables', 'cache_bootstrap')) {
-    $variables = $cached->data;
-  }
-  else {
-    // Cache miss. Avoid a stampede.
-    $name = 'variable_init';
-    if (!lock_acquire($name, 1)) {
-      // Another request is building the variable cache.
-      // Wait, then re-run this function.
-      lock_wait($name);
-      return variable_initialize($conf);
-    }
-    else {
-      // Proceed with variable rebuild.
-      $variables = array_map('unserialize', db_query('SELECT name, value FROM {variable}')->fetchAllKeyed());
-      cache_set('variables', $variables, 'cache_bootstrap');
-      lock_release($name);
-    }
-  }
-
-  foreach ($conf as $name => $value) {
-    $variables[$name] = $value;
-  }
-
-  return $variables;
-}
-
-/**
  * Returns a persistent variable.
  *
  * Case-sensitivity of the variable_* functions depends on the database
@@ -786,6 +749,34 @@ function variable_get($name, $default = 
 }
 
 /**
+ * Load the persistent variable table.
+ *
+ * The variable table is composed of values that have been saved in the table
+ * with variable_set() as well as those explicitly specified in the configuration
+ * file.
+ */
+function variable_initialize($conf = array()) {
+  // NOTE: caching the variables improves performance by 20% when serving
+  // cached pages.
+  if ($cached = cache_get('variables', 'cache_bootstrap')) {
+    $variables = $cached->data;
+  }
+  else {
+    // Signal to variable_reset_cache() that this is a read-only operation.
+    // In this case, if no lock can be acquired, the variable values are
+    // returned without writing to the persistent cache to avoid a race
+    // between reading and writing to the cache.
+    $variables = variable_reset_cache(FALSE);
+  }
+
+  foreach ($conf as $name => $value) {
+    $variables[$name] = $value;
+  }
+
+  return $variables;
+}
+
+/**
  * Sets a persistent variable.
  *
  * Case-sensitivity of the variable_* functions depends on the database
@@ -803,12 +794,37 @@ function variable_get($name, $default = 
  */
 function variable_set($name, $value) {
   global $conf;
+  $conf[$name] = $value;
 
   db_merge('variable')->key(array('name' => $name))->fields(array('value' => serialize($value)))->execute();
+  variable_reset_cache();
+}
 
-  cache_clear_all('variables', 'cache_bootstrap');
-
-  $conf[$name] = $value;
+/**
+ * Reset the variable cache safely.
+ *
+ * @param bool $variable_write
+ */
+function variable_reset_cache($variable_write = TRUE) {
+  $lock_name = __FUNCTION__;
+  if (!$lock_acquired = lock_acquire($lock_name, 1) && $variable_write) {
+    // When we've made a change via variable_set() or variable_del(), we try
+    // harder to get the lock.
+    lock_wait($lock_name);
+    $lock_acquired = lock_acquire($lock_name, 1);
+  }
+  $variables = array_map('unserialize', db_query('SELECT name, value FROM {variable}')->fetchAllKeyed());
+  if ($lock_acquired) {
+    cache_set('variables', $variables, 'cache_bootstrap');
+    lock_release($lock_name);
+  }
+  else if ($variable_write) {
+    // When we've made a change via variable_set() or variable_del() and failed
+    // to rebuild the cache, we need to clear it to ensure that subsequent
+    // requests pick up the changes.
+    cache_clear_all('variables', 'cache_bootstrap');
+  }
+  return $variables;
 }
 
 /**
@@ -830,9 +846,10 @@ function variable_del($name) {
   db_delete('variable')
     ->condition('name', $name)
     ->execute();
-  cache_clear_all('variables', 'cache_bootstrap');
 
   unset($conf[$name]);
+
+  variable_reset_cache();
 }
 
 /**
