include/formula/token.hxx | 19 ++++-- sc/inc/externalrefmgr.hxx | 35 ++++++++--- sc/source/core/tool/compiler.cxx | 2 sc/source/ui/docshell/externalrefmgr.cxx | 91 +++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 18 deletions(-)
New commits: commit 3f04bb5305dc35b34cbec5e4738b3f63c7a10b6b Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Tue Nov 5 19:06:15 2013 -0500 Guard cache access with mutex & a new method just to check for range name. Change-Id: Id24b5ba72362f9d878b4878c1e807bed3e596b20 diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx index 6156abb..b3d35f9 100644 --- a/sc/inc/externalrefmgr.hxx +++ b/sc/inc/externalrefmgr.hxx @@ -233,6 +233,7 @@ public: ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const OUString& rName); void setRangeNameTokens(sal_uInt16 nFileId, const OUString& rName, TokenArrayRef pArray); + bool isValidRangeName(sal_uInt16 nFileId, const OUString& rName) const; void setCellData(sal_uInt16 nFileId, const OUString& rTabName, SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uLong nFmtIndex); @@ -557,6 +558,8 @@ public: ScExternalRefCache::TokenArrayRef getRangeNameTokens( sal_uInt16 nFileId, const OUString& rName, const ScAddress* pCurPos = NULL); + bool isValidRangeName(sal_uInt16 nFileId, const OUString& rName); + OUString getOwnDocumentName() const; bool isOwnDocument(const OUString& rFile) const; @@ -765,6 +768,12 @@ private: private: ScDocument* mpDoc; + /** Mutex for accessing cached data and/or source document shells. */ + mutable osl::Mutex maMtxCacheAccess; + + /** Mutex for source document meta-data access. */ + mutable osl::Mutex maMtxSrcFiles; + /** cache of referenced ranges and names from source documents. */ ScExternalRefCache maRefCache; @@ -798,7 +807,6 @@ private: * external document identifiers. */ std::vector<SrcFileData> maSrcFiles; - mutable osl::Mutex maMtxSrcFiles; /** Status whether in reference marking state. See isInReferenceMarking(). */ bool mbInReferenceMarking:1; diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index 5a7d8e2..95e4ef0 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -2914,7 +2914,7 @@ bool ScCompiler::IsExternalNamedRange( const OUString& rSymbol ) pRefMgr->convertToAbsName(aTmp); aFile = aTmp; sal_uInt16 nFileId = pRefMgr->getExternalFileId(aFile); - if (!pRefMgr->getRangeNameTokens(nFileId, aName).get()) + if (!pRefMgr->isValidRangeName(nFileId, aName)) // range name doesn't exist in the source document. return false; diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx index 1561cbb..9c07fd7 100644 --- a/sc/source/ui/docshell/externalrefmgr.cxx +++ b/sc/source/ui/docshell/externalrefmgr.cxx @@ -710,6 +710,18 @@ void ScExternalRefCache::setRangeNameTokens(sal_uInt16 nFileId, const OUString& pDoc->maRealRangeNameMap.insert(NamePairMap::value_type(aUpperName, rName)); } +bool ScExternalRefCache::isValidRangeName(sal_uInt16 nFileId, const OUString& rName) const +{ + osl::MutexGuard aGuard(&maMtxDocs); + + DocItem* pDoc = getDocItem(nFileId); + if (!pDoc) + return false; + + const RangeNameMap& rMap = pDoc->maRangeNames; + return rMap.count(rName) > 0; +} + void ScExternalRefCache::setCellData(sal_uInt16 nFileId, const OUString& rTabName, SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uLong nFmtIndex) { @@ -1747,6 +1759,8 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken( sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rCell, const ScAddress* pCurPos, SCTAB* pTab, ScExternalRefCache::CellFormat* pFmt) { + osl::MutexGuard aGuard(&maMtxCacheAccess); + if (pCurPos) insertRefCell(nFileId, *pCurPos); @@ -1839,6 +1853,8 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken( ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange, const ScAddress* pCurPos) { + osl::MutexGuard aGuard(&maMtxCacheAccess); + if (pCurPos) insertRefCell(nFileId, *pCurPos); @@ -1885,6 +1901,8 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens( ScExternalRefCache::TokenArrayRef ScExternalRefManager::getRangeNameTokens( sal_uInt16 nFileId, const OUString& rName, const ScAddress* pCurPos) { + osl::MutexGuard aGuard(&maMtxCacheAccess); + if (pCurPos) insertRefCell(nFileId, *pCurPos); @@ -1924,6 +1942,42 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getRangeNameTokens( return pArray; } +namespace { + +bool hasRangeName(ScDocument& rDoc, const OUString& rName) +{ + ScRangeName* pExtNames = rDoc.GetRangeName(); + OUString aUpperName = ScGlobal::pCharClass->uppercase(rName); + const ScRangeData* pRangeData = pExtNames->findByUpperName(aUpperName); + return pRangeData != NULL; +} + +} + +bool ScExternalRefManager::isValidRangeName(sal_uInt16 nFileId, const OUString& rName) +{ + osl::MutexGuard aGuard(&maMtxCacheAccess); + + maybeLinkExternalFile(nFileId); + ScDocument* pSrcDoc = getInMemorySrcDocument(nFileId); + if (pSrcDoc) + { + // Only check the presence of the name. + return hasRangeName(*pSrcDoc, rName); + } + + if (maRefCache.isValidRangeName(nFileId, rName)) + // Range name is cached. + return true; + + pSrcDoc = getSrcDocument(nFileId); + if (!pSrcDoc) + // failed to load document from disk. + return false; + + return hasRangeName(*pSrcDoc, rName); +} + void ScExternalRefManager::refreshAllRefCells(sal_uInt16 nFileId) { RefCellMap::iterator itrFile = maRefCells.find(nFileId); commit c30e006e0633be5eba0a86a8f54bdf9807fe4f91 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Tue Nov 5 17:10:24 2013 -0500 Add mutex for external source document meta-data container. These get updated from reference parser code (ScAddress, ScRange etc) which may be run from multiple threads. Change-Id: I5a1aaa4b51d9b9fb032458eb5e89f0652887184e diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx index c5a73ae..6156abb 100644 --- a/sc/inc/externalrefmgr.hxx +++ b/sc/inc/externalrefmgr.hxx @@ -793,8 +793,12 @@ private: NumFmtMap maNumFormatMap; - /** original source file index. */ - ::std::vector<SrcFileData> maSrcFiles; + /** + * List of external source document meta-data, used to keep track of + * external document identifiers. + */ + std::vector<SrcFileData> maSrcFiles; + mutable osl::Mutex maMtxSrcFiles; /** Status whether in reference marking state. See isInReferenceMarking(). */ bool mbInReferenceMarking:1; diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx index f7d026b..1561cbb 100644 --- a/sc/source/ui/docshell/externalrefmgr.cxx +++ b/sc/source/ui/docshell/externalrefmgr.cxx @@ -1594,6 +1594,7 @@ void ScExternalRefManager::getAllCachedNumberFormats(vector<sal_uInt32>& rNumFmt sal_uInt16 ScExternalRefManager::getExternalFileCount() const { + osl::MutexGuard aGuard(&maMtxSrcFiles); return static_cast< sal_uInt16 >( maSrcFiles.size() ); } @@ -2360,6 +2361,7 @@ void ScExternalRefManager::SrcFileData::maybeCreateRealFileName(const OUString& void ScExternalRefManager::maybeCreateRealFileName(sal_uInt16 nFileId) { + osl::MutexGuard aGuard(&maMtxSrcFiles); if (nFileId >= maSrcFiles.size()) return; @@ -2404,6 +2406,8 @@ void ScExternalRefManager::convertToAbsName(OUString& rFile) const sal_uInt16 ScExternalRefManager::getExternalFileId(const OUString& rFile) { + osl::MutexGuard aGuard(&maMtxSrcFiles); + vector<SrcFileData>::const_iterator itrBeg = maSrcFiles.begin(), itrEnd = maSrcFiles.end(); vector<SrcFileData>::const_iterator itr = find_if(itrBeg, itrEnd, FindSrcFileByName(rFile)); if (itr != itrEnd) @@ -2420,6 +2424,8 @@ sal_uInt16 ScExternalRefManager::getExternalFileId(const OUString& rFile) const OUString* ScExternalRefManager::getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal) { + osl::MutexGuard aGuard(&maMtxSrcFiles); + if (nFileId >= maSrcFiles.size()) return NULL; @@ -2436,11 +2442,14 @@ const OUString* ScExternalRefManager::getExternalFileName(sal_uInt16 nFileId, bo bool ScExternalRefManager::hasExternalFile(sal_uInt16 nFileId) const { + osl::MutexGuard aGuard(&maMtxSrcFiles); return nFileId < maSrcFiles.size(); } bool ScExternalRefManager::hasExternalFile(const OUString& rFile) const { + osl::MutexGuard aGuard(&maMtxSrcFiles); + vector<SrcFileData>::const_iterator itrBeg = maSrcFiles.begin(), itrEnd = maSrcFiles.end(); vector<SrcFileData>::const_iterator itr = find_if(itrBeg, itrEnd, FindSrcFileByName(rFile)); return itr != itrEnd; @@ -2539,6 +2548,8 @@ void ScExternalRefManager::breakLink(sal_uInt16 nFileId) void ScExternalRefManager::switchSrcFile(sal_uInt16 nFileId, const OUString& rNewFile, const OUString& rNewFilter) { + osl::MutexGuard aGuard(&maMtxSrcFiles); + maSrcFiles[nFileId].maFileName = rNewFile; maSrcFiles[nFileId].maRelativeName = OUString(); maSrcFiles[nFileId].maRealFileName = OUString(); @@ -2553,6 +2564,8 @@ void ScExternalRefManager::switchSrcFile(sal_uInt16 nFileId, const OUString& rNe void ScExternalRefManager::setRelativeFileName(sal_uInt16 nFileId, const OUString& rRelUrl) { + osl::MutexGuard aGuard(&maMtxSrcFiles); + if (nFileId >= maSrcFiles.size()) return; maSrcFiles[nFileId].maRelativeName = rRelUrl; @@ -2560,6 +2573,8 @@ void ScExternalRefManager::setRelativeFileName(sal_uInt16 nFileId, const OUStrin void ScExternalRefManager::setFilterData(sal_uInt16 nFileId, const OUString& rFilterName, const OUString& rOptions) { + osl::MutexGuard aGuard(&maMtxSrcFiles); + if (nFileId >= maSrcFiles.size()) return; maSrcFiles[nFileId].maFilterName = rFilterName; @@ -2578,11 +2593,13 @@ void ScExternalRefManager::clear() bool ScExternalRefManager::hasExternalData() const { + osl::MutexGuard aGuard(&maMtxSrcFiles); return !maSrcFiles.empty(); } void ScExternalRefManager::resetSrcFileData(const OUString& rBaseFileUrl) { + osl::MutexGuard aGuard(&maMtxSrcFiles); for (vector<SrcFileData>::iterator itr = maSrcFiles.begin(), itrEnd = maSrcFiles.end(); itr != itrEnd; ++itr) { @@ -2598,6 +2615,7 @@ void ScExternalRefManager::resetSrcFileData(const OUString& rBaseFileUrl) void ScExternalRefManager::updateAbsAfterLoad() { + osl::MutexGuard aGuard(&maMtxSrcFiles); OUString aOwn( getOwnDocumentName() ); for (vector<SrcFileData>::iterator itr = maSrcFiles.begin(), itrEnd = maSrcFiles.end(); itr != itrEnd; ++itr) commit aa497840b4c378f4f8d65a9c7c9daec8463e3a21 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Tue Nov 5 16:55:54 2013 -0500 Make this method private as it is used only internally. Change-Id: I752c9a6bcd7f5b057cd517a9630a975009d6fb0d diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx index 21e4e75a..c5a73ae 100644 --- a/sc/inc/externalrefmgr.hxx +++ b/sc/inc/externalrefmgr.hxx @@ -669,14 +669,6 @@ public: */ bool isFileLoadable(const OUString& rFile) const; - /** - * If in maUnsavedDocShells move it to maDocShells and create a correct - * external reference entry - * - * @param Pointer to the newly saved DocumentShell - */ - void transformUnsavedRefToSavedRef( SfxObjectShell* pShell ); - virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); /** @@ -762,6 +754,13 @@ private: sal_uInt32 getMappedNumberFormat(sal_uInt16 nFileId, sal_uInt32 nNumFmt, const ScDocument* pSrcDoc); + /** + * If in maUnsavedDocShells move it to maDocShells and create a correct + * external reference entry + * + * @param Pointer to the newly saved DocumentShell + */ + void transformUnsavedRefToSavedRef( SfxObjectShell* pShell ); private: ScDocument* mpDoc; commit ba5bb8c0cad11d9182065d7ca4d390ee177d670b Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Tue Nov 5 16:49:55 2013 -0500 Set mutex for external ref cache content. Change-Id: Id00c0e553e08740df8d9b7eef19407e1b0d3f022 diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx index 9ade21d..21e4e75a 100644 --- a/sc/inc/externalrefmgr.hxx +++ b/sc/inc/externalrefmgr.hxx @@ -32,6 +32,7 @@ #include "types.hxx" #include "rangelst.hxx" #include "formula/token.hxx" +#include "osl/mutex.hxx" #include <boost/unordered_map.hpp> #include <boost/unordered_set.hpp> @@ -340,6 +341,7 @@ private: DocItem* getDocItem(sal_uInt16 nFileId) const; private: + mutable osl::Mutex maMtxDocs; mutable DocDataType maDocs; }; @@ -682,7 +684,7 @@ public: * * @return true if the document still contains references to an unsaved file */ - bool containsUnsavedReferences() { return !maUnsavedDocShells.empty(); } + bool containsUnsavedReferences() const { return !maUnsavedDocShells.empty(); } void insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell); diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx index 676352a..f7d026b 100644 --- a/sc/source/ui/docshell/externalrefmgr.cxx +++ b/sc/source/ui/docshell/externalrefmgr.cxx @@ -494,6 +494,8 @@ ScExternalRefCache::~ScExternalRefCache() {} const OUString* ScExternalRefCache::getRealTableName(sal_uInt16 nFileId, const OUString& rTabName) const { + osl::MutexGuard aGuard(&maMtxDocs); + DocDataType::const_iterator itrDoc = maDocs.find(nFileId); if (itrDoc == maDocs.end()) { @@ -515,6 +517,8 @@ const OUString* ScExternalRefCache::getRealTableName(sal_uInt16 nFileId, const O const OUString* ScExternalRefCache::getRealRangeName(sal_uInt16 nFileId, const OUString& rRangeName) const { + osl::MutexGuard aGuard(&maMtxDocs); + DocDataType::const_iterator itrDoc = maDocs.find(nFileId); if (itrDoc == maDocs.end()) { @@ -535,6 +539,8 @@ const OUString* ScExternalRefCache::getRealRangeName(sal_uInt16 nFileId, const O ScExternalRefCache::TokenRef ScExternalRefCache::getCellData( sal_uInt16 nFileId, const OUString& rTabName, SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex) { + osl::MutexGuard aGuard(&maMtxDocs); + DocDataType::const_iterator itrDoc = maDocs.find(nFileId); if (itrDoc == maDocs.end()) { @@ -564,6 +570,8 @@ ScExternalRefCache::TokenRef ScExternalRefCache::getCellData( ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange) { + osl::MutexGuard aGuard(&maMtxDocs); + DocDataType::iterator itrDoc = maDocs.find(nFileId); if (itrDoc == maDocs.end()) // specified document is not cached. @@ -673,6 +681,8 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData( ScExternalRefCache::TokenArrayRef ScExternalRefCache::getRangeNameTokens(sal_uInt16 nFileId, const OUString& rName) { + osl::MutexGuard aGuard(&maMtxDocs); + DocItem* pDoc = getDocItem(nFileId); if (!pDoc) return TokenArrayRef(); @@ -688,6 +698,8 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getRangeNameTokens(sal_uIn void ScExternalRefCache::setRangeNameTokens(sal_uInt16 nFileId, const OUString& rName, TokenArrayRef pArray) { + osl::MutexGuard aGuard(&maMtxDocs); + DocItem* pDoc = getDocItem(nFileId); if (!pDoc) return; @@ -912,6 +924,8 @@ SCsTAB ScExternalRefCache::getTabSpan( sal_uInt16 nFileId, const OUString& rStar void ScExternalRefCache::getAllNumberFormats(vector<sal_uInt32>& rNumFmts) const { + osl::MutexGuard aGuard(&maMtxDocs); + using ::std::sort; using ::std::unique; @@ -986,6 +1000,8 @@ bool ScExternalRefCache::setCacheTableReferenced( sal_uInt16 nFileId, const OUSt void ScExternalRefCache::setAllCacheTableReferencedStati( bool bReferenced ) { + osl::MutexGuard aGuard(&maMtxDocs); + if (bReferenced) { maReferenced.reset(0); @@ -1174,11 +1190,14 @@ ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nF void ScExternalRefCache::clearCache(sal_uInt16 nFileId) { + osl::MutexGuard aGuard(&maMtxDocs); maDocs.erase(nFileId); } ScExternalRefCache::DocItem* ScExternalRefCache::getDocItem(sal_uInt16 nFileId) const { + osl::MutexGuard aGuard(&maMtxDocs); + using ::std::pair; DocDataType::iterator itrDoc = maDocs.find(nFileId); if (itrDoc == maDocs.end()) commit 16880ec68c3d894e721cc98675a67ab2109dc713 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Tue Nov 5 16:25:16 2013 -0500 Use atomic increment and decrement for thread-safe reference count. Change-Id: I630298b1c37a6d23c1aa17aabc1c9b2dcb48608a diff --git a/include/formula/token.hxx b/include/formula/token.hxx index 8fa8708..ea91e2c 100644 --- a/include/formula/token.hxx +++ b/include/formula/token.hxx @@ -29,6 +29,7 @@ #include "formula/formuladllapi.h" #include "formula/types.hxx" #include "svl/sharedstring.hxx" +#include "osl/interlck.h" namespace formula { @@ -107,12 +108,18 @@ public: bool IsFunction() const; // pure functions, no operators bool IsExternalRef() const; sal_uInt8 GetParamCount() const; - inline void IncRef() const { nRefCnt++; } - inline void DecRef() const - { - if (!--nRefCnt) - const_cast<FormulaToken*>(this)->Delete(); - } + + inline void IncRef() const + { + osl_atomic_increment(&nRefCnt); + } + + inline void DecRef() const + { + if (!osl_atomic_decrement(&nRefCnt)) + const_cast<FormulaToken*>(this)->Delete(); + } + inline sal_uInt16 GetRef() const { return nRefCnt; } inline OpCode GetOpCode() const { return eOp; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits