comphelper/source/misc/lok.cxx | 9 +++-- desktop/source/lib/init.cxx | 5 ++ include/LibreOfficeKit/LibreOfficeKitTypes.h | 2 - include/comphelper/lok.hxx | 5 +- include/vcl/scheduler.hxx | 6 --- sfx2/qa/cppunit/view.cxx | 19 ++--------- sfx2/source/view/lokhelper.cxx | 41 +++++------------------- sw/qa/extras/tiledrendering/tiledrendering2.cxx | 14 ++++++-- vcl/source/app/scheduler.cxx | 13 ++----- 9 files changed, 45 insertions(+), 69 deletions(-)
New commits: commit f12991396dbb9c00e75978569e1bf110f7dcb50f Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Feb 18 14:56:00 2025 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Feb 19 14:22:39 2025 +0100 cool#11064 vcl lok: fold the scheduler info into the anyinput callback This changes the LOK API added in commit e9e39e45f0daed52276377321088aa4d49b112b6 (cool#11064 vcl lok: expose info about the scheduler, 2025-02-14) so that a LOK client doesn't have to query the priority of the most urgent task: instead the anyInput callback gets it as a parameter. The scheduler is a hot path and it's not expected this priority information would be needed in other places, so folding the new LOK API into the anyInput callback simplifies things. Change-Id: I1385055bfa27f47a243d40683b54cb2ddc9d33bd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181878 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/comphelper/source/misc/lok.cxx b/comphelper/source/misc/lok.cxx index 7d4ca7536b4b..92a8a3eba0c1 100644 --- a/comphelper/source/misc/lok.cxx +++ b/comphelper/source/misc/lok.cxx @@ -42,8 +42,9 @@ static bool g_bLocalRendering(false); static Compat g_eCompatFlags(Compat::none); -static std::function<bool(void*)> g_pAnyInputCallback; +static std::function<bool(void*, int)> g_pAnyInputCallback; static void* g_pAnyInputCallbackData; +static std::function<int()> g_pMostUrgentPriorityGetter; static std::function<void(int)> g_pViewSetter; static std::function<int()> g_pViewGetter; @@ -329,10 +330,11 @@ void statusIndicatorFinish() pStatusIndicatorCallback(pStatusIndicatorCallbackData, statusIndicatorCallbackType::Finish, 0, nullptr); } -void setAnyInputCallback(const std::function<bool(void*)>& pAnyInputCallback, void* pData) +void setAnyInputCallback(const std::function<bool(void*, int)>& pAnyInputCallback, void* pData, std::function<int()> pMostUrgentPriorityGetter) { g_pAnyInputCallback = pAnyInputCallback; g_pAnyInputCallbackData = pData; + g_pMostUrgentPriorityGetter = pMostUrgentPriorityGetter; } bool anyInput() @@ -342,7 +344,8 @@ bool anyInput() // Ignore input events during background save. if (!g_bForkedChild && g_pAnyInputCallback && g_pAnyInputCallbackData) { - bRet = g_pAnyInputCallback(g_pAnyInputCallbackData); + int nMostUrgentPriority = g_pMostUrgentPriorityGetter(); + bRet = g_pAnyInputCallback(g_pAnyInputCallbackData, nMostUrgentPriority); } return bRet; diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 831a3c9375f9..8fc9d592310b 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -198,6 +198,7 @@ #include <comphelper/diagnose_ex.hxx> #include <vcl/uitest/uiobject.hxx> #include <vcl/jsdialog/executor.hxx> +#include <vcl/scheduler.hxx> // Needed for getUndoManager() #include <com/sun/star/document/XUndoManager.hpp> @@ -7665,7 +7666,9 @@ static void lo_registerAnyInputCallback(LibreOfficeKit* /*pThis*/, void* pData) { SolarMutexGuard aGuard; - comphelper::LibreOfficeKit::setAnyInputCallback(pAnyInputCallback, pData); + comphelper::LibreOfficeKit::setAnyInputCallback(pAnyInputCallback, pData, []() -> int { + return Scheduler::GetMostUrgentTaskPriority(); + }); } static bool bInitialized = false; diff --git a/include/LibreOfficeKit/LibreOfficeKitTypes.h b/include/LibreOfficeKit/LibreOfficeKitTypes.h index a702a229834b..939766567607 100644 --- a/include/LibreOfficeKit/LibreOfficeKitTypes.h +++ b/include/LibreOfficeKit/LibreOfficeKitTypes.h @@ -26,7 +26,7 @@ typedef int (*LibreOfficeKitPollCallback)(void* pData, int timeoutUs); typedef void (*LibreOfficeKitWakeCallback)(void* pData); /// @see lok::Office::registerAnyInputCallback() -typedef bool (*LibreOfficeKitAnyInputCallback)(void* pData); +typedef bool (*LibreOfficeKitAnyInputCallback)(void* pData, int nMostUrgentPriority); #ifdef __cplusplus } diff --git a/include/comphelper/lok.hxx b/include/comphelper/lok.hxx index e222690c7e30..caed5075d986 100644 --- a/include/comphelper/lok.hxx +++ b/include/comphelper/lok.hxx @@ -138,8 +138,9 @@ COMPHELPER_DLLPUBLIC void statusIndicatorFinish(); COMPHELPER_DLLPUBLIC void setBlockedCommandList(const char* blockedCommandList); -COMPHELPER_DLLPUBLIC void setAnyInputCallback(const std::function<bool(void*)>& pAnyInputCallback, - void* pData); +COMPHELPER_DLLPUBLIC void +setAnyInputCallback(const std::function<bool(void*, int)>& pAnyInputCallback, void* pData, + std::function<int()> pMostUrgentPriorityGetter); COMPHELPER_DLLPUBLIC bool anyInput(); // These allow setting callbacks, so that set/get of a LOK view is possible even in code that is diff --git a/include/vcl/scheduler.hxx b/include/vcl/scheduler.hxx index f0002622d884..9caaf381443e 100644 --- a/include/vcl/scheduler.hxx +++ b/include/vcl/scheduler.hxx @@ -23,10 +23,6 @@ #include <vcl/dllapi.h> struct ImplSchedulerContext; -namespace tools -{ -class JsonWriter; -} class VCL_DLLPUBLIC Scheduler final { @@ -86,7 +82,7 @@ public: /// Return the current state of deterministic mode. static bool GetDeterministicMode(); - static void dumpAsJSON(tools::JsonWriter& rJsonWriter); + static int GetMostUrgentTaskPriority(); // Makes sure that idles are not processed, until the guard is destroyed struct VCL_DLLPUBLIC IdlesLockGuard final diff --git a/sfx2/qa/cppunit/view.cxx b/sfx2/qa/cppunit/view.cxx index dad9e4a51f45..22dbdfaa84ad 100644 --- a/sfx2/qa/cppunit/view.cxx +++ b/sfx2/qa/cppunit/view.cxx @@ -27,6 +27,7 @@ #include <rtl/ustrbuf.hxx> #include <comphelper/base64.hxx> #include <comphelper/propertyvalue.hxx> +#include <vcl/scheduler.hxx> using namespace com::sun::star; @@ -228,21 +229,11 @@ CPPUNIT_TEST_FIXTURE(Sfx2ViewTest, testScheduler) mxComponent = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument"); // When asking for the state of the scheduler: - tools::JsonWriter aWriter; - SfxLokHelper::getCommandValues(aWriter, ".uno:Scheduler"); - OString aJson = aWriter.finishAndGetAsOString(); + int nRet = Scheduler::GetMostUrgentTaskPriority(); - // Then make sure we get an int priority: - CPPUNIT_ASSERT(SfxLokHelper::supportsCommand(u"Scheduler")); - std::stringstream aStream{ std::string(aJson) }; - boost::property_tree::ptree aTree; - boost::property_tree::read_json(aStream, aTree); - auto it = aTree.find("mostUrgentPriority"); - // Without the accompanying fix in place, this test would have failed, this JSON key was - // missing. - CPPUNIT_ASSERT(it != aTree.not_found()); - // This returns TaskPriority::HIGH_IDLE, but just make sure we get an int. - it->second.get_value<int>(); + // Then make sure we get a priority: + // This returns TaskPriority::HIGH_IDLE, but just make sure we get a positive priority. + CPPUNIT_ASSERT(nRet != -1); } #endif diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx index 4ec48abfe6d5..f025e2598411 100644 --- a/sfx2/source/view/lokhelper.cxx +++ b/sfx2/source/view/lokhelper.cxx @@ -44,7 +44,6 @@ #include <tools/json_writer.hxx> #include <svl/cryptosign.hxx> #include <tools/urlobj.hxx> -#include <vcl/scheduler.hxx> #include <boost/property_tree/json_parser.hpp> @@ -997,8 +996,7 @@ void SfxLokHelper::addCertificates(const std::vector<std::string>& rCerts) bool SfxLokHelper::supportsCommand(std::u16string_view rCommand) { - static const std::initializer_list<std::u16string_view> vSupport - = { u"Signature", u"Scheduler" }; + static const std::initializer_list<std::u16string_view> vSupport = { u"Signature" }; return std::find(vSupport.begin(), vSupport.end(), rCommand) != vSupport.end(); } @@ -1030,11 +1028,14 @@ std::map<OUString, OUString> SfxLokHelper::parseCommandParameters(std::u16string return aMap; } -namespace -{ -/// Implements getCommandValues(".uno:Signature"). -void GetSignature(tools::JsonWriter& rJsonWriter, std::string_view rCommand) +void SfxLokHelper::getCommandValues(tools::JsonWriter& rJsonWriter, std::string_view rCommand) { + static constexpr OString aSignature(".uno:Signature"_ostr); + if (!o3tl::starts_with(rCommand, aSignature)) + { + return; + } + SfxObjectShell* pObjectShell = SfxObjectShell::Current(); if (!pObjectShell) { @@ -1052,7 +1053,7 @@ void GetSignature(tools::JsonWriter& rJsonWriter, std::string_view rCommand) } pObjectShell->SignDocumentContentUsingCertificate(aSigningContext); // Set commandName, this is a reply to a request. - rJsonWriter.put("commandName", ".uno:Signature"); + rJsonWriter.put("commandName", aSignature); auto aCommandValues = rJsonWriter.startNode("commandValues"); rJsonWriter.put("signatureTime", aSigningContext.m_nSignatureTime); @@ -1063,30 +1064,6 @@ void GetSignature(tools::JsonWriter& rJsonWriter, std::string_view rCommand) rJsonWriter.put("digest", aBuffer.makeStringAndClear()); } -/// Implements getCommandValues(".uno:Scheduler"). -void GetScheduler(tools::JsonWriter& rJsonWriter) -{ - Scheduler::dumpAsJSON(rJsonWriter); -} -} - -void SfxLokHelper::getCommandValues(tools::JsonWriter& rJsonWriter, std::string_view rCommand) -{ - static constexpr OString aSignature(".uno:Signature"_ostr); - static constexpr OString aScheduler(".uno:Scheduler"_ostr); - if (o3tl::starts_with(rCommand, aSignature)) - { - GetSignature(rJsonWriter, rCommand); - return; - } - - if (o3tl::starts_with(rCommand, aScheduler)) - { - GetScheduler(rJsonWriter); - return; - } -} - void SfxLokHelper::notifyUpdate(SfxViewShell const* pThisView, int nType) { if (DisableCallbacks::disabled() || !pThisView) diff --git a/sw/qa/extras/tiledrendering/tiledrendering2.cxx b/sw/qa/extras/tiledrendering/tiledrendering2.cxx index 93b08546a731..dc8f7e733b5c 100644 --- a/sw/qa/extras/tiledrendering/tiledrendering2.cxx +++ b/sw/qa/extras/tiledrendering/tiledrendering2.cxx @@ -199,11 +199,19 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, testAsyncLayout) class AnyInputCallback final { public: - static bool callback(void* /*pData*/) { return true; } + static bool callback(void* /*pData*/, int /*nPriority*/) { return true; } - AnyInputCallback() { comphelper::LibreOfficeKit::setAnyInputCallback(&callback, this); } + AnyInputCallback() + { + comphelper::LibreOfficeKit::setAnyInputCallback(&callback, this, + []() -> int { return -1; }); + } - ~AnyInputCallback() { comphelper::LibreOfficeKit::setAnyInputCallback(nullptr, nullptr); } + ~AnyInputCallback() + { + comphelper::LibreOfficeKit::setAnyInputCallback(nullptr, nullptr, + []() -> int { return -1; }); + } }; CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, testAnyInput) diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx index eb3acf65c8a4..ae88dee55df2 100644 --- a/vcl/source/app/scheduler.cxx +++ b/vcl/source/app/scheduler.cxx @@ -302,7 +302,7 @@ Scheduler::IdlesLockGuard::~IdlesLockGuard() osl_atomic_decrement(&rSchedCtx.mnIdlesLockCount); } -void Scheduler::dumpAsJSON(tools::JsonWriter& rJsonWriter) +int Scheduler::GetMostUrgentTaskPriority() { // Similar to Scheduler::CallbackTaskScheduling(), figure out the most urgent priority, but // don't actually invoke any task. @@ -311,15 +311,13 @@ void Scheduler::dumpAsJSON(tools::JsonWriter& rJsonWriter) ImplSchedulerContext& rSchedCtx = pSVData->maSchedCtx; if (!rSchedCtx.mbActive || rSchedCtx.mnTimerPeriod == InfiniteTimeoutMs) { - rJsonWriter.put("mostUrgentPriority", nMostUrgentPriority); - return; + return nMostUrgentPriority; } sal_uInt64 nTime = tools::Time::GetSystemTicks(); if (nTime < rSchedCtx.mnTimerStart + rSchedCtx.mnTimerPeriod - 1) { - rJsonWriter.put("mostUrgentPriority", nMostUrgentPriority); - return; + return nMostUrgentPriority; } for (int nTaskPriority = 0; nTaskPriority < PRIO_COUNT; ++nTaskPriority) @@ -335,14 +333,13 @@ void Scheduler::dumpAsJSON(tools::JsonWriter& rJsonWriter) if (nReadyPeriod == ImmediateTimeoutMs) { nMostUrgentPriority = nTaskPriority; - rJsonWriter.put("mostUrgentPriority", nMostUrgentPriority); - return; + return nMostUrgentPriority; } } pSchedulerData = pSchedulerData->mpNext; } } - rJsonWriter.put("mostUrgentPriority", nMostUrgentPriority); + return nMostUrgentPriority; } inline void Scheduler::UpdateSystemTimer( ImplSchedulerContext &rSchedCtx,