Extend the Link DBG_UTIL support to non-member function Links

...so that they don't report "unknown" (and make empty links report "empty"
instead, for clarification).  This introduces a new LINK_NONMEMBER macro; the
non-default Link ctor should no longer be used directly, so make it private.

Change-Id: I4ae99758de57adb8569ce98cb3824e875b26c959
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180593
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
This commit is contained in:
Stephan Bergmann
2025-01-22 12:54:21 +01:00
parent 10d8402957
commit b811b283c2
7 changed files with 51 additions and 25 deletions

View File

@@ -71,11 +71,29 @@
#ifdef DBG_UTIL
#define LINK(Instance, Class, Member) ::tools::detail::makeLink( \
::tools::detail::castTo<Class *>(Instance), &Class::LinkStub##Member, __FILE__ ":" SAL_STRINGIFY(__LINE__), SAL_STRINGIFY(Class::LinkStub##Member))
#define LINK_NONMEMBER(Instance, Function) ::tools::detail::makeLink( \
Instance, &Function, __FILE__ ":" SAL_STRINGIFY(__LINE__), SAL_STRINGIFY(Function))
#else
#define LINK(Instance, Class, Member) ::tools::detail::makeLink( \
::tools::detail::castTo<Class *>(Instance), &Class::LinkStub##Member)
#define LINK_NONMEMBER(Instance, Function) ::tools::detail::makeLink(Instance, &Function)
#endif
template<typename Arg, typename Ret> class SAL_WARN_UNUSED Link;
namespace tools::detail {
#ifdef DBG_UTIL
template<typename Arg, typename Ret>
Link<Arg, Ret> makeLink(
void * instance, Ret (* function)(void *, Arg), const char* source, const char* target);
#else
template<typename Arg, typename Ret>
Link<Arg, Ret> makeLink(void * instance, Ret (* function)(void *, Arg));
#endif
}
template<typename Arg, typename Ret>
class SAL_WARN_UNUSED Link {
public:
@@ -83,20 +101,6 @@ public:
Link() = default;
#ifdef DBG_UTIL
Link(void* instance, Stub* function, const char* const source = "unknown",
const char* const target = "unknown")
: function_(function)
, instance_(instance)
, source_(source)
, target_(target)
{
}
#else
Link(void * instance, Stub * function):
function_(function), instance_(instance) {}
#endif
Ret Call(Arg data) const
{ return function_ == nullptr ? Ret() : (*function_)(instance_, data); }
@@ -126,6 +130,28 @@ public:
#endif
private:
#ifdef DBG_UTIL
template<typename Arg2, typename Ret2> friend Link<Arg2, Ret2> tools::detail::makeLink(
void * instance, Ret2 (* function)(void *, Arg2), const char* source, const char* target);
#else
template<typename Arg2, typename Ret2> friend Link<Arg2, Ret2> tools::detail::makeLink(
void * instance, Ret2 (* function)(void *, Arg2));
#endif
#ifdef DBG_UTIL
Link(void* instance, Stub* function, const char* const source,
const char* const target)
: function_(function)
, instance_(instance)
, source_(source)
, target_(target)
{
}
#else
Link(void * instance, Stub * function):
function_(function), instance_(instance) {}
#endif
Stub* function_ = nullptr;
void* instance_ = nullptr;
@@ -134,8 +160,8 @@ private:
/// When debugging async events, it's often critical
/// to find out not only where a link leads (i.e. the target
/// function), but also where it was created (file:line).
const char* source_ = "unknown";
const char* target_ = "unknown";
const char* source_ = "empty";
const char* target_ = "empty";
#endif
};

View File

@@ -429,7 +429,7 @@ void SfxShell::ExecuteSlot( SfxRequest& rReq, bool bAsync )
{
if( !pImpl->pExecuter )
pImpl->pExecuter.reset( new svtools::AsynchronLink(
Link<void*,void>( this, ShellCall_Impl ) ) );
LINK_NONMEMBER( this, ShellCall_Impl ) ) );
pImpl->pExecuter->Call( new SfxRequest( rReq ) );
}
}
@@ -672,7 +672,7 @@ void SfxShell::UIFeatureChanged()
// something may get stuck in the bunkered tools. Asynchronous call to
// prevent recursion.
if ( !pImpl->pUpdater )
pImpl->pUpdater.reset( new svtools::AsynchronLink( Link<void*,void>( this, DispatcherUpdate_Impl ) ) );
pImpl->pUpdater.reset( new svtools::AsynchronLink( LINK_NONMEMBER( this, DispatcherUpdate_Impl ) ) );
// Multiple views allowed
pImpl->pUpdater->Call( pFrame->GetDispatcher(), true );

View File

@@ -801,7 +801,7 @@ void BackingWindow::dispatchURL( const OUString& i_rURL,
if ( xDispatch.is() )
{
std::unique_ptr<ImplDelayedDispatch> pDisp(new ImplDelayedDispatch( xDispatch, std::move(aDispatchURL), i_rArgs ));
if( Application::PostUserEvent( Link<void*,void>( nullptr, implDispatchDelayed ), pDisp.get() ) )
if( Application::PostUserEvent( LINK_NONMEMBER( nullptr, implDispatchDelayed ), pDisp.get() ) )
pDisp.release();
}
}

View File

@@ -1231,7 +1231,7 @@ namespace
LOKPostAsyncEvent(pEvent, nullptr);
}
else
Application::PostUserEvent(Link<void*, void>(pEvent, LOKPostAsyncEvent));
Application::PostUserEvent(LINK_NONMEMBER(pEvent, LOKPostAsyncEvent));
}
}

View File

@@ -158,7 +158,7 @@ UUIInteractionHelper::handleRequest(
{
// we are not in the main thread, let it handle that stuff
HandleData aHD(rRequest);
Link<void*,void> aLink(&aHD,handlerequest);
Link<void*,void> aLink = LINK_NONMEMBER(&aHD,handlerequest);
Application::PostUserEvent(aLink,this);
comphelper::SolarMutex& rSolarMutex = Application::GetSolarMutex();
sal_uInt32 nLockCount = (rSolarMutex.IsCurrentThread()) ? rSolarMutex.release(true) : 0;
@@ -209,7 +209,7 @@ UUIInteractionHelper::getStringFromRequest(
{
// we are not in the main thread, let it handle that stuff
HandleData aHD(rRequest);
Link<void*,void> aLink(&aHD,getstringfromrequest);
Link<void*,void> aLink = LINK_NONMEMBER(&aHD,getstringfromrequest);
Application::PostUserEvent(aLink,this);
comphelper::SolarMutex& rSolarMutex = Application::GetSolarMutex();
sal_uInt32 nLockCount = (rSolarMutex.IsCurrentThread()) ? rSolarMutex.release(true) : 0;

View File

@@ -90,7 +90,7 @@ void AquaA11yFocusTracker::WindowEventHandler(void * pThis, VclSimpleEvent& rEve
}
AquaA11yFocusTracker::AquaA11yFocusTracker() :
m_aWindowEventLink(this, WindowEventHandler),
m_aWindowEventLink(LINK_NONMEMBER(this, WindowEventHandler)),
m_xDocumentFocusListener(new DocumentFocusListener(*this))
{
Application::AddEventListener(m_aWindowEventLink);

View File

@@ -792,7 +792,7 @@ bool ImplHandleMouseEvent( const VclPtr<vcl::Window>& xWindow, NotifyEventType n
ContextMenuEvent* pEv = new ContextMenuEvent;
pEv->pWindow = std::move(pChild);
pEv->aChildPos = aChildPos;
Application::PostUserEvent( Link<void*,void>( pEv, ContextMenuEventLink ) );
Application::PostUserEvent( LINK_NONMEMBER( pEv, ContextMenuEventLink ) );
}
else
bRet = ! ImplCallCommand( pChild, CommandEventId::ContextMenu, nullptr, true, &aChildPos );
@@ -2272,7 +2272,7 @@ static void ImplHandleClose( const vcl::Window* pWindow )
{
DelayedCloseEvent* pEv = new DelayedCloseEvent;
pEv->pWindow = pWin;
Application::PostUserEvent( Link<void*,void>( pEv, DelayedCloseEventLink ) );
Application::PostUserEvent( LINK_NONMEMBER( pEv, DelayedCloseEventLink ) );
}
}