Kaydet (Commit) 9b0b29ea authored tarafından Luboš Luňák's avatar Luboš Luňák Kaydeden (comit) Michael Meeks

avoid race condition in DocumentLinkManager::getLinkManager()

Change-Id: Ib8ffcf32e4a4dc80539828611adabb3beef1dafa
Reviewed-on: https://gerrit.libreoffice.org/55764
Tested-by: Jenkins
Reviewed-by: 's avatarMichael Meeks <michael.meeks@collabora.com>
üst 3020fb15
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 . * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/ */
#include <comphelper/doublecheckedinit.hxx>
#include <documentlinkmgr.hxx> #include <documentlinkmgr.hxx>
#include <datastream.hxx> #include <datastream.hxx>
#include <ddelink.hxx> #include <ddelink.hxx>
...@@ -36,7 +37,7 @@ struct DocumentLinkManagerImpl ...@@ -36,7 +37,7 @@ struct DocumentLinkManagerImpl
{ {
SfxObjectShell* mpShell; SfxObjectShell* mpShell;
std::unique_ptr<DataStream, o3tl::default_delete<DataStream>> mpDataStream; std::unique_ptr<DataStream, o3tl::default_delete<DataStream>> mpDataStream;
std::unique_ptr<sfx2::LinkManager> mpLinkManager; std::atomic<sfx2::LinkManager*> mpLinkManager;
DocumentLinkManagerImpl(const DocumentLinkManagerImpl&) = delete; DocumentLinkManagerImpl(const DocumentLinkManagerImpl&) = delete;
const DocumentLinkManagerImpl& operator=(const DocumentLinkManagerImpl&) = delete; const DocumentLinkManagerImpl& operator=(const DocumentLinkManagerImpl&) = delete;
...@@ -47,15 +48,17 @@ struct DocumentLinkManagerImpl ...@@ -47,15 +48,17 @@ struct DocumentLinkManagerImpl
~DocumentLinkManagerImpl() ~DocumentLinkManagerImpl()
{ {
// Shared base links // Shared base links
if (mpLinkManager) sfx2::LinkManager* linkManager = mpLinkManager;
if (linkManager)
{ {
sfx2::SvLinkSources aTemp = mpLinkManager->GetServers(); sfx2::SvLinkSources aTemp = linkManager->GetServers();
for (sfx2::SvLinkSources::const_iterator it = aTemp.begin(); it != aTemp.end(); ++it) for (sfx2::SvLinkSources::const_iterator it = aTemp.begin(); it != aTemp.end(); ++it)
(*it)->Closed(); (*it)->Closed();
if (!mpLinkManager->GetLinks().empty()) if (!linkManager->GetLinks().empty())
mpLinkManager->Remove(0, mpLinkManager->GetLinks().size()); linkManager->Remove(0, linkManager->GetLinks().size());
} }
delete linkManager;
} }
}; };
...@@ -83,23 +86,25 @@ const DataStream* DocumentLinkManager::getDataStream() const ...@@ -83,23 +86,25 @@ const DataStream* DocumentLinkManager::getDataStream() const
sfx2::LinkManager* DocumentLinkManager::getLinkManager( bool bCreate ) sfx2::LinkManager* DocumentLinkManager::getLinkManager( bool bCreate )
{ {
if (!mpImpl->mpLinkManager && bCreate && mpImpl->mpShell) if (bCreate && mpImpl->mpShell)
mpImpl->mpLinkManager.reset(new sfx2::LinkManager(mpImpl->mpShell)); return comphelper::doubleCheckedInit( mpImpl->mpLinkManager,
return mpImpl->mpLinkManager.get(); [this]() { return new sfx2::LinkManager(mpImpl->mpShell); } );
return mpImpl->mpLinkManager;
} }
const sfx2::LinkManager* DocumentLinkManager::getExistingLinkManager() const const sfx2::LinkManager* DocumentLinkManager::getExistingLinkManager() const
{ {
return mpImpl->mpLinkManager.get(); return mpImpl->mpLinkManager;
} }
bool DocumentLinkManager::idleCheckLinks() bool DocumentLinkManager::idleCheckLinks()
{ {
if (!mpImpl->mpLinkManager) sfx2::LinkManager* pMgr = mpImpl->mpLinkManager;
if (!pMgr)
return false; return false;
bool bAnyLeft = false; bool bAnyLeft = false;
const sfx2::SvBaseLinks& rLinks = mpImpl->mpLinkManager->GetLinks(); const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
for (const auto & rLink : rLinks) for (const auto & rLink : rLinks)
{ {
sfx2::SvBaseLink* pBase = rLink.get(); sfx2::SvBaseLink* pBase = rLink.get();
...@@ -127,10 +132,11 @@ bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks() const ...@@ -127,10 +132,11 @@ bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks() const
bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const
{ {
if (!mpImpl->mpLinkManager) sfx2::LinkManager* pMgr = mpImpl->mpLinkManager;
if (!pMgr)
return false; return false;
const sfx2::SvBaseLinks& rLinks = mpImpl->mpLinkManager->GetLinks(); const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
for (const auto & rLink : rLinks) for (const auto & rLink : rLinks)
{ {
sfx2::SvBaseLink* pBase = rLink.get(); sfx2::SvBaseLink* pBase = rLink.get();
...@@ -147,10 +153,10 @@ bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, boo ...@@ -147,10 +153,10 @@ bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, boo
bool DocumentLinkManager::updateDdeOrOleOrWebServiceLinks(weld::Window* pWin) bool DocumentLinkManager::updateDdeOrOleOrWebServiceLinks(weld::Window* pWin)
{ {
if (!mpImpl->mpLinkManager) sfx2::LinkManager* pMgr = mpImpl->mpLinkManager;
if (!pMgr)
return false; return false;
sfx2::LinkManager* pMgr = mpImpl->mpLinkManager.get();
const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks(); const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
// If the update takes longer, reset all values so that nothing // If the update takes longer, reset all values so that nothing
...@@ -210,10 +216,10 @@ bool DocumentLinkManager::updateDdeOrOleOrWebServiceLinks(weld::Window* pWin) ...@@ -210,10 +216,10 @@ bool DocumentLinkManager::updateDdeOrOleOrWebServiceLinks(weld::Window* pWin)
void DocumentLinkManager::updateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem ) void DocumentLinkManager::updateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem )
{ {
if (!mpImpl->mpLinkManager) sfx2::LinkManager* pMgr = mpImpl->mpLinkManager;
if (!pMgr)
return; return;
sfx2::LinkManager* pMgr = mpImpl->mpLinkManager.get();
const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks(); const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
for (const auto & rLink : rLinks) for (const auto & rLink : rLinks)
...@@ -235,11 +241,12 @@ void DocumentLinkManager::updateDdeLink( const OUString& rAppl, const OUString& ...@@ -235,11 +241,12 @@ void DocumentLinkManager::updateDdeLink( const OUString& rAppl, const OUString&
size_t DocumentLinkManager::getDdeLinkCount() const size_t DocumentLinkManager::getDdeLinkCount() const
{ {
if (!mpImpl->mpLinkManager) sfx2::LinkManager* pMgr = mpImpl->mpLinkManager;
if (!pMgr)
return 0; return 0;
size_t nDdeCount = 0; size_t nDdeCount = 0;
const sfx2::SvBaseLinks& rLinks = mpImpl->mpLinkManager->GetLinks(); const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
for (const auto & rLink : rLinks) for (const auto & rLink : rLinks)
{ {
::sfx2::SvBaseLink* pBase = rLink.get(); ::sfx2::SvBaseLink* pBase = rLink.get();
...@@ -255,10 +262,11 @@ size_t DocumentLinkManager::getDdeLinkCount() const ...@@ -255,10 +262,11 @@ size_t DocumentLinkManager::getDdeLinkCount() const
void DocumentLinkManager::disconnectDdeLinks() void DocumentLinkManager::disconnectDdeLinks()
{ {
if (!mpImpl->mpLinkManager) sfx2::LinkManager* pMgr = mpImpl->mpLinkManager;
if (!pMgr)
return; return;
const sfx2::SvBaseLinks& rLinks = mpImpl->mpLinkManager->GetLinks(); const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
for (const auto & rLink : rLinks) for (const auto & rLink : rLinks)
{ {
::sfx2::SvBaseLink* pBase = rLink.get(); ::sfx2::SvBaseLink* pBase = rLink.get();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment