diff options
author | Michael Stahl <mstahl@redhat.com> | 2014-08-19 23:29:32 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2014-08-20 16:40:16 +0200 |
commit | 14eb485c5c62a4f745b24a3798f313623f283e55 (patch) | |
tree | fab271ff05b8bb802a66b714b32171cf6f04099e /sw | |
parent | 1e28d7901dbebf77f75e5770d11a49fef036976c (diff) |
i#107771: sw: implement thread-safe instance caching for SwXReferenceMark
Change-Id: I4f3b6789dde053ca913e12233b20d45dfe50c7ec
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/fmtrfmrk.hxx | 16 | ||||
-rw-r--r-- | sw/inc/unocoll.hxx | 1 | ||||
-rw-r--r-- | sw/source/core/inc/unorefmark.hxx | 11 | ||||
-rw-r--r-- | sw/source/core/txtnode/atrref.cxx | 9 | ||||
-rw-r--r-- | sw/source/core/unocore/unocoll.cxx | 19 | ||||
-rw-r--r-- | sw/source/core/unocore/unocrsrhelper.cxx | 4 | ||||
-rw-r--r-- | sw/source/core/unocore/unoportenum.cxx | 2 | ||||
-rw-r--r-- | sw/source/core/unocore/unorefmk.cxx | 35 |
8 files changed, 59 insertions, 38 deletions
diff --git a/sw/inc/fmtrfmrk.hxx b/sw/inc/fmtrfmrk.hxx index d8e807d18381..4825699a6fae 100644 --- a/sw/inc/fmtrfmrk.hxx +++ b/sw/inc/fmtrfmrk.hxx @@ -20,10 +20,15 @@ #define INCLUDED_SW_INC_FMTRFMRK_HXX #include <rtl/ustring.hxx> +#include <cppuhelper/weakref.hxx> #include <svl/poolitem.hxx> #include <calbck.hxx> +namespace com { namespace sun { namespace star { + namespace text { class XTextContent; } +} } } + class SwTxtRefMark; // ATT_REFMARK @@ -39,6 +44,8 @@ class SwFmtRefMark SwFmtRefMark& operator=(const SwFmtRefMark& rRefMark); OUString aRefName; + css::uno::WeakReference<css::text::XTextContent> m_wXReferenceMark; + public: SwFmtRefMark( const OUString& rTxt ); SwFmtRefMark( const SwFmtRefMark& rRefMark ); @@ -48,6 +55,10 @@ public: virtual bool operator==( const SfxPoolItem& ) const SAL_OVERRIDE; virtual SfxPoolItem* Clone( SfxItemPool* pPool = 0 ) const SAL_OVERRIDE; + // SwClient + virtual void Modify(SfxPoolItem const* pOld, SfxPoolItem const* pNew) + SAL_OVERRIDE; + void InvalidateRefMark(); const SwTxtRefMark *GetTxtRefMark() const { return pTxtAttr; } @@ -55,6 +66,11 @@ public: inline OUString &GetRefName() { return aRefName; } inline const OUString &GetRefName() const { return aRefName; } + + css::uno::WeakReference<css::text::XTextContent> const& GetXRefMark() const + { return m_wXReferenceMark; } + void SetXRefMark(css::uno::Reference<css::text::XTextContent> const& xMark) + { m_wXReferenceMark = xMark; } }; #endif diff --git a/sw/inc/unocoll.hxx b/sw/inc/unocoll.hxx index eb55c8116f84..d5c97bb44d21 100644 --- a/sw/inc/unocoll.hxx +++ b/sw/inc/unocoll.hxx @@ -521,7 +521,6 @@ public: virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw( ::com::sun::star::uno::RuntimeException, std::exception ) SAL_OVERRIDE; virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw( ::com::sun::star::uno::RuntimeException, std::exception ) SAL_OVERRIDE; - static SwXReferenceMark* GetObject( SwDoc* pDoc, const SwFmtRefMark* pMark ); }; #endif diff --git a/sw/source/core/inc/unorefmark.hxx b/sw/source/core/inc/unorefmark.hxx index 78dac4b0207c..73d8d410d97d 100644 --- a/sw/source/core/inc/unorefmark.hxx +++ b/sw/source/core/inc/unorefmark.hxx @@ -53,15 +53,12 @@ private: virtual ~SwXReferenceMark(); -public: - SwXReferenceMark(SwDoc *const pDoc, SwFmtRefMark *const pMark); - static SwXReferenceMark * - CreateXReferenceMark(SwDoc & rDoc, SwFmtRefMark & rMarkFmt); - /// may return 0 - static SwXReferenceMark * - GetReferenceMark(SwModify const& rUnoCB, SwFmtRefMark const& rMarkFmt); +public: + + static css::uno::Reference<css::text::XTextContent> + CreateXReferenceMark(SwDoc & rDoc, SwFmtRefMark * pMarkFmt); static const ::com::sun::star::uno::Sequence< sal_Int8 >& getUnoTunnelId(); diff --git a/sw/source/core/txtnode/atrref.cxx b/sw/source/core/txtnode/atrref.cxx index 1b9fe63d0413..35f338b30e48 100644 --- a/sw/source/core/txtnode/atrref.cxx +++ b/sw/source/core/txtnode/atrref.cxx @@ -55,6 +55,15 @@ SfxPoolItem* SwFmtRefMark::Clone( SfxItemPool* ) const return new SwFmtRefMark( *this ); } +void SwFmtRefMark::Modify(SfxPoolItem const* pOld, SfxPoolItem const* pNew) +{ + NotifyClients(pOld, pNew); + if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which())) + { // invalidate cached UNO object + SetXRefMark(css::uno::Reference<css::text::XTextContent>(0)); + } +} + void SwFmtRefMark::InvalidateRefMark() { SwPtrMsgPoolItem const item(RES_REMOVE_UNO_OBJECT, diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx index d9540975b365..4f3a825330b3 100644 --- a/sw/source/core/unocore/unocoll.cxx +++ b/sw/source/core/unocore/unocoll.cxx @@ -669,7 +669,7 @@ uno::Reference< uno::XInterface > SwXServiceProvider::MakeInstance(sal_uInt16 break; case SW_SERVICE_REFERENCE_MARK : - xRet = (cppu::OWeakObject*)new SwXReferenceMark(0, 0); + xRet = SwXReferenceMark::CreateXReferenceMark(*pDoc, 0); break; case SW_SERVICE_STYLE_CHARACTER_STYLE: case SW_SERVICE_STYLE_PARAGRAPH_STYLE: @@ -1912,10 +1912,11 @@ uno::Any SwXReferenceMarks::getByIndex(sal_Int32 nIndex) uno::Reference< XTextContent > xRef; if(0 <= nIndex && nIndex < USHRT_MAX) { - const SwFmtRefMark* pMark = GetDoc()->GetRefMark( (sal_uInt16) nIndex ); + SwFmtRefMark *const pMark = const_cast<SwFmtRefMark*>( + GetDoc()->GetRefMark(static_cast<sal_uInt16>(nIndex))); if(pMark) { - xRef = SwXReferenceMarks::GetObject( GetDoc(), pMark ); + xRef = SwXReferenceMark::CreateXReferenceMark(*GetDoc(), pMark); aRet.setValue(&xRef, cppu::UnoType<XTextContent>::get()); } } @@ -1931,10 +1932,12 @@ uno::Any SwXReferenceMarks::getByName(const OUString& rName) uno::Any aRet; if(IsValid()) { - const SwFmtRefMark* pMark = GetDoc()->GetRefMark(rName); + SwFmtRefMark *const pMark = + const_cast<SwFmtRefMark*>(GetDoc()->GetRefMark(rName)); if(pMark) { - uno::Reference< XTextContent > xRef = SwXReferenceMarks::GetObject( GetDoc(), pMark ); + uno::Reference<XTextContent> const xRef = + SwXReferenceMark::CreateXReferenceMark(*GetDoc(), pMark); aRet.setValue(&xRef, cppu::UnoType<XTextContent>::get()); } else @@ -1984,12 +1987,6 @@ sal_Bool SwXReferenceMarks::hasElements(void) throw( uno::RuntimeException, std: return 0 != GetDoc()->GetRefMarks(); } -SwXReferenceMark* SwXReferenceMarks::GetObject( SwDoc* pDoc, const SwFmtRefMark* pMark ) -{ - return SwXReferenceMark::CreateXReferenceMark( - *pDoc, *const_cast<SwFmtRefMark*>(pMark)); -} - void SwUnoCollection::Invalidate() { bObjectValid = false; diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx index 71610597968c..a80c496589bd 100644 --- a/sw/source/core/unocore/unocrsrhelper.cxx +++ b/sw/source/core/unocore/unocrsrhelper.cxx @@ -632,7 +632,9 @@ bool getCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry if( pAny ) { // hmm... can only return 1 here const SwFmtRefMark& rRef = (*marks.begin())->GetRefMark(); - uno::Reference< XTextContent > xRef = SwXReferenceMarks::GetObject( rPam.GetDoc(), &rRef ); + uno::Reference<XTextContent> const xRef = + SwXReferenceMark::CreateXReferenceMark(*rPam.GetDoc(), + const_cast<SwFmtRefMark*>(&rRef)); pAny->setValue(&xRef, cppu::UnoType<XTextContent>::get()); } } diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx index 3b5cba4d6a68..5e02a0200b1e 100644 --- a/sw/source/core/unocore/unoportenum.cxx +++ b/sw/source/core/unocore/unoportenum.cxx @@ -496,7 +496,7 @@ lcl_CreateRefMarkPortion( Reference<XTextContent> xContent; if (!xContent.is()) { - xContent = new SwXReferenceMark(pDoc, &rRefMark); + xContent = SwXReferenceMark::CreateXReferenceMark(*pDoc, &rRefMark); } SwXTextPortion* pPortion = 0; diff --git a/sw/source/core/unocore/unorefmk.cxx b/sw/source/core/unocore/unorefmk.cxx index abcb746843ce..10f0a067b872 100644 --- a/sw/source/core/unocore/unorefmk.cxx +++ b/sw/source/core/unocore/unorefmk.cxx @@ -108,25 +108,26 @@ SwXReferenceMark::~SwXReferenceMark() { } -SwXReferenceMark * -SwXReferenceMark::GetReferenceMark( - SwModify const& /*rUnoCB*/, SwFmtRefMark const& /*rMarkFmt*/) -{ - // #i105557#: do not iterate over the registered clients: race condition - // to do this properly requires the SwXReferenceMark to register at the - // SwFmtRefMark directly, not at the unocallback - return 0; -} - -SwXReferenceMark * +uno::Reference<text::XTextContent> SwXReferenceMark::CreateXReferenceMark( - SwDoc & rDoc, SwFmtRefMark & rMarkFmt) + SwDoc & rDoc, SwFmtRefMark *const pMarkFmt) { - SwXReferenceMark *const pXMark( - GetReferenceMark(rMarkFmt, rMarkFmt) ); - return (pXMark) - ? pXMark - : new SwXReferenceMark(&rDoc, &rMarkFmt); + // i#105557: do not iterate over the registered clients: race condition + uno::Reference<text::XTextContent> xMark; + if (pMarkFmt) + { + xMark = pMarkFmt->GetXRefMark(); + } + if (!xMark.is()) + { + SwXReferenceMark *const pMark(new SwXReferenceMark(&rDoc, pMarkFmt)); + xMark.set(pMark); + if (pMarkFmt) + { + pMarkFmt->SetXRefMark(xMark); + } + } + return xMark; } namespace |