diff options
Diffstat (limited to 'comphelper/source/eventattachermgr/eventattachermgr.cxx')
-rw-r--r-- | comphelper/source/eventattachermgr/eventattachermgr.cxx | 145 |
1 files changed, 91 insertions, 54 deletions
diff --git a/comphelper/source/eventattachermgr/eventattachermgr.cxx b/comphelper/source/eventattachermgr/eventattachermgr.cxx index 35e90a8379b0..9a6d4af5afe5 100644 --- a/comphelper/source/eventattachermgr/eventattachermgr.cxx +++ b/comphelper/source/eventattachermgr/eventattachermgr.cxx @@ -21,7 +21,6 @@ #include <o3tl/any.hxx> #include <o3tl/safeint.hxx> -#include <osl/mutex.hxx> #include <osl/diagnose.h> #include <comphelper/eventattachermgr.hxx> #include <comphelper/sequence.hxx> @@ -42,13 +41,15 @@ #include <com/sun/star/script/XEventAttacherManager.hpp> #include <com/sun/star/script/XScriptListener.hpp> #include <cppuhelper/weak.hxx> -#include <comphelper/interfacecontainer3.hxx> +#include <comphelper/interfacecontainer4.hxx> #include <cppuhelper/exc_hlp.hxx> #include <cppuhelper/implbase.hxx> #include <rtl/ref.hxx> #include <deque> +#include <mutex> #include <algorithm> +#include <utility> using namespace com::sun::star::uno; using namespace com::sun::star::io; @@ -57,7 +58,6 @@ using namespace com::sun::star::beans; using namespace com::sun::star::script; using namespace com::sun::star::reflection; using namespace cppu; -using namespace osl; namespace comphelper @@ -84,9 +84,9 @@ class ImplEventAttacherManager { friend class AttacherAllListener_Impl; std::deque< AttacherIndex_Impl > aIndex; - Mutex aLock; + std::mutex m_aMutex; // Container for the ScriptListener - OInterfaceContainerHelper3<XScriptListener> aScriptListeners; + OInterfaceContainerHelper4<XScriptListener> aScriptListeners; // Instance of EventAttacher Reference< XEventAttacher2 > xAttacher; Reference< XComponentContext > mxContext; @@ -116,8 +116,14 @@ public: virtual void SAL_CALL read(const Reference< XObjectInputStream >& InStream) override; private: + void registerScriptEvent(std::unique_lock<std::mutex>&, sal_Int32 Index, const ScriptEventDescriptor& ScriptEvent); + void registerScriptEvents(std::unique_lock<std::mutex>&, sal_Int32 Index, const Sequence< ScriptEventDescriptor >& ScriptEvents); + void attach(std::unique_lock<std::mutex>&, sal_Int32 Index, const Reference< XInterface >& Object, const Any& Helper); + void detach(std::unique_lock<std::mutex>&, sal_Int32 nIndex, const Reference< XInterface >& xObject); + void insertEntry(std::unique_lock<std::mutex>&, sal_Int32 Index); + /// @throws Exception - Reference< XIdlReflection > getReflection(); + Reference< XIdlReflection > getReflection(std::unique_lock<std::mutex>&); /** checks if <arg>_nIndex</arg> is a valid index, throws an <type>IllegalArgumentException</type> if not @param _nIndex @@ -140,8 +146,8 @@ class AttacherAllListener_Impl : public WeakImplHelper< XAllListener > /// @throws CannotConvertException void convertToEventReturn( Any & rRet, const Type & rRetType ); public: - AttacherAllListener_Impl( ImplEventAttacherManager* pManager_, const OUString &rScriptType_, - const OUString & rScriptCode_ ); + AttacherAllListener_Impl( ImplEventAttacherManager* pManager_, OUString aScriptType_, + OUString aScriptCode_ ); // Methods of XAllListener virtual void SAL_CALL firing(const AllEventObject& Event) override; @@ -156,12 +162,12 @@ public: AttacherAllListener_Impl::AttacherAllListener_Impl ( ImplEventAttacherManager* pManager_, - const OUString & rScriptType_, - const OUString & rScriptCode_ + OUString aScriptType_, + OUString aScriptCode_ ) : mxManager( pManager_ ) - , aScriptType( rScriptType_ ) - , aScriptCode( rScriptCode_ ) + , aScriptType(std::move( aScriptType_ )) + , aScriptCode(std::move( aScriptCode_ )) { } @@ -179,9 +185,8 @@ void SAL_CALL AttacherAllListener_Impl::firing(const AllEventObject& Event) aScriptEvent.ScriptCode = aScriptCode; // Iterate over all listeners and pass events. - OInterfaceIteratorHelper3 aIt( mxManager->aScriptListeners ); - while( aIt.hasMoreElements() ) - aIt.next()->firing( aScriptEvent ); + std::unique_lock l(mxManager->m_aMutex); + mxManager->aScriptListeners.notifyEach( l, &XScriptListener::firing, aScriptEvent ); } @@ -242,13 +247,17 @@ Any SAL_CALL AttacherAllListener_Impl::approveFiring( const AllEventObject& Even Any aRet; // Iterate over all listeners and pass events. - OInterfaceIteratorHelper3 aIt( mxManager->aScriptListeners ); + std::unique_lock l(mxManager->m_aMutex); + OInterfaceIteratorHelper4 aIt( l, mxManager->aScriptListeners ); while( aIt.hasMoreElements() ) { + // cannot hold lock over call to approveFiring, since it might recurse back into us + l.unlock(); aRet = aIt.next()->approveFiring( aScriptEvent ); + l.lock(); try { - Reference< XIdlClass > xListenerType = mxManager->getReflection()-> + Reference< XIdlClass > xListenerType = mxManager->getReflection(l)-> forName( Event.ListenerType.getTypeName() ); Reference< XIdlMethod > xMeth = xListenerType->getMethod( Event.MethodName ); if( xMeth.is() ) @@ -299,7 +308,7 @@ Any SAL_CALL AttacherAllListener_Impl::approveFiring( const AllEventObject& Even catch (const CannotConvertException&) { // silent ignore conversions errors from a script call - Reference< XIdlClass > xListenerType = mxManager->getReflection()-> + Reference< XIdlClass > xListenerType = mxManager->getReflection(l)-> forName( Event.ListenerType.getTypeName() ); Reference< XIdlMethod > xMeth = xListenerType->getMethod( Event.MethodName ); if( xMeth.is() ) @@ -340,8 +349,7 @@ Reference< XEventAttacherManager > createEventAttacherManager( const Reference< ImplEventAttacherManager::ImplEventAttacherManager( const Reference< XIntrospection > & rIntrospection, const Reference< XComponentContext >& rContext ) - : aScriptListeners( aLock ) - , mxContext( rContext ) + : mxContext( rContext ) , nVersion(0) { if ( rContext.is() ) @@ -362,9 +370,8 @@ ImplEventAttacherManager::ImplEventAttacherManager( const Reference< XIntrospect } } -Reference< XIdlReflection > ImplEventAttacherManager::getReflection() +Reference< XIdlReflection > ImplEventAttacherManager::getReflection(std::unique_lock<std::mutex>&) { - Guard< Mutex > aGuard( aLock ); // Do we already have a service? If not, create one. if( !mxCoreReflection.is() ) { @@ -390,8 +397,17 @@ void SAL_CALL ImplEventAttacherManager::registerScriptEvent const ScriptEventDescriptor& ScriptEvent ) { - Guard< Mutex > aGuard( aLock ); + std::unique_lock l(m_aMutex); + registerScriptEvent(l, nIndex, ScriptEvent); +} +void ImplEventAttacherManager::registerScriptEvent +( + std::unique_lock<std::mutex>&, + sal_Int32 nIndex, + const ScriptEventDescriptor& ScriptEvent +) +{ // Examine the index and apply the array std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); @@ -425,20 +441,29 @@ void SAL_CALL ImplEventAttacherManager::registerScriptEvents const Sequence< ScriptEventDescriptor >& ScriptEvents ) { - Guard< Mutex > aGuard( aLock ); + std::unique_lock l(m_aMutex); + registerScriptEvents(l, nIndex, ScriptEvents); +} +void ImplEventAttacherManager::registerScriptEvents +( + std::unique_lock<std::mutex>& l, + sal_Int32 nIndex, + const Sequence< ScriptEventDescriptor >& ScriptEvents +) +{ // Examine the index and apply the array std::deque< AttachedObject_Impl > aList = implCheckIndex( nIndex )->aObjList; for( const auto& rObj : aList ) - detach( nIndex, rObj.xTarget ); + detach( l, nIndex, rObj.xTarget ); const ScriptEventDescriptor* pArray = ScriptEvents.getConstArray(); sal_Int32 nLen = ScriptEvents.getLength(); for( sal_Int32 i = 0 ; i < nLen ; i++ ) - registerScriptEvent( nIndex, pArray[ i ] ); + registerScriptEvent( l, nIndex, pArray[ i ] ); for( const auto& rObj : aList ) - attach( nIndex, rObj.xTarget, rObj.aHelper ); + attach( l, nIndex, rObj.xTarget, rObj.aHelper ); } @@ -450,18 +475,18 @@ void SAL_CALL ImplEventAttacherManager::revokeScriptEvent const OUString& ToRemoveListenerParam ) { - Guard< Mutex > aGuard( aLock ); + std::unique_lock l(m_aMutex); std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); std::deque< AttachedObject_Impl > aList = aIt->aObjList; for( const auto& rObj : aList ) - detach( nIndex, rObj.xTarget ); + detach( l, nIndex, rObj.xTarget ); - OUString aLstType = ListenerType; - sal_Int32 nLastDot = aLstType.lastIndexOf('.'); - if (nLastDot != -1) - aLstType = aLstType.copy(nLastDot+1); + std::u16string_view aLstType = ListenerType; + size_t nLastDot = aLstType.rfind('.'); + if (nLastDot != std::u16string_view::npos) + aLstType = aLstType.substr(nLastDot+1); auto aEvtIt = std::find_if(aIt->aEventList.begin(), aIt->aEventList.end(), [&aLstType, &EventMethod, &ToRemoveListenerParam](const ScriptEventDescriptor& rEvent) { @@ -473,30 +498,35 @@ void SAL_CALL ImplEventAttacherManager::revokeScriptEvent aIt->aEventList.erase( aEvtIt ); for( const auto& rObj : aList ) - attach( nIndex, rObj.xTarget, rObj.aHelper ); + attach( l, nIndex, rObj.xTarget, rObj.aHelper ); } void SAL_CALL ImplEventAttacherManager::revokeScriptEvents(sal_Int32 nIndex ) { - Guard< Mutex > aGuard( aLock ); + std::unique_lock l(m_aMutex); std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); std::deque< AttachedObject_Impl > aList = aIt->aObjList; for( const auto& rObj : aList ) - detach( nIndex, rObj.xTarget ); + detach( l, nIndex, rObj.xTarget ); aIt->aEventList.clear(); for( const auto& rObj : aList ) - attach( nIndex, rObj.xTarget, rObj.aHelper ); + attach( l, nIndex, rObj.xTarget, rObj.aHelper ); } void SAL_CALL ImplEventAttacherManager::insertEntry(sal_Int32 nIndex) { - Guard< Mutex > aGuard( aLock ); + std::unique_lock l(m_aMutex); if( nIndex < 0 ) throw IllegalArgumentException("negative index", static_cast<cppu::OWeakObject*>(this), 1); + insertEntry(l, nIndex); +} + +void ImplEventAttacherManager::insertEntry(std::unique_lock<std::mutex>&, sal_Int32 nIndex) +{ if ( o3tl::make_unsigned(nIndex) >= aIndex.size() ) aIndex.resize(nIndex+1); @@ -504,15 +534,14 @@ void SAL_CALL ImplEventAttacherManager::insertEntry(sal_Int32 nIndex) aIndex.insert( aIndex.begin() + nIndex, aTmp ); } - void SAL_CALL ImplEventAttacherManager::removeEntry(sal_Int32 nIndex) { - Guard< Mutex > aGuard( aLock ); + std::unique_lock l(m_aMutex); std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); std::deque< AttachedObject_Impl > aList = aIt->aObjList; for( const auto& rObj : aList ) - detach( nIndex, rObj.xTarget ); + detach( l, nIndex, rObj.xTarget ); aIndex.erase( aIt ); } @@ -520,7 +549,7 @@ void SAL_CALL ImplEventAttacherManager::removeEntry(sal_Int32 nIndex) Sequence< ScriptEventDescriptor > SAL_CALL ImplEventAttacherManager::getScriptEvents(sal_Int32 nIndex) { - Guard< Mutex > aGuard( aLock ); + std::unique_lock l(m_aMutex); std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); return comphelper::containerToSequence(aIt->aEventList); } @@ -528,17 +557,21 @@ Sequence< ScriptEventDescriptor > SAL_CALL ImplEventAttacherManager::getScriptEv void SAL_CALL ImplEventAttacherManager::attach(sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any & Helper) { - Guard< Mutex > aGuard( aLock ); + std::unique_lock l(m_aMutex); if( nIndex < 0 || !xObject.is() ) throw IllegalArgumentException("negative index, or null object", static_cast<cppu::OWeakObject*>(this), -1); + attach(l, nIndex, xObject, Helper); +} +void ImplEventAttacherManager::attach(std::unique_lock<std::mutex>& l, sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any & Helper) +{ if( o3tl::make_unsigned(nIndex) >= aIndex.size() ) { // read older files if( nVersion != 1 ) throw IllegalArgumentException(); - insertEntry( nIndex ); - attach( nIndex, xObject, Helper ); + insertEntry( l, nIndex ); + attach( l, nIndex, xObject, Helper ); return; } @@ -584,11 +617,15 @@ void SAL_CALL ImplEventAttacherManager::attach(sal_Int32 nIndex, const Reference void SAL_CALL ImplEventAttacherManager::detach(sal_Int32 nIndex, const Reference< XInterface >& xObject) { - Guard< Mutex > aGuard( aLock ); + std::unique_lock l(m_aMutex); //return; if( nIndex < 0 || o3tl::make_unsigned(nIndex) >= aIndex.size() || !xObject.is() ) throw IllegalArgumentException("bad index or null object", static_cast<cppu::OWeakObject*>(this), 1); + detach(l, nIndex, xObject); +} +void ImplEventAttacherManager::detach(std::unique_lock<std::mutex>&, sal_Int32 nIndex, const Reference< XInterface >& xObject) +{ std::deque< AttacherIndex_Impl >::iterator aCurrentPosition = aIndex.begin() + nIndex; auto aObjIt = std::find_if(aCurrentPosition->aObjList.begin(), aCurrentPosition->aObjList.end(), [&xObject](const AttachedObject_Impl& rObj) { return rObj.xTarget == xObject; }); @@ -616,14 +653,14 @@ void SAL_CALL ImplEventAttacherManager::detach(sal_Int32 nIndex, const Reference void SAL_CALL ImplEventAttacherManager::addScriptListener(const Reference< XScriptListener >& aListener) { - Guard< Mutex > aGuard( aLock ); - aScriptListeners.addInterface( aListener ); + std::unique_lock l(m_aMutex); + aScriptListeners.addInterface( l, aListener ); } void SAL_CALL ImplEventAttacherManager::removeScriptListener(const Reference< XScriptListener >& aListener) { - Guard< Mutex > aGuard( aLock ); - aScriptListeners.removeInterface( aListener ); + std::unique_lock l(m_aMutex); + aScriptListeners.removeInterface( l, aListener ); } @@ -635,7 +672,7 @@ OUString SAL_CALL ImplEventAttacherManager::getServiceName() void SAL_CALL ImplEventAttacherManager::write(const Reference< XObjectOutputStream >& OutStream) { - Guard< Mutex > aGuard( aLock ); + std::unique_lock l(m_aMutex); // Don't run without XMarkableStream Reference< XMarkableStream > xMarkStream( OutStream, UNO_QUERY ); if( !xMarkStream.is() ) @@ -674,7 +711,7 @@ void SAL_CALL ImplEventAttacherManager::write(const Reference< XObjectOutputStre void SAL_CALL ImplEventAttacherManager::read(const Reference< XObjectInputStream >& InStream) { - Guard< Mutex > aGuard( aLock ); + std::unique_lock l(m_aMutex); // Don't run without XMarkableStream Reference< XMarkableStream > xMarkStream( InStream, UNO_QUERY ); if( !xMarkStream.is() ) @@ -695,7 +732,7 @@ void SAL_CALL ImplEventAttacherManager::read(const Reference< XObjectInputStream for( sal_Int32 i = 0 ; i < nItemCount ; i++ ) { - insertEntry( i ); + insertEntry( l, i ); // Read the length of the sequence sal_Int32 nSeqLen = InStream->readLong(); @@ -711,7 +748,7 @@ void SAL_CALL ImplEventAttacherManager::read(const Reference< XObjectInputStream rDesc.ScriptType = InStream->readUTF(); rDesc.ScriptCode = InStream->readUTF(); } - registerScriptEvents( i, aSEDSeq ); + registerScriptEvents( l, i, aSEDSeq ); } // Have we read the specified length? |