From e10cd7b8bf180ec2769ea82f537fd3bc98d2cee3 Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Tue, 14 May 2019 13:34:46 +0300 Subject: [PATCH] Introduce vcl::lok::unregisterPollCallbacks() and clarify isUnipoll() There was a problem in the iOS app where a callback was done passing a registered mpPollClosure that pointed to the mainKit variable in lokit_main() even though that variable had already gone out of scope and been destructed. Introduce unregisterPollCallbacks(), which just sets the mpPollClosure pointer to null. That means no callbacks should be done any more. It does not mean that Unipoll would not be active. Change isUnipoll() to look at whether the mpPollCallback pointer has been set or not. Change-Id: I5d5527c0ef097682679371dc642f8896ff05450d Reviewed-on: https://gerrit.libreoffice.org/72283 Reviewed-by: Michael Meeks Tested-by: Michael Meeks --- include/vcl/lok.hxx | 1 + vcl/headless/svpinst.cxx | 9 +++++---- vcl/source/app/svapp.cxx | 15 ++++++++++++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/vcl/lok.hxx b/include/vcl/lok.hxx index 2dbc0443d7b7..7fc5479a25cd 100644 --- a/include/vcl/lok.hxx +++ b/include/vcl/lok.hxx @@ -21,6 +21,7 @@ namespace lok bool VCL_DLLPUBLIC isUnipoll(); void VCL_DLLPUBLIC registerPollCallbacks(LibreOfficeKitPollCallback pPollCallback, LibreOfficeKitWakeCallback pWakeCallback, void* pData); +void VCL_DLLPUBLIC unregisterPollCallbacks(); } } diff --git a/vcl/headless/svpinst.cxx b/vcl/headless/svpinst.cxx index 275ffc092735..74900df2471f 100644 --- a/vcl/headless/svpinst.cxx +++ b/vcl/headless/svpinst.cxx @@ -29,6 +29,7 @@ #include #include +#include #ifndef LIBO_HEADLESS # include #endif @@ -176,7 +177,7 @@ void SvpSalInstance::Wakeup(SvpRequest const request) ImplSVData* pSVData = ImplGetSVData(); - if (pSVData->mpWakeCallback) + if (pSVData->mpWakeCallback && pSVData->mpPollClosure) pSVData->mpWakeCallback(pSVData->mpPollClosure); SvpSalYieldMutex *const pMutex(static_cast(GetYieldMutex())); @@ -377,8 +378,7 @@ sal_uInt32 SvpSalYieldMutex::doRelease(bool const bUnlockAll) if (isReleased) { - ImplSVData* pSVData = ImplGetSVData(); - if (pSVData->mpPollCallback) // is unipoll + if (vcl::lok::isUnipoll()) { if (pInst) pInst->Wakeup(SvpRequest::NONE); @@ -472,7 +472,8 @@ bool SvpSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents) nTimeoutMS = 5000; // External poll. - if (pSVData->mpPollCallback(pSVData->mpPollClosure, nTimeoutMS * 1000 /* us */) < 0) + if (pSVData->mpPollClosure != nullptr && + pSVData->mpPollCallback(pSVData->mpPollClosure, nTimeoutMS * 1000 /* us */) < 0) pSVData->maAppData.mbAppQuit = true; } else diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index df05d78d864f..d087a1595ac6 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -1675,10 +1675,23 @@ void registerPollCallbacks( } } +void unregisterPollCallbacks() +{ + ImplSVData * pSVData = ImplGetSVData(); + if (pSVData) + { + // Just set mpPollClosure to null as that is what calling this means, that the callback data + // points to an object that no longer exists. In particular, don't set + // pSVData->mpPollCallback to nullptr as that is used to detect whether Unipoll is in use in + // isUnipoll(). + pSVData->mpPollClosure = nullptr; + } +} + bool isUnipoll() { ImplSVData * pSVData = ImplGetSVData(); - return pSVData && pSVData->mpPollClosure != nullptr; + return pSVData && pSVData->mpPollCallback != nullptr; } } } // namespace lok, namespace vcl