optimize unoxml for the common case of no listeners

Change-Id: I64dcf61813c9a5dfa8a82fd0b39bad2bf916b9d2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182080
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Tested-by: Jenkins
This commit is contained in:
Caolán McNamara
2025-02-24 15:11:15 +01:00
parent 86d36ee565
commit 004c882b69
6 changed files with 100 additions and 72 deletions
+2
View File
@@ -59,6 +59,8 @@ public:
const css::uno::Reference<css::xml::dom::events::XEventListener>& aListener,
bool bCapture);
bool hasListeners() const;
static void callListeners(
TypeListenerMap const& rTMap,
xmlNodePtr const pNode,
+14 -12
View File
@@ -18,6 +18,8 @@
*/
#include "characterdata.hxx"
#include "document.hxx"
#include <eventdispatcher.hxx>
#include <string.h>
@@ -43,9 +45,15 @@ namespace DOM
{
}
void CCharacterData::dispatchEvent_Impl(
void CCharacterData::dispatchEvent_Impl(::osl::ClearableMutexGuard& guard,
OUString const& prevValue, OUString const& newValue)
{
CDocument& rDocument(GetOwnerDocument());
if (!rDocument.GetEventDispatcher().hasListeners())
return;
guard.clear(); // release mutex before calling event handlers
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
Reference< XMutationEvent > event(docevent->createEvent(
u"DOMCharacterDataModified"_ustr), UNO_QUERY);
@@ -69,9 +77,7 @@ namespace DOM
OUString oldValue(reinterpret_cast<char*>(m_aNodePtr->content), strlen(reinterpret_cast<char*>(m_aNodePtr->content)), RTL_TEXTENCODING_UTF8);
xmlNodeAddContent(m_aNodePtr, reinterpret_cast<const xmlChar*>(OUStringToOString(arg, RTL_TEXTENCODING_UTF8).getStr()));
OUString newValue(reinterpret_cast<char*>(m_aNodePtr->content), strlen(reinterpret_cast<char*>(m_aNodePtr->content)), RTL_TEXTENCODING_UTF8);
guard.clear(); // release mutex before calling event handlers
dispatchEvent_Impl(oldValue, newValue);
dispatchEvent_Impl(guard, oldValue, newValue);
}
}
@@ -103,8 +109,7 @@ namespace DOM
xmlNodeSetContent(m_aNodePtr, reinterpret_cast<const xmlChar*>(OUStringToOString(tmp2, RTL_TEXTENCODING_UTF8).getStr()));
OUString newValue(reinterpret_cast<char*>(m_aNodePtr->content), strlen(reinterpret_cast<char*>(m_aNodePtr->content)), RTL_TEXTENCODING_UTF8);
guard.clear(); // release mutex before calling event handlers
dispatchEvent_Impl(oldValue, newValue);
dispatchEvent_Impl(guard, oldValue, newValue);
}
@@ -173,8 +178,7 @@ namespace DOM
xmlNodeSetContent(m_aNodePtr, reinterpret_cast<const xmlChar*>(OUStringToOString(tmp2, RTL_TEXTENCODING_UTF8).getStr()));
OUString newValue(reinterpret_cast<char*>(m_aNodePtr->content), strlen(reinterpret_cast<char*>(m_aNodePtr->content)), RTL_TEXTENCODING_UTF8);
guard.clear(); // release mutex before calling event handlers
dispatchEvent_Impl(oldValue, newValue);
dispatchEvent_Impl(guard, oldValue, newValue);
}
@@ -210,8 +214,7 @@ namespace DOM
xmlNodeSetContent(m_aNodePtr, reinterpret_cast<const xmlChar*>(OUStringToOString(tmp2, RTL_TEXTENCODING_UTF8).getStr()));
OUString newValue(reinterpret_cast<char*>(m_aNodePtr->content), strlen(reinterpret_cast<char*>(m_aNodePtr->content)), RTL_TEXTENCODING_UTF8);
guard.clear(); // release mutex before calling event handlers
dispatchEvent_Impl(oldValue, newValue);
dispatchEvent_Impl(guard, oldValue, newValue);
}
@@ -228,8 +231,7 @@ namespace DOM
xmlNodeSetContent(m_aNodePtr, reinterpret_cast<const xmlChar*>(OUStringToOString(data, RTL_TEXTENCODING_UTF8).getStr()));
OUString newValue(reinterpret_cast<char*>(m_aNodePtr->content), strlen(reinterpret_cast<char*>(m_aNodePtr->content)), RTL_TEXTENCODING_UTF8);
guard.clear(); // release mutex before calling event handlers
dispatchEvent_Impl(oldValue, newValue);
dispatchEvent_Impl(guard, oldValue, newValue);
}
}
+1 -1
View File
@@ -44,7 +44,7 @@ namespace DOM
CCharacterData(CDocument const& rDocument, ::osl::Mutex const& rMutex,
css::xml::dom::NodeType const& reNodeType, xmlNodePtr const& rpNode);
void dispatchEvent_Impl(
void dispatchEvent_Impl(::osl::ClearableMutexGuard& guard,
OUString const& prevValue, OUString const& newValue);
public:
+32 -22
View File
@@ -33,6 +33,7 @@
#include <comphelper/attributelist.hxx>
#include <comphelper/servicehelper.hxx>
#include <eventdispatcher.hxx>
#include <node.hxx>
#include "attr.hxx"
#include "elementlist.hxx"
@@ -622,18 +623,22 @@ namespace DOM
xmlSetProp(m_aNodePtr, pName, pValue);
}
// dispatch DOMAttrModified event
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
Reference< XMutationEvent > event(docevent->createEvent(
u"DOMAttrModified"_ustr), UNO_QUERY);
event->initMutationEvent(u"DOMAttrModified"_ustr,
true, false,
getAttributeNode(name),
oldValue, value, name, aChangeType);
CDocument& rDocument(GetOwnerDocument());
if (rDocument.GetEventDispatcher().hasListeners())
{
// dispatch DOMAttrModified event
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
Reference< XMutationEvent > event(docevent->createEvent(
u"DOMAttrModified"_ustr), UNO_QUERY);
event->initMutationEvent(u"DOMAttrModified"_ustr,
true, false,
getAttributeNode(name),
oldValue, value, name, aChangeType);
guard.clear(); // release mutex before calling event handlers
dispatchEvent(event);
dispatchSubtreeModified();
guard.clear(); // release mutex before calling event handlers
dispatchEvent(event);
dispatchSubtreeModified();
}
}
/**
@@ -703,18 +708,23 @@ namespace DOM
RTL_TEXTENCODING_UTF8);
xmlSetNsProp(m_aNodePtr, pNs, pLName, pValue);
}
// dispatch DOMAttrModified event
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
Reference< XMutationEvent > event(docevent->createEvent(
u"DOMAttrModified"_ustr), UNO_QUERY);
event->initMutationEvent(
u"DOMAttrModified"_ustr, true, false,
getAttributeNodeNS(namespaceURI, OUString(reinterpret_cast<char const *>(pLName), strlen(reinterpret_cast<char const *>(pLName)), RTL_TEXTENCODING_UTF8)),
oldValue, value, qualifiedName, aChangeType);
guard.clear(); // release mutex before calling event handlers
dispatchEvent(event);
dispatchSubtreeModified();
CDocument& rDocument(GetOwnerDocument());
if (rDocument.GetEventDispatcher().hasListeners())
{
// dispatch DOMAttrModified event
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
Reference< XMutationEvent > event(docevent->createEvent(
u"DOMAttrModified"_ustr), UNO_QUERY);
event->initMutationEvent(
u"DOMAttrModified"_ustr, true, false,
getAttributeNodeNS(namespaceURI, OUString(reinterpret_cast<char const *>(pLName), strlen(reinterpret_cast<char const *>(pLName)), RTL_TEXTENCODING_UTF8)),
oldValue, value, qualifiedName, aChangeType);
guard.clear(); // release mutex before calling event handlers
dispatchEvent(event);
dispatchSubtreeModified();
}
}
Reference< XNamedNodeMap > SAL_CALL
+46 -37
View File
@@ -357,27 +357,32 @@ namespace DOM
// because that will not remove unneeded ns decls
nscleanup(res, m_aNodePtr);
::rtl::Reference<CNode> const pNode = GetOwnerDocument().GetCNode(res);
CDocument& rDocument(GetOwnerDocument());
::rtl::Reference<CNode> const pNode = rDocument.GetCNode(res);
if (!pNode.is()) { return nullptr; }
// dispatch DOMNodeInserted event, target is the new node
// this node is the related node
// does bubble
pNode->m_bUnlinked = false; // will be deleted by xmlFreeDoc
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
Reference< XMutationEvent > event(docevent->createEvent(
u"DOMNodeInserted"_ustr), UNO_QUERY);
event->initMutationEvent(u"DOMNodeInserted"_ustr, true, false, this,
OUString(), OUString(), OUString(), AttrChangeType(0) );
// the following dispatch functions use only UNO interfaces
// and call event listeners, so release mutex to prevent deadlocks.
guard.clear();
if (rDocument.GetEventDispatcher().hasListeners())
{
// dispatch DOMNodeInserted event, target is the new node
// this node is the related node
// does bubble
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
Reference< XMutationEvent > event(docevent->createEvent(
u"DOMNodeInserted"_ustr), UNO_QUERY);
event->initMutationEvent(u"DOMNodeInserted"_ustr, true, false, this,
OUString(), OUString(), OUString(), AttrChangeType(0) );
dispatchEvent(event);
// dispatch subtree modified for this node
dispatchSubtreeModified();
// the following dispatch functions use only UNO interfaces
// and call event listeners, so release mutex to prevent deadlocks.
guard.clear();
dispatchEvent(event);
// dispatch subtree modified for this node
dispatchSubtreeModified();
}
return pNode;
}
@@ -752,30 +757,34 @@ namespace DOM
pOld->m_bUnlinked = true;
}
/*DOMNodeRemoved
* Fired when a node is being removed from its parent node.
* This event is dispatched before the node is removed from the tree.
* The target of this event is the node being removed.
* Bubbles: Yes
* Cancelable: No
* Context Info: relatedNode holds the parent node
*/
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
Reference< XMutationEvent > event(docevent->createEvent(
u"DOMNodeRemoved"_ustr), UNO_QUERY);
event->initMutationEvent(u"DOMNodeRemoved"_ustr,
true,
false,
this,
OUString(), OUString(), OUString(), AttrChangeType(0) );
CDocument& rDocument(GetOwnerDocument());
if (rDocument.GetEventDispatcher().hasListeners())
{
/*DOMNodeRemoved
* Fired when a node is being removed from its parent node.
* This event is dispatched before the node is removed from the tree.
* The target of this event is the node being removed.
* Bubbles: Yes
* Cancelable: No
* Context Info: relatedNode holds the parent node
*/
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
Reference< XMutationEvent > event(docevent->createEvent(
u"DOMNodeRemoved"_ustr), UNO_QUERY);
event->initMutationEvent(u"DOMNodeRemoved"_ustr,
true,
false,
this,
OUString(), OUString(), OUString(), AttrChangeType(0) );
// the following dispatch functions use only UNO interfaces
// and call event listeners, so release mutex to prevent deadlocks.
guard.clear();
// the following dispatch functions use only UNO interfaces
// and call event listeners, so release mutex to prevent deadlocks.
guard.clear();
dispatchEvent(event);
// subtree modified for this node
dispatchSubtreeModified();
dispatchEvent(event);
// subtree modified for this node
dispatchSubtreeModified();
}
return xReturn;
}
+5
View File
@@ -78,6 +78,11 @@ namespace DOM::events {
}
}
bool CEventDispatcher::hasListeners() const
{
return !m_CaptureListeners.empty() || !m_TargetListeners.empty();
}
CEventDispatcher::~CEventDispatcher()
{
}