Kaydet (Commit) b35fa775 authored tarafından Dennis Francis's avatar Dennis Francis Kaydeden (comit) Michael Meeks

Do not do threaded group calc if...

the dependency computation resulted in a breach of
recursion limit of MAXRECURSION. In such a case,
the formula-group we are trying to thread is at the
bottom of recursion guard stack and the dependencies
(up the recursion guard stack) are yet to be computed,
so the formula-group is not safe for threading.

This patch fixes a crash in tdf#115034/1 when threading
is enabled.

Change-Id: I81737d3dd00f4e5cc782e9f030c18e36f6337a1b
Reviewed-on: https://gerrit.libreoffice.org/54789Reviewed-by: 's avatarMichael Meeks <michael.meeks@collabora.com>
Tested-by: Jenkins
üst 3e76985d
...@@ -4405,8 +4405,9 @@ bool ScFormulaCell::InterpretFormulaGroup() ...@@ -4405,8 +4405,9 @@ bool ScFormulaCell::InterpretFormulaGroup()
return false; return false;
auto aScope = sc::FormulaLogger::get().enterGroup(*pDocument, *this); auto aScope = sc::FormulaLogger::get().enterGroup(*pDocument, *this);
ScRecursionHelper& rRecursionHelper = pDocument->GetRecursionHelper();
if (pDocument->GetRecursionHelper().GetRecursionCount()) if (rRecursionHelper.GetRecursionCount())
{ {
// Do not attempt to interpret a group when calculations are already // Do not attempt to interpret a group when calculations are already
// running, otherwise we may run into a circular reference hell. See // running, otherwise we may run into a circular reference hell. See
...@@ -4441,7 +4442,7 @@ bool ScFormulaCell::InterpretFormulaGroup() ...@@ -4441,7 +4442,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
// ScFormulaCell::InterpretFormulaGroup() must never be called through // ScFormulaCell::InterpretFormulaGroup() must never be called through
// anything else than ScFormulaCell::Interpret(), same as // anything else than ScFormulaCell::Interpret(), same as
// ScFormulaCell::InterpretTail() // ScFormulaCell::InterpretTail()
RecursionCounter aRecursionCounter( pDocument->GetRecursionHelper(), this); RecursionCounter aRecursionCounter( rRecursionHelper, this);
// Preference order: // Preference order:
// First try OpenCL, but only if actual OpenCL is available (i.e. no SwInterpreter). // First try OpenCL, but only if actual OpenCL is available (i.e. no SwInterpreter).
...@@ -4473,7 +4474,16 @@ bool ScFormulaCell::InterpretFormulaGroupThreading(sc::FormulaLogger::GroupScope ...@@ -4473,7 +4474,16 @@ bool ScFormulaCell::InterpretFormulaGroupThreading(sc::FormulaLogger::GroupScope
// Disable or hugely enlarge subset for S/W group // Disable or hugely enlarge subset for S/W group
// threading interpreter // threading interpreter
if (!aCalculator.DoIt()) bool bOKToThread = aCalculator.DoIt();
if (pDocument->GetRecursionHelper().IsInRecursionReturn())
{
mxGroup->meCalcState = sc::GroupCalcDisabled;
aScope.addMessage("Recursion limit reached, cannot thread this formula group now");
return false;
}
if (!bOKToThread)
{ {
mxGroup->meCalcState = sc::GroupCalcDisabled; mxGroup->meCalcState = sc::GroupCalcDisabled;
aScope.addMessage("could not do new dependencies calculation thing"); aScope.addMessage("could not do new dependencies calculation thing");
...@@ -4535,7 +4545,6 @@ bool ScFormulaCell::InterpretFormulaGroupThreading(sc::FormulaLogger::GroupScope ...@@ -4535,7 +4545,6 @@ bool ScFormulaCell::InterpretFormulaGroupThreading(sc::FormulaLogger::GroupScope
nThreadCount /= 2; nThreadCount /= 2;
SAL_INFO("sc.threaded", "Running " << nThreadCount << " threads"); SAL_INFO("sc.threaded", "Running " << nThreadCount << " threads");
{ {
assert(!pDocument->IsThreadedGroupCalcInProgress()); assert(!pDocument->IsThreadedGroupCalcInProgress());
pDocument->SetThreadedGroupCalcInProgress(true); pDocument->SetThreadedGroupCalcInProgress(true);
......
...@@ -16,7 +16,7 @@ void ScRecursionHelper::Init() ...@@ -16,7 +16,7 @@ void ScRecursionHelper::Init()
bInRecursionReturn = bDoingRecursion = bInIterationReturn = false; bInRecursionReturn = bDoingRecursion = bInIterationReturn = false;
aInsertPos = GetIterationEnd(); aInsertPos = GetIterationEnd();
ResetIteration(); ResetIteration();
aFGList.clear(); // Must not force clear aFGList ever.
} }
void ScRecursionHelper::ResetIteration() void ScRecursionHelper::ResetIteration()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment