diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2018-10-01 14:26:57 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2018-10-10 13:01:59 +0200 |
commit | 79449d73900d7a9bf061244d76f5f8eecc441198 (patch) | |
tree | e85f9bc29941cbf5e5ccb858ee4703ae67d00810 /sc/inc | |
parent | b1721b04d8a921a69230927cd7995d8c5d8f5fe2 (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.hxx | 17 | ||||
-rw-r--r-- | sc/inc/interpretercontext.hxx | 10 | ||||
-rw-r--r-- | sc/inc/lookupcache.hxx | 8 |
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: */ |