Issue #147000 by Berdir, Dave Reid, pwolanin, pillarsdotnet, TR, jbrauer, dstol:...
authorGábor Hojtsy
Wed, 1 Feb 2012 11:34:24 +0000 (12:34 +0100)
committerGábor Hojtsy
Wed, 1 Feb 2012 11:34:24 +0000 (12:34 +0100)
includes/lock-install.inc [new file with mode: 0644]
includes/module.inc
install.php
modules/system/system.module

diff --git a/includes/lock-install.inc b/includes/lock-install.inc
new file mode 100644 (file)
index 0000000..34bfb28
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+
+/**
+ * @file
+ * A stub lock implementation to be used during the installation
+ * process when database access is not yet available. Because Drupal's
+ * install system should never be running in more than on concurrant
+ * request, we can bypass any need for locking.
+ */
+
+/**
+ * Initialize the locking system.
+ */
+function lock_init() {
+}
+
+/**
+ * Acquire (or renew) a lock, but do not block if it fails.
+ *
+ * @return
+ *   TRUE if the lock was acquired, FALSE if it failed.
+ */
+function lock_acquire($name, $timeout = 30.0) {
+  return TRUE;
+}
+
+/**
+ * Check if lock acquired by a different process may be available.
+ *
+ * @return
+ *   TRUE if there is no lock or it was removed, FALSE otherwise.
+ */
+function lock_may_be_available($name) {
+  return TRUE;
+}
+
+/**
+ * Wait for a lock to be available.
+ *
+ * @return
+ *   TRUE if the lock holds, FALSE if it is available.
+ */
+function lock_wait($name, $delay = 30) {
+  return FALSE;
+}
+
+/**
+ * Release a lock previously acquired by lock_acquire().
+ *
+ * This will release the named lock if it is still held by the current request.
+ *
+ * @param $name
+ *   The name of the lock.
+ */
+function lock_release($name) {
+}
+
+/**
+ * Release all previously acquired locks.
+ */
+function lock_release_all($lock_id = NULL) {
+}
index bc4fbea..7958367 100644 (file)
@@ -93,6 +93,14 @@ function module_list($refresh = FALSE, $bootstrap = TRUE, $sort = FALSE, $fixed_
  *   The array of filesystem objects used to rebuild the cache.
  */
 function module_rebuild_cache() {
+  $write_database = TRUE;
+  // If lock not acquired, return $files data without writing to database.
+  if (!lock_acquire('module_rebuild_cache')) {
+    $write_database = FALSE;
+    // Wait for the parallel thread to be done so we are more likely
+    // to get updated and consistent data.
+    lock_wait('module_rebuild_cache');
+  }
   // Get current list of modules
   $files = drupal_system_listing('\.module$', 'modules', 'name', 0);
 
@@ -119,32 +127,39 @@ function module_rebuild_cache() {
       unset($files[$filename]);
       continue;
     }
-    // Merge in defaults and save.
-    $files[$filename]->info = $file->info + $defaults;
 
     // Invoke hook_system_info_alter() to give installed modules a chance to
     // modify the data in the .info files if necessary.
     drupal_alter('system_info', $files[$filename]->info, $files[$filename]);
 
-    // Log the critical hooks implemented by this module.
-    $bootstrap = 0;
-    foreach (bootstrap_hooks() as $hook) {
-      if (module_hook($file->name, $hook)) {
-        $bootstrap = 1;
-        break;
+    // Merge in defaults and save.
+    $files[$filename]->info = $file->info + $defaults;
+  }
+
+  // If lock not acquired, return $files data without writing to database.
+  if ($write_database) {
+    foreach ($files as $filename => $file) {
+      // Log the critical hooks implemented by this module.
+      $bootstrap = 0;
+      foreach (bootstrap_hooks() as $hook) {
+        if (module_hook($file->name, $hook)) {
+          $bootstrap = 1;
+          break;
+        }
       }
-    }
 
-    // Update the contents of the system table:
-    if (isset($file->status) || (isset($file->old_filename) && $file->old_filename != $file->filename)) {
-      db_query("UPDATE {system} SET info = '%s', name = '%s', filename = '%s', bootstrap = %d WHERE filename = '%s'", serialize($files[$filename]->info), $file->name, $file->filename, $bootstrap, $file->old_filename);
-    }
-    else {
-      // This is a new module.
-      $files[$filename]->status = 0;
-      $files[$filename]->throttle = 0;
-      db_query("INSERT INTO {system} (name, info, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $file->name, serialize($files[$filename]->info), 'module', $file->filename, 0, 0, $bootstrap);
+      // Update the contents of the system table:
+      if (isset($file->status)) {
+        db_query("UPDATE {system} SET info = '%s', name = '%s', filename = '%s', bootstrap = %d WHERE filename = '%s'", serialize($files[$filename]->info), $file->name, $file->filename, $bootstrap, $file->old_filename);
+      }
+      else {
+        // This is a new module.
+        $files[$filename]->status = 0;
+        $files[$filename]->throttle = 0;
+        db_query("INSERT INTO {system} (name, info, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $file->name, serialize($files[$filename]->info), 'module', $file->filename, 0, 0, $bootstrap);
+      }
     }
+    lock_release('module_rebuild_cache');
   }
   $files = _module_build_dependencies($files);
   return $files;
index 8cac289..0773d33 100644 (file)
@@ -130,6 +130,12 @@ function install_main() {
     if (!$verify) {
       install_change_settings($profile, $install_locale);
     }
+    // The default lock implementation uses a database table,
+    // so we cannot use it for install, but we still need
+    // the API functions available.
+    require_once './includes/lock-install.inc';
+    $conf['lock_inc'] = './includes/lock-install.inc';
+    lock_init();
 
     // Install system.module.
     drupal_install_system();
index 5ad849b..db34a8c 100644 (file)
@@ -805,22 +805,48 @@ function system_theme_default() {
  *   Array of all available themes and their data.
  */
 function system_theme_data() {
+  $write_database = TRUE;
+  // If lock not acquired, return $files data without writing to database.
+  if (!lock_acquire('system_theme_data')) {
+    $write_database = FALSE;
+    // Wait for the parallel thread to be done so we are more likely
+    // to get updated and consistent data.
+    lock_wait('system_theme_data');
+  }
   // Scan the installation theme .info files and their engines.
   $themes = _system_theme_data();
+  foreach ($themes as $key => $theme) {
+    if (!isset($theme->owner)) {
+      $themes[$key]->owner = '';
+    }
+  }
 
   // Extract current files from database.
   system_get_files_database($themes, 'theme');
 
-  db_query("DELETE FROM {system} WHERE type = 'theme'");
+  // If lock not acquired, return $themes data without writing to database.
+  if ($write_database) {
+    $names = array();
 
-  foreach ($themes as $theme) {
-    if (!isset($theme->owner)) {
-      $theme->owner = '';
+    foreach ($themes as $theme) {
+      // Record the name of each theme found in the file system.
+      $names[] = $theme->name;
+      // Update the contents of the system table.
+      if (isset($theme->status) && !(defined('MAINTENANCE_MODE') && MAINTENANCE_MODE != 'install')) {
+        db_query("UPDATE {system} SET owner = '%s', info = '%s', filename = '%s' WHERE name = '%s' AND type = '%s'", $theme->owner, serialize($theme->info), $theme->filename, $theme->name, 'theme');
+      }
+      else {
+        $theme->status = ($theme->name == variable_get('theme_default', 'garland'));
+        // This is a new theme.
+        db_query("INSERT INTO {system} (name, owner, info, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, %d)", $theme->name, $theme->owner, serialize($theme->info), 'theme', $theme->filename, $theme->status, 0, 0);
+      }
     }
-
-    db_query("INSERT INTO {system} (name, owner, info, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, %d)", $theme->name, $theme->owner, serialize($theme->info), 'theme', $theme->filename, isset($theme->status) ? $theme->status : 0, 0, 0);
+    // Delete from the system table any themes missing from the file system.
+    if ($names) {
+      db_query("DELETE FROM {system} WHERE type = 'theme' AND name NOT IN (". db_placeholders($names, 'varchar') .")", $names);
+    }
+    lock_release('system_theme_data');
   }
-
   return $themes;
 }