summaryrefslogtreecommitdiff
path: root/includes/menu.inc
diff options
context:
space:
mode:
Diffstat (limited to 'includes/menu.inc')
-rw-r--r--includes/menu.inc21
1 files changed, 19 insertions, 2 deletions
diff --git a/includes/menu.inc b/includes/menu.inc
index 4ad0770be..de37139a0 100644
--- a/includes/menu.inc
+++ b/includes/menu.inc
@@ -1835,18 +1835,35 @@ function menu_cache_clear_all() {
* schedule a call to itself on the first real page load from
* menu_execute_active_handler(), because the maintenance page environment
* is different and leaves stale data in the menu tables.
+ *
+ * @return
+ * TRUE if the menu was rebuilt, FALSE if another thread was rebuilding
+ * in parallel and the current thread just waited for completion.
*/
function menu_rebuild() {
- variable_del('menu_rebuild_needed');
+ if (!lock_acquire('menu_rebuild')) {
+ // Wait for another request that is already doing this work.
+ // We choose to block here since otherwise the router item may not
+ // be available in menu_execute_active_handler() resulting in a 404.
+ lock_wait('menu_rebuild');
+ return FALSE;
+ }
+
list($menu, $masks) = menu_router_build();
_menu_router_save($menu, $masks);
_menu_navigation_links_rebuild($menu);
+ // Clear the menu, page and block caches.
menu_cache_clear_all();
- // Clear the page and block caches.
_menu_clear_page_cache();
+
if (defined('MAINTENANCE_MODE')) {
variable_set('menu_rebuild_needed', TRUE);
}
+ else {
+ variable_del('menu_rebuild_needed');
+ }
+ lock_release('menu_rebuild');
+ return TRUE;
}
/**