diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 4967991..982d1fc 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -2938,11 +2938,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 . '/core/includes/registry.inc'; _registry_update(); + + if (!$in_installer) { + lock_release(__FUNCTION__); + } + return TRUE; } /** diff --git a/core/includes/registry.inc b/core/includes/registry.inc index 7ac2960..5767057 100644 --- a/core/includes/registry.inc +++ b/core/includes/registry.inc @@ -127,10 +127,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; } @@ -152,9 +148,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 @@ -162,17 +158,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(); } }