summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2012-01-31 20:40:47 +0100
committerPetr Mladek <pmladek@suse.cz>2012-02-01 10:23:39 +0100
commit6ccf504e590a47bb950aa179590f7e61146c043d (patch)
tree38f41a3edc2db7471846b54e49e9485bfec3eff7
parentdon't delete thread while it is still running, fdo#45401 (diff)
downloadcore-6ccf504e590a47bb950aa179590f7e61146c043d.tar.gz
core-6ccf504e590a47bb950aa179590f7e61146c043d.zip
clone token in ScFormulaResult copy-ctor instead of referring
Replaces commit e2b11f4fd79dce4116badb0ecf6477546ca5d0d4 Prevent excessive references to single token instance during fill. Because if not, we may run out of the 16-bit integer space to store reference count. Signed-off-by: Kohei Yoshida <kohei.yoshida@suse.com> Signed-off-by: Markus Mohrhard <markus.mohrhard@googlemail.com> Signed-off-by: Petr Mladek <pmladek@suse.cz>
-rw-r--r--sc/inc/formularesult.hxx23
1 files changed, 20 insertions, 3 deletions
diff --git a/sc/inc/formularesult.hxx b/sc/inc/formularesult.hxx
index 2aa674c359f2..444552f835d1 100644
--- a/sc/inc/formularesult.hxx
+++ b/sc/inc/formularesult.hxx
@@ -41,6 +41,20 @@ class ScFormulaResult
static const Multiline MULTILINE_FALSE = 1;
static const Multiline MULTILINE_TRUE = 2;
+ // Clone token if the 16-bit only reference counter is nearing it's
+ // capacity during fill or copy&paste, leaving 4k for temporary passing
+ // around. (That should be enough for all times (TM) ;-)
+ static const sal_uInt16 MAX_TOKENREF_COUNT = 0xf000;
+ static void IncrementTokenRef( const formula::FormulaToken* & rp )
+ {
+ if (rp)
+ {
+ if (rp->GetRef() >= MAX_TOKENREF_COUNT)
+ rp = rp->Clone();
+ rp->IncRef();
+ }
+ }
+
union
{
double mfValue; // double result direct for performance and memory consumption
@@ -94,8 +108,12 @@ public:
const ScMatrixFormulaCellToken* pMatFormula =
r.GetMatrixFormulaCellToken();
if (pMatFormula)
+ {
mpToken = new ScMatrixFormulaCellToken( *pMatFormula);
- mpToken->IncRef();
+ mpToken->IncRef();
+ }
+ else
+ IncrementTokenRef( mpToken);
}
}
else
@@ -308,8 +326,7 @@ inline void ScFormulaResult::Assign( const ScFormulaResult & r )
inline void ScFormulaResult::SetToken( const formula::FormulaToken* p )
{
ResetToDefaults();
- if (p)
- p->IncRef();
+ IncrementTokenRef( p);
// Handle a result obtained from the interpreter to be assigned to a matrix
// formula cell's ScMatrixFormulaCellToken.
ScMatrixFormulaCellToken* pMatFormula = GetMatrixFormulaCellTokenNonConst();