diff -u b/includes/module.inc b/includes/module.inc --- b/includes/module.inc +++ b/includes/module.inc @@ -712,6 +712,7 @@ if ($reset) { $implementations = array(); cache_set('module_implements', array(), 'cache_bootstrap'); + drupal_static_reset('_module_implements_get_implementations'); drupal_static_reset('module_hook_info'); drupal_static_reset('drupal_alter'); cache_clear_all('hook_info', 'cache_bootstrap'); @@ -720,13 +721,7 @@ // Fetch implementations from cache. if (empty($implementations)) { - $implementations = cache_get('module_implements', 'cache_bootstrap'); - if ($implementations === FALSE) { - $implementations = array(); - } - else { - $implementations = $implementations->data; - } + $implementations = _module_implements_get_implementations(); } if (!isset($implementations[$hook])) { @@ -775,6 +770,38 @@ } /** + * Helper function that gets the module implementations from cache. + * + * @return array + * The module implementations. + */ +function _module_implements_get_implementations() { + $implementations_cached = &drupal_static(__FUNCTION__); + // Try to fetch the implementations from static cache. + if (isset($implementations_cached)) { + $implementations = $implementations_cached; + } + // Otherwise, get the implementations from the cache backend. + else { + $implementations = cache_get('module_implements', 'cache_bootstrap'); + if ($implementations === FALSE) { + $implementations = array(); + } + else { + // Set up the implementations variable. + $implementations = $implementations->data; + + // Because we reset the "module_implements" static at the end of the + // bootstrap, we store the cache result into another static variable + // so as to prevent having a second cache_get() in case + // module_implements() is called early in the bootstrap. + // @see _drupal_bootstrap_full() + $implementations_cached = $implementations; + } + } +} + +/** * Retrieves a list of hooks that are declared through hook_hook_info(). * * @return