summaryrefslogtreecommitdiff
path: root/sc/source/core/data/formulacell.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core/data/formulacell.cxx')
-rw-r--r--sc/source/core/data/formulacell.cxx133
1 files changed, 91 insertions, 42 deletions
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 835b813389c5..d6996fa35036 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -1724,7 +1724,24 @@ void ScFormulaCell::Interpret()
#endif
}
-void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam, bool bUpdateProgress )
+namespace {
+class StackCleaner
+{
+ ScDocument* pDoc;
+ ScInterpreter* pInt;
+ public:
+ StackCleaner( ScDocument* pD, ScInterpreter* pI )
+ : pDoc(pD), pInt(pI)
+ {}
+ ~StackCleaner()
+ {
+ delete pInt;
+ pDoc->DecInterpretLevel();
+ }
+};
+}
+
+void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam, bool bSingleThreaded )
{
RecursionCounter aRecursionCounter( pDocument->GetRecursionHelper(), this);
nSeenInIteration = pDocument->GetRecursionHelper().GetIteration();
@@ -1751,20 +1768,6 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam, bool bUp
if( pCode->GetCodeLen() && pDocument )
{
- class StackCleaner
- {
- ScDocument* pDoc;
- ScInterpreter* pInt;
- public:
- StackCleaner( ScDocument* pD, ScInterpreter* pI )
- : pDoc(pD), pInt(pI)
- {}
- ~StackCleaner()
- {
- delete pInt;
- pDoc->DecInterpretLevel();
- }
- };
pDocument->IncInterpretLevel();
ScInterpreter* pInterpreter = new ScInterpreter( this, pDocument, aPos, *pCode );
StackCleaner aStackCleaner( pDocument, pInterpreter);
@@ -2085,7 +2088,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam, bool bUp
// a changed result must still reset the stream flag
pDocument->SetStreamValid(aPos.Tab(), false, true);
}
- if ( !pCode->IsRecalcModeAlways() )
+ if ( bSingleThreaded && !pCode->IsRecalcModeAlways() )
pDocument->RemoveFromFormulaTree( this );
// FORCED cells also immediately tested for validity (start macro possibly)
@@ -2104,7 +2107,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam, bool bUp
}
// Reschedule slows the whole thing down considerably, thus only execute on percent change
- if (bUpdateProgress)
+ if (bSingleThreaded)
{
ScProgress *pProgress = ScProgress::GetInterpretProgress();
if (pProgress && pProgress->Enabled())
@@ -2112,13 +2115,59 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam, bool bUp
pProgress->SetStateCountDownOnPercent(
pDocument->GetFormulaCodeInTree()/MIN_NO_CODES_PER_PROGRESS_UPDATE );
}
+
+ switch (pInterpreter->GetVolatileType())
+ {
+ case ScInterpreter::VOLATILE:
+ // Volatile via built-in volatile functions. No actions needed.
+ break;
+ case ScInterpreter::VOLATILE_MACRO:
+ // The formula contains a volatile macro.
+ pCode->SetExclusiveRecalcModeAlways();
+ pDocument->PutInFormulaTree(this);
+ StartListeningTo(pDocument);
+ break;
+ case ScInterpreter::NOT_VOLATILE:
+ if (pCode->IsRecalcModeAlways())
+ {
+ // The formula was previously volatile, but no more.
+ EndListeningTo(pDocument);
+ pCode->SetExclusiveRecalcModeNormal();
+ }
+ else
+ {
+ // non-volatile formula. End listening to the area in case
+ // it's listening due to macro module change.
+ pDocument->EndListeningArea(BCA_LISTEN_ALWAYS, false, this);
+ }
+ pDocument->RemoveFromFormulaTree(this);
+ break;
+ default:
+ ;
+ }
}
+ }
+ else
+ {
+ // Cells with compiler errors should not be marked dirty forever
+ OSL_ENSURE( pCode->GetCodeError() != FormulaError::NONE, "no RPN code and no errors ?!?!" );
+ ResetDirty();
+ }
+}
+
+void ScFormulaCell::HandleStuffAfterParallelCalculation()
+{
+ if( pCode->GetCodeLen() && pDocument )
+ {
+ if ( !pCode->IsRecalcModeAlways() )
+ pDocument->RemoveFromFormulaTree( this );
+
+ pDocument->IncInterpretLevel();
+ ScInterpreter* pInterpreter = new ScInterpreter( this, pDocument, aPos, *pCode );
+ StackCleaner aStackCleaner( pDocument, pInterpreter);
switch (pInterpreter->GetVolatileType())
{
- case ScInterpreter::VOLATILE:
- // Volatile via built-in volatile functions. No actions needed.
- break;
case ScInterpreter::VOLATILE_MACRO:
// The formula contains a volatile macro.
pCode->SetExclusiveRecalcModeAlways();
@@ -2144,12 +2193,6 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam, bool bUp
;
}
}
- else
- {
- // Cells with compiler errors should not be marked dirty forever
- OSL_ENSURE( pCode->GetCodeError() != FormulaError::NONE, "no RPN code and no errors ?!?!" );
- ResetDirty();
- }
}
void ScFormulaCell::SetCompile( bool bVal )
@@ -4255,27 +4298,33 @@ bool ScFormulaCell::InterpretFormulaGroup()
SAL_INFO("sc.threaded", "Running " << nThreadCount << " threads");
- ScMutationGuard aGuard(pDocument, ScMutationGuardFlags::CORE);
-
- // Start nThreadCount new threads
- std::vector<int> vResult(nThreadCount);
- std::shared_ptr<comphelper::ThreadTaskTag> aTag = comphelper::ThreadPool::createThreadTaskTag();
- for (int i = 0; i < nThreadCount; ++i)
- {
- rThreadPool.pushTask(new Executor(aTag, i, nThreadCount, pDocument, mxGroup->mpTopCell->aPos, mxGroup->mnLength, vResult));
- }
- SAL_INFO("sc.threaded", "Joining threads");
- rThreadPool.waitUntilDone(aTag);
- SAL_INFO("sc.threaded", "Done");
- for (int i = 0; i < nThreadCount; ++i)
{
- if (!vResult[i])
+ ScMutationGuard aGuard(pDocument, ScMutationGuardFlags::CORE);
+
+ // Start nThreadCount new threads
+ std::vector<int> vResult(nThreadCount);
+ std::shared_ptr<comphelper::ThreadTaskTag> aTag = comphelper::ThreadPool::createThreadTaskTag();
+ for (int i = 0; i < nThreadCount; ++i)
{
- SAL_INFO("sc.threaded", "Thread " << i << " failed");
- result = false;
+ rThreadPool.pushTask(new Executor(aTag, i, nThreadCount, pDocument, mxGroup->mpTopCell->aPos, mxGroup->mnLength, vResult));
+ }
+
+ SAL_INFO("sc.threaded", "Joining threads");
+ rThreadPool.waitUntilDone(aTag);
+ SAL_INFO("sc.threaded", "Done");
+
+ for (int i = 0; i < nThreadCount; ++i)
+ {
+ if (!vResult[i])
+ {
+ SAL_INFO("sc.threaded", "Thread " << i << " failed");
+ result = false;
+ }
}
}
+ pDocument->HandleStuffAfterParallelCalculation(mxGroup->mpTopCell->aPos, mxGroup->mnLength);
+
return result;
}