summaryrefslogtreecommitdiff
path: root/sc/inc
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2018-10-01 14:26:57 +0200
committerLuboš Luňák <l.lunak@collabora.com>2018-10-10 13:01:59 +0200
commit79449d73900d7a9bf061244d76f5f8eecc441198 (patch)
treee85f9bc29941cbf5e5ccb858ee4703ae67d00810 /sc/inc
parentb1721b04d8a921a69230927cd7995d8c5d8f5fe2 (diff)
make VLOOKUP in Calc thread-safe
There is mutex protection needed for accessing the same SvtBroadcaster when calling StartListeningArea(). Also some of the memory management and caching needed fixing. Change-Id: Ia57ed85286cf195521719cfd3b320f73a6342bb1 Reviewed-on: https://gerrit.libreoffice.org/61187 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'sc/inc')
-rw-r--r--sc/inc/document.hxx17
-rw-r--r--sc/inc/interpretercontext.hxx10
-rw-r--r--sc/inc/lookupcache.hxx8
3 files changed, 22 insertions, 13 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 06c155a07aa4..96b28d4d13f0 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -171,7 +171,7 @@ class VirtualDevice;
class ScAutoNameCache;
class ScTemporaryChartLock;
class ScLookupCache;
-struct ScLookupCacheMapImpl;
+struct ScLookupCacheMap;
class SfxUndoManager;
class ScFormulaParserPool;
struct ScClipParam;
@@ -276,11 +276,8 @@ struct ScDocumentThreadSpecific
{
ScRecursionHelper* pRecursionHelper; // information for recursive and iterative cell formulas
- ScLookupCacheMapImpl* pLookupCacheMapImpl; // cache for lookups like VLOOKUP and MATCH
-
ScDocumentThreadSpecific() :
- pRecursionHelper(nullptr),
- pLookupCacheMapImpl(nullptr)
+ pRecursionHelper(nullptr)
{
}
@@ -457,6 +454,9 @@ private:
mutable ScInterpreterContext maInterpreterContext;
+ osl::Mutex mScLookupMutex; // protection for thread-unsafe parts of handling ScLookup
+ std::vector<ScLookupCacheMap*> mThreadStoredScLookupCaches; // temporarily stored for computation threads
+
sal_uInt16 nSrcVer; // file version (load/save)
sal_uInt16 nFormulaTrackCount;
HardRecalcState eHardRecalcState; // off, temporary, eternal
@@ -582,7 +582,8 @@ public:
maInterpreterContext.mpFormatter = GetFormatTable();
return maInterpreterContext;
}
- void MergeBackIntoNonThreadedContext( ScInterpreterContext& threadedContext );
+ void SetupFromNonThreadedContext( ScInterpreterContext& threadedContext, int threadNumber );
+ void MergeBackIntoNonThreadedContext( ScInterpreterContext& threadedContext, int threadNumber );
void SetThreadedGroupCalcInProgress( bool set ) { (void)this; ScGlobal::bThreadedGroupCalcInProgress = set; }
bool IsThreadedGroupCalcInProgress() const { (void)this; return ScGlobal::bThreadedGroupCalcInProgress; }
@@ -1291,7 +1292,7 @@ public:
/** Creates a ScLookupCache cache for the range if it
doesn't already exist. */
- ScLookupCache & GetLookupCache( const ScRange & rRange );
+ ScLookupCache & GetLookupCache( const ScRange & rRange, ScInterpreterContext* pContext );
/** Only ScLookupCache dtor uses RemoveLookupCache(), do
not use elsewhere! */
void RemoveLookupCache( ScLookupCache & rCache );
@@ -2494,6 +2495,8 @@ private:
void EndListeningGroups( const std::vector<ScAddress>& rPosArray );
void SetNeedsListeningGroups( const std::vector<ScAddress>& rPosArray );
+
+ bool RemoveLookupCacheHelper( ScLookupCacheMap* cacheMap, ScLookupCache& rCache );
};
typedef std::unique_ptr<ScDocument, o3tl::default_delete<ScDocument>> ScDocumentUniquePtr;
diff --git a/sc/inc/interpretercontext.hxx b/sc/inc/interpretercontext.hxx
index 8b920472fb44..2855370e7b09 100644
--- a/sc/inc/interpretercontext.hxx
+++ b/sc/inc/interpretercontext.hxx
@@ -18,6 +18,7 @@
class ScDocument;
class SvNumberFormatter;
+struct ScLookupCacheMap;
// SetNumberFormat() is not thread-safe, so calls to it need to be delayed to the main thread.
struct DelayedSetNumberFormat
@@ -33,21 +34,18 @@ struct ScInterpreterContext
size_t mnTokenCachePos;
std::vector<formula::FormulaToken*> maTokens;
std::vector<DelayedSetNumberFormat> maDelayedSetNumberFormat;
+ ScLookupCacheMap* mScLookupCache; // cache for lookups like VLOOKUP and MATCH
ScInterpreterContext(const ScDocument& rDoc, SvNumberFormatter* pFormatter)
: mrDoc(rDoc)
, mpFormatter(pFormatter)
, mnTokenCachePos(0)
, maTokens(TOKEN_CACHE_SIZE, nullptr)
+ , mScLookupCache(nullptr)
{
}
- ~ScInterpreterContext()
- {
- for (auto p : maTokens)
- if (p)
- p->DecRef();
- }
+ ~ScInterpreterContext();
SvNumberFormatter* GetFormatTable() const { return mpFormatter; }
};
diff --git a/sc/inc/lookupcache.hxx b/sc/inc/lookupcache.hxx
index fa55c2bcbced..15ec15f086b1 100644
--- a/sc/inc/lookupcache.hxx
+++ b/sc/inc/lookupcache.hxx
@@ -23,6 +23,7 @@
#include "address.hxx"
#include <svl/listener.hxx>
+#include <memory>
#include <unordered_map>
class ScDocument;
@@ -189,6 +190,13 @@ private:
};
+// Struct because including lookupcache.hxx in document.hxx isn't wanted.
+struct ScLookupCacheMap
+{
+ std::unordered_map< ScRange, std::unique_ptr<ScLookupCache>, ScLookupCache::Hash > aCacheMap;
+};
+
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */