diff --git a/include/vcl/idletask.hxx b/include/vcl/idletask.hxx index 1b8e33b7b181..3c038626e496 100644 --- a/include/vcl/idletask.hxx +++ b/include/vcl/idletask.hxx @@ -12,6 +12,8 @@ #include #include #include +#include +#include //IdleTask class to add a low priority Idle task class VCL_DLLPUBLIC IdleTask @@ -27,6 +29,11 @@ public: private: DECL_LINK(FlipFlag, Timer*, void); + + // Mutex and condition variable used to signal flag + std::mutex mFlagMutex; + std::condition_variable mFlagCv; + bool flag; Idle maIdle{ "testtool IdleTask" }; }; diff --git a/vcl/source/helper/idletask.cxx b/vcl/source/helper/idletask.cxx index 2865d8d0367a..9c4c10df205f 100644 --- a/vcl/source/helper/idletask.cxx +++ b/vcl/source/helper/idletask.cxx @@ -32,19 +32,31 @@ bool IdleTask::GetFlag() const //Callback function of IdleTask Class IMPL_LINK(IdleTask, FlipFlag, Timer*, , void) { + std::lock_guard aGuard(mFlagMutex); //setting the flag to make sure that low priority idle task has been dispatched flag = true; + mFlagCv.notify_all(); } void IdleTask::waitUntilIdleDispatched() { //creating instance of IdleTask Class IdleTask idleTask; - while (!idleTask.GetFlag()) + + if (Application::IsMainThread()) { - //dispatching all the events via VCL main-loop SolarMutexGuard aGuard; - Application::Yield(); + while (!idleTask.GetFlag()) + Application::Yield(); + } + else + { + // We don’t want to wait with Yield because that can cause this thread to execute the idle + // task. If the main thread is processing an event and temporarily releases the solar mutex + // then that would cause this function to finish before the event processing in the main + // thread actually finishes. + std::unique_lock aLock(idleTask.mFlagMutex); + idleTask.mFlagCv.wait(aLock, [&idleTask] { return idleTask.GetFlag(); }); } }