summaryrefslogtreecommitdiff
path: root/comphelper/source/eventattachermgr/eventattachermgr.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'comphelper/source/eventattachermgr/eventattachermgr.cxx')
-rw-r--r--comphelper/source/eventattachermgr/eventattachermgr.cxx145
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?