summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwebchick <webchick@24967.no-reply.drupal.org>2012-04-28 23:39:22 -0700
committerwebchick <webchick@24967.no-reply.drupal.org>2012-04-28 23:39:22 -0700
commita5e79e0cba1e9b2ebb63d73c7cc8ea488cb83f9a (patch)
tree8c813fbc31f8752b5e839116060f05002b2e4b55
parent9647c746ba5ef11003a6eee2aa7f58d40228a36a (diff)
downloadbrdo-a5e79e0cba1e9b2ebb63d73c7cc8ea488cb83f9a.tar.gz
brdo-a5e79e0cba1e9b2ebb63d73c7cc8ea488cb83f9a.tar.bz2
Issue #1372122 by klausi, sun, beejeebus, juampy, mradcliffe, tim.plunkett, cha0s: Fixed STOP the registry integrity constraint violation nightmare.
-rw-r--r--includes/bootstrap.inc19
-rw-r--r--includes/registry.inc34
2 files changed, 38 insertions, 15 deletions
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 9f43b9232..104aa708a 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -3088,11 +3088,30 @@ function registry_rebuild() {
* to be called, because it is already known that the list of files in the
* {system} table matches those in the file system.
*
+ * @return
+ * TRUE if the registry was rebuilt, FALSE if another thread was rebuilding
+ * in parallel and the current thread just waited for completion.
+ *
* @see registry_rebuild()
*/
function registry_update() {
+ // install_system_module() calls module_enable() which calls into this
+ // function during initial system installation, so the lock system is neither
+ // loaded nor does its storage exist yet.
+ $in_installer = drupal_installation_attempted();
+ if (!$in_installer && !lock_acquire(__FUNCTION__)) {
+ // Another request got the lock, wait for it to finish.
+ lock_wait(__FUNCTION__);
+ return FALSE;
+ }
+
require_once DRUPAL_ROOT . '/includes/registry.inc';
_registry_update();
+
+ if (!$in_installer) {
+ lock_release(__FUNCTION__);
+ }
+ return TRUE;
}
/**
diff --git a/includes/registry.inc b/includes/registry.inc
index c7b8702c4..f6c81eb1a 100644
--- a/includes/registry.inc
+++ b/includes/registry.inc
@@ -131,10 +131,6 @@ function _registry_parse_files($files) {
if (file_exists($filename)) {
$hash = hash_file('sha256', $filename);
if (empty($file['hash']) || $file['hash'] != $hash) {
- // Delete registry entries for this file, so we can insert the new resources.
- db_delete('registry')
- ->condition('filename', $filename)
- ->execute();
$file['hash'] = $hash;
$parsed_files[$filename] = $file;
}
@@ -156,9 +152,9 @@ function _registry_parse_files($files) {
* Parse a file and save its function and class listings.
*
* @param $filename
- * Name of the file we are going to parse.
+ * Name of the file we are going to parse.
* @param $contents
- * Contents of the file we are going to parse as a string.
+ * Contents of the file we are going to parse as a string.
* @param $module
* (optional) Name of the module this file belongs to.
* @param $weight
@@ -166,17 +162,25 @@ function _registry_parse_files($files) {
*/
function _registry_parse_file($filename, $contents, $module = '', $weight = 0) {
if (preg_match_all('/^\s*(?:abstract|final)?\s*(class|interface)\s+([a-zA-Z0-9_]+)/m', $contents, $matches)) {
- $query = db_insert('registry')->fields(array('name', 'type', 'filename', 'module', 'weight'));
foreach ($matches[2] as $key => $name) {
- $query->values(array(
- 'name' => $name,
- 'type' => $matches[1][$key],
- 'filename' => $filename,
- 'module' => $module,
- 'weight' => $weight,
- ));
+ db_merge('registry')
+ ->key(array(
+ 'name' => $name,
+ 'type' => $matches[1][$key],
+ ))
+ ->fields(array(
+ 'filename' => $filename,
+ 'module' => $module,
+ 'weight' => $weight,
+ ))
+ ->execute();
}
- $query->execute();
+ // Delete any resources for this file where the name is not in the list
+ // we just merged in.
+ db_delete('registry')
+ ->condition('filename', $filename)
+ ->condition('name', $matches[2], 'NOT IN')
+ ->execute();
}
}