summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--includes/lock-install.inc62
-rw-r--r--includes/module.inc51
-rw-r--r--install.php6
-rw-r--r--modules/system/system.module40
4 files changed, 134 insertions, 25 deletions
diff --git a/includes/lock-install.inc b/includes/lock-install.inc
new file mode 100644
index 0000000..34bfb28
--- /dev/null
+++ b/includes/lock-install.inc
@@ -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) {
+}
diff --git a/includes/module.inc b/includes/module.inc
index bc4fbea..7958367 100644
--- a/includes/module.inc
+++ b/includes/module.inc
@@ -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;
diff --git a/install.php b/install.php
index 8cac289..0773d33 100644
--- a/install.php
+++ b/install.php
@@ -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();
diff --git a/modules/system/system.module b/modules/system/system.module
index 5ad849b..db34a8c 100644
--- a/modules/system/system.module
+++ b/modules/system/system.module
@@ -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;
}