summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2018-09-16 19:17:31 +0000
committerJan-Marek Glogowski <glogow@fbihome.de>2018-09-24 14:12:58 +0200
commitd0bd1880f4edf6b5a1657e675aa10a6418003d99 (patch)
treef87a18f808620ded18dd08a02b909a7e241214d8
parentd4f871a859d969172bd1f8959e86f40993664ad5 (diff)
Scheduler: add per-priority Task lists
This way we don't have to search the whole list for a higher priority event, if an immediate Task is found. This probably helps bugs like tdf#119724 and tdf#119428. Change-Id: Ic5685193d1bedb6996cf46f0ee2cba42190ff7cc Reviewed-on: https://gerrit.libreoffice.org/60572 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
-rw-r--r--include/vcl/task.hxx12
-rw-r--r--svx/source/sidebar/PanelLayout.cxx7
-rw-r--r--vcl/inc/svdata.hxx6
-rw-r--r--vcl/qa/cppunit/timer.cxx21
-rw-r--r--vcl/source/app/scheduler.cxx208
-rw-r--r--vcl/source/app/svapp.cxx21
6 files changed, 158 insertions, 117 deletions
diff --git a/include/vcl/task.hxx b/include/vcl/task.hxx
index 7c450099c830..76d2890055fb 100644
--- a/include/vcl/task.hxx
+++ b/include/vcl/task.hxx
@@ -21,6 +21,7 @@
#define INCLUDED_VCL_TASK_HXX
#include <vcl/dllapi.h>
+#include <sal/log.hxx>
#include <memory>
class Scheduler;
@@ -38,6 +39,8 @@ enum class TaskPriority
LOWEST ///< Low, very idle cleanup tasks
};
+#define PRIO_COUNT (static_cast<int>(TaskPriority::LOWEST) + 1)
+
class VCL_DLLPUBLIC Task
{
friend class Scheduler;
@@ -76,7 +79,7 @@ public:
virtual ~Task() COVERITY_NOEXCEPT_FALSE;
Task& operator=( const Task& rTask );
- void SetPriority(TaskPriority ePriority) { mePriority = ePriority; }
+ inline void SetPriority(TaskPriority ePriority);
TaskPriority GetPriority() const { return mePriority; }
void SetDebugName( const sal_Char *pDebugName ) { mpDebugName = pDebugName; }
@@ -100,6 +103,13 @@ public:
bool IsStatic() const { return mbStatic; }
};
+inline void Task::SetPriority(TaskPriority ePriority)
+{
+ SAL_WARN_IF(mpSchedulerData, "vcl.schedule",
+ "Priority will just change after next schedule!");
+ mePriority = ePriority;
+}
+
#endif // INCLUDED_VCL_TASK_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/sidebar/PanelLayout.cxx b/svx/source/sidebar/PanelLayout.cxx
index 90bbd328da8b..82a7316c0589 100644
--- a/svx/source/sidebar/PanelLayout.cxx
+++ b/svx/source/sidebar/PanelLayout.cxx
@@ -18,14 +18,15 @@ using namespace sfx2::sidebar;
PanelLayout::PanelLayout(vcl::Window* pParent, const OString& rID, const OUString& rUIXMLDescription, const css::uno::Reference<css::frame::XFrame> &rFrame)
: Control(pParent)
- , m_aPanelLayoutIdle("svx sidebar PanelLayoutIdle")
, m_bInClose(false)
{
SetStyle(GetStyle() | WB_DIALOGCONTROL);
- m_pUIBuilder.reset(new VclBuilder(this, getUIRootDir(), rUIXMLDescription, rID, rFrame));
m_aPanelLayoutIdle.SetPriority(TaskPriority::RESIZE);
m_aPanelLayoutIdle.SetInvokeHandler( LINK( this, PanelLayout, ImplHandlePanelLayoutTimerHdl ) );
- m_aPanelLayoutIdle.SetDebugName( "svx::PanelLayout m_aPanelLayoutIdle" );
+ m_aPanelLayoutIdle.SetDebugName("svx::PanelLayout m_aPanelLayoutIdle");
+
+ // VclBuilder will trigger resize and start Idle
+ m_pUIBuilder.reset(new VclBuilder(this, getUIRootDir(), rUIXMLDescription, rID, rFrame));
if (GetSettings().GetStyleSettings().GetAutoMnemonic())
Accelerator::GenerateAutoMnemonicsOnHierarchy(this);
}
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index 6ef279586ea1..6df874abc74b 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -26,6 +26,7 @@
#include <unotools/options.hxx>
#include <vcl/svapp.hxx>
#include <vcl/window.hxx>
+#include <vcl/task.hxx>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/i18n/XCharacterClassification.hpp>
@@ -327,9 +328,10 @@ struct BlendFrameCache
struct ImplSchedulerContext
{
- ImplSchedulerData* mpFirstSchedulerData = nullptr; ///< list of all active tasks
- ImplSchedulerData* mpLastSchedulerData = nullptr; ///< last item of the mpFirstSchedulerData list
+ ImplSchedulerData* mpFirstSchedulerData[PRIO_COUNT] = { nullptr, }; ///< list of all active tasks per priority
+ ImplSchedulerData* mpLastSchedulerData[PRIO_COUNT] = { nullptr, }; ///< last item of each mpFirstSchedulerData list
ImplSchedulerData* mpSchedulerStack = nullptr; ///< stack of invoked tasks
+ ImplSchedulerData* mpSchedulerStackTop = nullptr; ///< top most stack entry to detect needed rescheduling during pop
SalTimer* mpSalTimer = nullptr; ///< interface to sal event loop / system timer
sal_uInt64 mnTimerStart = 0; ///< start time of the timer
sal_uInt64 mnTimerPeriod = SAL_MAX_UINT64; ///< current timer period
diff --git a/vcl/qa/cppunit/timer.cxx b/vcl/qa/cppunit/timer.cxx
index 4c4ed630c601..cb5a3bd64c52 100644
--- a/vcl/qa/cppunit/timer.cxx
+++ b/vcl/qa/cppunit/timer.cxx
@@ -453,12 +453,13 @@ class IdleSerializer : public Idle
sal_uInt32 const mnPosition;
sal_uInt32 &mrProcesed;
public:
- IdleSerializer( const sal_Char *pDebugName,
- sal_uInt32 nPosition, sal_uInt32 &rProcesed )
+ IdleSerializer(const sal_Char *pDebugName, TaskPriority ePrio,
+ sal_uInt32 nPosition, sal_uInt32 &rProcesed)
: Idle( pDebugName )
, mnPosition( nPosition )
, mrProcesed( rProcesed )
{
+ SetPriority(ePrio);
Start();
}
virtual void Invoke() override
@@ -474,10 +475,10 @@ void TimerTest::testPriority()
{
// Start: 1st Idle low, 2nd high
sal_uInt32 nProcessed = 0;
- IdleSerializer aLowPrioIdle( "IdleSerializer LowPrio", 2, nProcessed );
- aLowPrioIdle.SetPriority( TaskPriority::LOWEST );
- IdleSerializer aHighPrioIdle( "IdleSerializer HighPrio", 1, nProcessed );
- aHighPrioIdle.SetPriority( TaskPriority::HIGHEST );
+ IdleSerializer aLowPrioIdle("IdleSerializer LowPrio",
+ TaskPriority::LOWEST, 2, nProcessed);
+ IdleSerializer aHighPrioIdle("IdleSerializer HighPrio",
+ TaskPriority::HIGHEST, 1, nProcessed);
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT_EQUAL_MESSAGE( "Not all idles processed", sal_uInt32(2), nProcessed );
}
@@ -485,10 +486,10 @@ void TimerTest::testPriority()
{
// Start: 1st Idle high, 2nd low
sal_uInt32 nProcessed = 0;
- IdleSerializer aHighPrioIdle( "IdleSerializer HighPrio", 1, nProcessed );
- aHighPrioIdle.SetPriority( TaskPriority::HIGHEST );
- IdleSerializer aLowPrioIdle( "IdleSerializer LowPrio", 2, nProcessed );
- aLowPrioIdle.SetPriority( TaskPriority::LOWEST );
+ IdleSerializer aHighPrioIdle("IdleSerializer HighPrio",
+ TaskPriority::HIGHEST, 1, nProcessed);
+ IdleSerializer aLowPrioIdle("IdleSerializer LowPrio",
+ TaskPriority::LOWEST, 2, nProcessed);
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT_EQUAL_MESSAGE( "Not all idles processed", sal_uInt32(2), nProcessed );
}
diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx
index 9e5c3bc8db72..506638cc0ee5 100644
--- a/vcl/source/app/scheduler.cxx
+++ b/vcl/source/app/scheduler.cxx
@@ -104,18 +104,20 @@ void Scheduler::ImplDeInitScheduler()
SchedulerGuard aSchedulerGuard;
+ int nTaskPriority = 0;
#if OSL_DEBUG_LEVEL > 0
+ sal_uInt32 nTasks = 0;
+ for (nTaskPriority = 0; nTaskPriority < PRIO_COUNT; ++nTaskPriority)
{
- ImplSchedulerData* pSchedulerData = rSchedCtx.mpFirstSchedulerData;
- sal_uInt32 nTasks = 0;
+ ImplSchedulerData* pSchedulerData = rSchedCtx.mpFirstSchedulerData[nTaskPriority];
while ( pSchedulerData )
{
++nTasks;
pSchedulerData = pSchedulerData->mpNext;
}
- SAL_INFO( "vcl.schedule.deinit",
- "DeInit the scheduler - pending tasks: " << nTasks );
}
+ SAL_INFO( "vcl.schedule.deinit",
+ "DeInit the scheduler - pending tasks: " << nTasks );
// clean up all the sfx::SfxItemDisruptor_Impl Idles
ProcessEventsToIdle();
@@ -131,7 +133,11 @@ void Scheduler::ImplDeInitScheduler()
#if OSL_DEBUG_LEVEL > 0
sal_uInt32 nActiveTasks = 0, nIgnoredTasks = 0;
#endif
- ImplSchedulerData* pSchedulerData = rSchedCtx.mpFirstSchedulerData;
+ nTaskPriority = 0;
+ ImplSchedulerData* pSchedulerData = nullptr;
+
+next_priority:
+ pSchedulerData = rSchedCtx.mpFirstSchedulerData[nTaskPriority];
while ( pSchedulerData )
{
Task *pTask = pSchedulerData->mpTask;
@@ -176,6 +182,11 @@ void Scheduler::ImplDeInitScheduler()
pSchedulerData = pSchedulerData->mpNext;
delete pDeleteSchedulerData;
}
+
+ ++nTaskPriority;
+ if (nTaskPriority < PRIO_COUNT)
+ goto next_priority;
+
#if OSL_DEBUG_LEVEL > 0
SAL_INFO( "vcl.schedule.deinit", "DeInit the scheduler - finished" );
SAL_WARN_IF( 0 != nActiveTasks, "vcl.schedule.deinit", "DeInit active tasks: "
@@ -183,8 +194,11 @@ void Scheduler::ImplDeInitScheduler()
// assert( nIgnoredTasks == nActiveTasks );
#endif
- rSchedCtx.mpFirstSchedulerData = nullptr;
- rSchedCtx.mpLastSchedulerData = nullptr;
+ for (nTaskPriority = 0; nTaskPriority < PRIO_COUNT; ++nTaskPriority)
+ {
+ rSchedCtx.mpFirstSchedulerData[nTaskPriority] = nullptr;
+ rSchedCtx.mpLastSchedulerData[nTaskPriority] = nullptr;
+ }
rSchedCtx.mnTimerPeriod = InfiniteTimeoutMs;
}
@@ -298,38 +312,40 @@ inline void Scheduler::UpdateSystemTimer( ImplSchedulerContext &rSchedCtx,
}
static inline void AppendSchedulerData( ImplSchedulerContext &rSchedCtx,
- ImplSchedulerData * const pSchedulerData )
+ ImplSchedulerData * const pSchedulerData)
{
- if ( !rSchedCtx.mpLastSchedulerData )
+ assert(pSchedulerData->mpTask);
+ const int nTaskPriority = static_cast<int>(pSchedulerData->mpTask->GetPriority());
+ if (!rSchedCtx.mpLastSchedulerData[nTaskPriority])
{
- rSchedCtx.mpFirstSchedulerData = pSchedulerData;
- rSchedCtx.mpLastSchedulerData = pSchedulerData;
+ rSchedCtx.mpFirstSchedulerData[nTaskPriority] = pSchedulerData;
+ rSchedCtx.mpLastSchedulerData[nTaskPriority] = pSchedulerData;
}
else
{
- rSchedCtx.mpLastSchedulerData->mpNext = pSchedulerData;
- rSchedCtx.mpLastSchedulerData = pSchedulerData;
+ rSchedCtx.mpLastSchedulerData[nTaskPriority]->mpNext = pSchedulerData;
+ rSchedCtx.mpLastSchedulerData[nTaskPriority] = pSchedulerData;
}
pSchedulerData->mpNext = nullptr;
}
static inline ImplSchedulerData* DropSchedulerData(
ImplSchedulerContext &rSchedCtx, ImplSchedulerData * const pPrevSchedulerData,
- const ImplSchedulerData * const pSchedulerData )
+ const ImplSchedulerData * const pSchedulerData, const int nTaskPriority)
{
assert( pSchedulerData );
if ( pPrevSchedulerData )
assert( pPrevSchedulerData->mpNext == pSchedulerData );
else
- assert( rSchedCtx.mpFirstSchedulerData == pSchedulerData );
+ assert(rSchedCtx.mpFirstSchedulerData[nTaskPriority] == pSchedulerData);
ImplSchedulerData * const pSchedulerDataNext = pSchedulerData->mpNext;
if ( pPrevSchedulerData )
pPrevSchedulerData->mpNext = pSchedulerDataNext;
else
- rSchedCtx.mpFirstSchedulerData = pSchedulerDataNext;
+ rSchedCtx.mpFirstSchedulerData[nTaskPriority] = pSchedulerDataNext;
if ( !pSchedulerDataNext )
- rSchedCtx.mpLastSchedulerData = pPrevSchedulerData;
+ rSchedCtx.mpLastSchedulerData[nTaskPriority] = pPrevSchedulerData;
return pSchedulerDataNext;
}
@@ -348,10 +364,9 @@ bool Scheduler::ProcessTaskScheduling()
// Allow for decimals, so subtract in the compare (needed at least on iOS)
if ( nTime < rSchedCtx.mnTimerStart + rSchedCtx.mnTimerPeriod -1)
{
- SAL_WARN( "vcl.schedule", "we're too early - restart the timer!" );
- UpdateSystemTimer( rSchedCtx,
- rSchedCtx.mnTimerStart + rSchedCtx.mnTimerPeriod - nTime,
- true, nTime );
+ int nSleep = rSchedCtx.mnTimerStart + rSchedCtx.mnTimerPeriod - nTime;
+ SAL_WARN("vcl.schedule", "we're too early - restart the timer (" << nSleep << "ms)!");
+ UpdateSystemTimer(rSchedCtx, nSleep, true, nTime);
return false;
}
@@ -359,69 +374,72 @@ bool Scheduler::ProcessTaskScheduling()
ImplSchedulerData* pPrevSchedulerData = nullptr;
ImplSchedulerData *pMostUrgent = nullptr;
ImplSchedulerData *pPrevMostUrgent = nullptr;
+ int nMostUrgentPriority = 0;
sal_uInt64 nMinPeriod = InfiniteTimeoutMs;
- sal_uInt64 nMostUrgentPeriod = InfiniteTimeoutMs;
sal_uInt64 nReadyPeriod = InfiniteTimeoutMs;
unsigned nTasks = 0;
+ int nTaskPriority = 0;
- pSchedulerData = rSchedCtx.mpFirstSchedulerData;
- while ( pSchedulerData )
+ for (; nTaskPriority < PRIO_COUNT; ++nTaskPriority)
{
- ++nTasks;
- const Timer *timer = dynamic_cast<Timer*>( pSchedulerData->mpTask );
- if ( timer )
- SAL_INFO( "vcl.schedule", tools::Time::GetSystemTicks() << " "
- << pSchedulerData << " " << *pSchedulerData << " " << *timer );
- else if ( pSchedulerData->mpTask )
- SAL_INFO( "vcl.schedule", tools::Time::GetSystemTicks() << " "
- << pSchedulerData << " " << *pSchedulerData
- << " " << *pSchedulerData->mpTask );
- else
- SAL_INFO( "vcl.schedule", tools::Time::GetSystemTicks() << " "
- << pSchedulerData << " " << *pSchedulerData << " (to be deleted)" );
-
- // Should the Task be released from scheduling or stacked?
- if ( !pSchedulerData->mpTask || !pSchedulerData->mpTask->IsActive()
- || pSchedulerData->mbInScheduler )
+ pSchedulerData = rSchedCtx.mpFirstSchedulerData[nTaskPriority];
+ pPrevSchedulerData = nullptr;
+ while (pSchedulerData)
{
- ImplSchedulerData * const pSchedulerDataNext =
- DropSchedulerData( rSchedCtx, pPrevSchedulerData, pSchedulerData );
- if ( pSchedulerData->mbInScheduler )
- {
- pSchedulerData->mpNext = rSchedCtx.mpSchedulerStack;
- rSchedCtx.mpSchedulerStack = pSchedulerData;
- }
+ ++nTasks;
+ const Timer *timer = dynamic_cast<Timer*>( pSchedulerData->mpTask );
+ if ( timer )
+ SAL_INFO( "vcl.schedule", tools::Time::GetSystemTicks() << " "
+ << pSchedulerData << " " << *pSchedulerData << " " << *timer );
+ else if ( pSchedulerData->mpTask )
+ SAL_INFO( "vcl.schedule", tools::Time::GetSystemTicks() << " "
+ << pSchedulerData << " " << *pSchedulerData
+ << " " << *pSchedulerData->mpTask );
else
+ SAL_INFO( "vcl.schedule", tools::Time::GetSystemTicks() << " "
+ << pSchedulerData << " " << *pSchedulerData << " (to be deleted)" );
+
+ // Should the Task be released from scheduling?
+ assert(!pSchedulerData->mbInScheduler);
+ if (!pSchedulerData->mpTask || !pSchedulerData->mpTask->IsActive())
{
+ ImplSchedulerData * const pSchedulerDataNext =
+ DropSchedulerData(rSchedCtx, pPrevSchedulerData, pSchedulerData, nTaskPriority);
if ( pSchedulerData->mpTask )
pSchedulerData->mpTask->mpSchedulerData = nullptr;
delete pSchedulerData;
+ pSchedulerData = pSchedulerDataNext;
+ continue;
}
- pSchedulerData = pSchedulerDataNext;
- continue;
- }
- assert( pSchedulerData->mpTask );
- if ( !pSchedulerData->mpTask->IsActive() )
- goto next_entry;
+ assert(pSchedulerData->mpTask);
+ if (pSchedulerData->mpTask->IsActive())
+ {
+ nReadyPeriod = pSchedulerData->mpTask->UpdateMinPeriod( nMinPeriod, nTime );
+ if (ImmediateTimeoutMs == nReadyPeriod)
+ {
+ if (!pMostUrgent)
+ {
+ pPrevMostUrgent = pPrevSchedulerData;
+ pMostUrgent = pSchedulerData;
+ nMostUrgentPriority = nTaskPriority;
+ }
+ else
+ {
+ nMinPeriod = ImmediateTimeoutMs;
+ break;
+ }
+ }
+ else if (nMinPeriod > nReadyPeriod)
+ nMinPeriod = nReadyPeriod;
+ }
- // skip ready tasks with lower priority than the most urgent (numerical lower is higher)
- nReadyPeriod = pSchedulerData->mpTask->UpdateMinPeriod( nMinPeriod, nTime );
- if ( ImmediateTimeoutMs == nReadyPeriod &&
- (!pMostUrgent || (pSchedulerData->mpTask->GetPriority() < pMostUrgent->mpTask->GetPriority())) )
- {
- if ( pMostUrgent && nMinPeriod > nMostUrgentPeriod )
- nMinPeriod = nMostUrgentPeriod;
- pPrevMostUrgent = pPrevSchedulerData;
- pMostUrgent = pSchedulerData;
- nMostUrgentPeriod = nReadyPeriod;
+ pPrevSchedulerData = pSchedulerData;
+ pSchedulerData = pSchedulerData->mpNext;
}
- else if ( nMinPeriod > nReadyPeriod )
- nMinPeriod = nReadyPeriod;
-next_entry:
- pPrevSchedulerData = pSchedulerData;
- pSchedulerData = pSchedulerData->mpNext;
+ if (ImmediateTimeoutMs == nMinPeriod)
+ break;
}
if ( InfiniteTimeoutMs != nMinPeriod )
@@ -441,10 +459,15 @@ next_entry:
// prepare Scheduler object for deletion after handling
pTask->SetDeletionFlags();
- // invoke the task
- // defer pushing the scheduler stack to next run, as most tasks will
- // not run a nested Scheduler loop and don't need a stack push!
pMostUrgent->mbInScheduler = true;
+
+ // always push the stack, as we don't traverse the whole list to push later
+ DropSchedulerData(rSchedCtx, pPrevMostUrgent, pMostUrgent, nMostUrgentPriority);
+ pMostUrgent->mpNext = rSchedCtx.mpSchedulerStack;
+ rSchedCtx.mpSchedulerStack = pMostUrgent;
+ rSchedCtx.mpSchedulerStackTop = pMostUrgent;
+
+ // invoke the task
sal_uInt32 nLockCount = Unlock( true );
try
{
@@ -472,34 +495,35 @@ next_entry:
SAL_INFO( "vcl.schedule", tools::Time::GetSystemTicks() << " "
<< pMostUrgent << " invoke-out" );
- // eventually pop the scheduler stack
+ // pop the scheduler stack
+ pSchedulerData = rSchedCtx.mpSchedulerStack;
+ assert(pSchedulerData == pMostUrgent);
+ rSchedCtx.mpSchedulerStack = pSchedulerData->mpNext;
+
+ const bool bTaskAlive = pMostUrgent->mpTask && pMostUrgent->mpTask->IsActive();
+ if (!bTaskAlive)
+ {
+ if (pMostUrgent->mpTask)
+ pMostUrgent->mpTask->mpSchedulerData = nullptr;
+ delete pMostUrgent;
+ }
+ else
+ AppendSchedulerData(rSchedCtx, pMostUrgent);
+
// this just happens for nested calls, which renders all accounting
// invalid, so we just enforce a rescheduling!
- if ( pMostUrgent == pSVData->maSchedCtx.mpSchedulerStack )
+ if (rSchedCtx.mpSchedulerStackTop != pSchedulerData)
{
- pSchedulerData = pSVData->maSchedCtx.mpSchedulerStack;
- pSVData->maSchedCtx.mpSchedulerStack = pSchedulerData->mpNext;
- AppendSchedulerData( rSchedCtx, pSchedulerData );
UpdateSystemTimer( rSchedCtx, ImmediateTimeoutMs, true,
tools::Time::GetSystemTicks() );
}
- else
+ else if (bTaskAlive)
{
- // Since we can restart tasks, round-robin all non-last tasks
- if ( pMostUrgent->mpNext )
- {
- DropSchedulerData( rSchedCtx, pPrevMostUrgent, pMostUrgent );
- AppendSchedulerData( rSchedCtx, pMostUrgent );
- }
-
- if ( pMostUrgent->mpTask && pMostUrgent->mpTask->IsActive() )
- {
- pMostUrgent->mnUpdateTime = nTime;
- nReadyPeriod = pMostUrgent->mpTask->UpdateMinPeriod( nMinPeriod, nTime );
- if ( nMinPeriod > nReadyPeriod )
- nMinPeriod = nReadyPeriod;
- UpdateSystemTimer( rSchedCtx, nMinPeriod, false, nTime );
- }
+ pMostUrgent->mnUpdateTime = nTime;
+ nReadyPeriod = pMostUrgent->mpTask->UpdateMinPeriod( nMinPeriod, nTime );
+ if ( nMinPeriod > nReadyPeriod )
+ nMinPeriod = nReadyPeriod;
+ UpdateSystemTimer( rSchedCtx, nMinPeriod, false, nTime );
}
}
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index ec151895815a..ca3848d58a22 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -503,21 +503,24 @@ void Scheduler::ProcessEventsToIdle()
// events were processed at some point, but our check can't prevent further
// processing in the main thread, which may add new events, so skip it.
const ImplSVData* pSVData = ImplGetSVData();
- if ( !pSVData->mpDefInst->IsMainThread() )
+ if (!pSVData->mpDefInst->IsMainThread())
return;
- const ImplSchedulerData* pSchedulerData = pSVData->maSchedCtx.mpFirstSchedulerData;
- while ( pSchedulerData )
+ for (int nTaskPriority = 0; nTaskPriority < PRIO_COUNT; ++nTaskPriority)
{
- if ( pSchedulerData->mpTask && !pSchedulerData->mbInScheduler )
+ const ImplSchedulerData* pSchedulerData = pSVData->maSchedCtx.mpFirstSchedulerData[nTaskPriority];
+ while (pSchedulerData)
{
- Idle *pIdle = dynamic_cast<Idle*>( pSchedulerData->mpTask );
- if ( pIdle && pIdle->IsActive() )
+ if (pSchedulerData->mpTask && !pSchedulerData->mbInScheduler)
{
- SAL_WARN( "vcl.schedule", "Unprocessed Idle: "
- << pIdle << " " << pIdle->GetDebugName() );
+ Idle *pIdle = dynamic_cast<Idle*>(pSchedulerData->mpTask);
+ if (pIdle && pIdle->IsActive())
+ {
+ SAL_WARN("vcl.schedule", "Unprocessed Idle: "
+ << pIdle << " " << pIdle->GetDebugName());
+ }
}
+ pSchedulerData = pSchedulerData->mpNext;
}
- pSchedulerData = pSchedulerData->mpNext;
}
#endif
}