From b70b4fc4602804a95e0e5f2946a47dbe53dacf9a Mon Sep 17 00:00:00 2001 From: "Daniel Knoppel (Phusion)" Date: Thu, 30 Apr 2015 16:34:29 +0200 Subject: [PATCH] Fix for SIGSEGV crash when using passenger with OOBGC. The least busy process selection method was only suitable for enabled processes, and not disabling/disabled processes. Closes GH-1469. --- CHANGELOG | 6 ++++++ ext/common/ApplicationPool2/Group.h | 28 +++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 55f4e91ec2..7950c9bc42 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +Release 5.0.8 +------------- + + * Fixes a Passenger crash (SIGSEGV) that occurs occasionally when out-of-band garbage collection is enabled. Closes GH-1469. + + Release 5.0.7 ------------- diff --git a/ext/common/ApplicationPool2/Group.h b/ext/common/ApplicationPool2/Group.h index 6380ca453d..6a1140e02f 100644 --- a/ext/common/ApplicationPool2/Group.h +++ b/ext/common/ApplicationPool2/Group.h @@ -389,7 +389,7 @@ class Group: public boost::enable_shared_from_this { RouteResult route(const Options &options) const { if (OXT_LIKELY(enabledCount > 0)) { if (options.stickySessionId == 0) { - Process *process = findProcessWithLowestBusyness(enabledProcesses); + Process *process = findEnabledProcessWithLowestBusyness(); if (process->canBeRoutedTo()) { return RouteResult(process); } else { @@ -496,6 +496,29 @@ class Group: public boost::enable_shared_from_this { return NULL; } + int lowestBusyness = -1; + Process *leastBusyProcess = NULL; + ProcessList::const_iterator it; + ProcessList::const_iterator end = processes.end(); + for (it = processes.begin(); it != end; it++) { + Process *process = (*it).get(); + int busyness = process->busyness(); + if (lowestBusyness == -1 || lowestBusyness > busyness) { + lowestBusyness = busyness; + leastBusyProcess = process; + } + } + return leastBusyProcess; + } + + /** + * Cache-optimized version of findProcessWithLowestBusyness() for the common case. + */ + Process *findEnabledProcessWithLowestBusyness() const { + if (enabledProcesses.empty()) { + return NULL; + } + int leastBusyProcessIndex = -1; int lowestBusyness = 0; unsigned int i, size = enabledProcessBusynessLevels.size(); @@ -1006,8 +1029,7 @@ class Group: public boost::enable_shared_from_this { assert(m_spawning || restarting() || poolAtFullCapacity()); if (disablingCount > 0 && !restarting()) { - Process *process = findProcessWithLowestBusyness( - disablingProcesses); + Process *process = findProcessWithLowestBusyness(disablingProcesses); assert(process != NULL); if (!process->isTotallyBusy()) { return newSession(process, newOptions.currentTime);