27#include <com/sun/star/uno/Exception.hpp>
45template<
typename charT,
typename traits >
47 std::basic_ostream<charT, traits> & stream,
const Task& task )
52 return stream <<
" (nullptr)";
64template<
typename charT,
typename traits >
66 std::basic_ostream<charT, traits> & stream,
const Timer& timer )
68 bool bIsIdle = (
dynamic_cast<const Idle*
>( &timer ) !=
nullptr);
69 stream << (bIsIdle ?
"Idle " :
"Timer")
72 if (
nullptr == name )
78 stream <<
" (" << &timer <<
")";
82template<
typename charT,
typename traits >
84 std::basic_ostream<charT, traits> & stream,
const Idle& idle )
86 return stream << static_cast<const Timer*>( &idle );
89template<
typename charT,
typename traits >
104 assert( pSVData !=
nullptr );
111 int nTaskPriority = 0;
112#if OSL_DEBUG_LEVEL > 0
113 sal_uInt32 nTasks = 0;
114 for (nTaskPriority = 0; nTaskPriority <
PRIO_COUNT; ++nTaskPriority)
117 while ( pSchedulerData )
120 pSchedulerData = pSchedulerData->
mpNext;
124 "DeInit the scheduler - pending tasks: " << nTasks );
139#if OSL_DEBUG_LEVEL > 0
140 sal_uInt32 nActiveTasks = 0, nIgnoredTasks = 0;
147 while ( pSchedulerData )
154#if OSL_DEBUG_LEVEL > 0
155 const char *sIgnored =
"";
160 || !strcmp( pTask->
GetDebugName(),
"desktop::Desktop m_firstRunTimer" )
161 || !strcmp( pTask->
GetDebugName(),
"DrawWorkStartupTimer" )
162 || !strcmp( pTask->
GetDebugName(),
"editeng::ImpEditEngine aOnlineSpellTimer" )
163 || !strcmp( pTask->
GetDebugName(),
"sc ScModule IdleTimer" )
164 || !strcmp( pTask->
GetDebugName(),
"sd::CacheConfiguration maReleaseTimer" )
165 || !strcmp( pTask->
GetDebugName(),
"svtools::GraphicCache maReleaseTimer" )
166 || !strcmp( pTask->
GetDebugName(),
"svtools::GraphicObject mpSwapOutTimer" )
167 || !strcmp( pTask->
GetDebugName(),
"svx OLEObjCache pTimer UnloadCheck" )
168 || !strcmp( pTask->
GetDebugName(),
"vcl SystemDependentDataBuffer aSystemDependentDataBuffer" )
171 sIgnored =
" (ignored)";
174 const Timer *timer =
dynamic_cast<Timer*
>( pTask );
176 SAL_WARN(
"vcl.schedule.deinit",
"DeInit task: " << *timer << sIgnored );
178 SAL_WARN(
"vcl.schedule.deinit",
"DeInit task: " << *pTask << sIgnored );
186 pSchedulerData = pSchedulerData->
mpNext;
187 delete pDeleteSchedulerData;
194#if OSL_DEBUG_LEVEL > 0
195 SAL_INFO(
"vcl.schedule.deinit",
"DeInit the scheduler - finished" );
196 SAL_WARN_IF( 0 != nActiveTasks,
"vcl.schedule.deinit",
"DeInit active tasks: "
197 << nActiveTasks <<
" (ignored: " << nIgnoredTasks <<
")" );
201 for (nTaskPriority = 0; nTaskPriority <
PRIO_COUNT; ++nTaskPriority)
212 assert( pSVData !=
nullptr );
219 assert( pSVData !=
nullptr );
247 sal_uInt64 nProposedTimeout = nTime + nMS;
253 if (bForce || nProposedTimeout < nCurTimeout || (!nMS && rSchedCtx.
mnTimerPeriod))
255 SAL_INFO(
"vcl.schedule",
" Starting scheduler system timer (" << nMS <<
"ms)" );
275 const sal_uInt64 nMinPeriod,
276 const bool bForce,
const sal_uInt64 nTime )
280 SAL_INFO(
"vcl.schedule",
" Stopping system timer");
292 assert(pSchedulerData->
mpTask);
294 pSchedulerData->
mpNext =
nullptr;
296 const int nTaskPriority =
static_cast<int>(pSchedulerData->
mePriority);
313 assert( pSchedulerData );
314 if ( pPrevSchedulerData )
315 assert( pPrevSchedulerData->
mpNext == pSchedulerData );
320 if ( pPrevSchedulerData )
321 pPrevSchedulerData->
mpNext = pSchedulerDataNext;
324 if ( !pSchedulerDataNext )
326 return pSchedulerDataNext;
353 int nMostUrgentPriority = 0;
357 int nTaskPriority = 0;
359 for (; nTaskPriority <
PRIO_COUNT; ++nTaskPriority)
369 pPrevSchedulerData =
nullptr;
370 while (pSchedulerData)
376 << pSchedulerData <<
" " << *pSchedulerData <<
" " << *timer );
377 else if ( pSchedulerData->
mpTask )
379 << pSchedulerData <<
" " << *pSchedulerData
380 <<
" " << *pSchedulerData->
mpTask );
383 << pSchedulerData <<
" " << *pSchedulerData <<
" (to be deleted)" );
391 if ( pSchedulerData->
mpTask )
393 delete pSchedulerData;
394 pSchedulerData = pSchedulerDataNext;
398 assert(pSchedulerData->
mpTask);
406 pPrevMostUrgent = pPrevSchedulerData;
407 pMostUrgent = pSchedulerData;
408 nMostUrgentPriority = nTaskPriority;
416 else if (nMinPeriod > nReadyPeriod)
417 nMinPeriod = nReadyPeriod;
420 pPrevSchedulerData = pSchedulerData;
421 pSchedulerData = pSchedulerData->
mpNext;
430 "Calculated minimum timeout as " << nMinPeriod <<
" of " << nTasks <<
" tasks");
437 << pMostUrgent <<
" invoke-in " << *pMostUrgent->
mpTask );
460 bool bDelayInvoking = bIsHighPriorityIdle &&
475 <<
" delayed, system events pending" );
483 catch (css::uno::Exception&)
488 catch (std::exception& e)
490 SAL_WARN(
"vcl.schedule",
"Uncaught " <<
typeid(e).
name() <<
" " << e.what());
495 SAL_WARN(
"vcl.schedule",
"Uncaught exception during Task::Invoke()!");
504 << pMostUrgent <<
" invoke-out" );
508 assert(pSchedulerData == pMostUrgent);
533 if ( nMinPeriod > nReadyPeriod )
534 nMinPeriod = nReadyPeriod;
580 pSchedulerData->
mpTask =
this;
611 "Stop the task before changing the priority, as it will just "
612 "change after the task was scheduled with the old prio!");
634 : mpSchedulerData( nullptr )
635 , mpDebugName( pDebugName )
644 : mpSchedulerData( nullptr )
645 , mpDebugName( rTask.mpDebugName )
646 , mePriority( rTask.mePriority )
std::ostream & operator<<(std::ostream &rStrm, const glm::mat4 &rMatrix)
static bool AnyInput(VclInputFlags nType=VCL_INPUT_ANY)
Determine if there are any pending input events.
An idle is a timer to be scheduled immediately.
virtual SalTimer * CreateSalTimer()=0
void SetCallback(SALTIMERPROC pProc)
virtual void Start(sal_uInt64 nMS)=0
static void SetDeterministicMode(bool bDeterministic)
Control the deterministic mode.
static bool GetDeterministicMode()
Return the current state of deterministic mode.
static void ImplDeInitScheduler()
static void CallbackTaskScheduling()
System timer callback function, which processes one LO task.
static constexpr sal_uInt64 InfiniteTimeoutMs
static constexpr sal_uInt64 ImmediateTimeoutMs
static void Wakeup()
Wakes up the scheduler.
static void UpdateSystemTimer(ImplSchedulerContext &rSchedCtx, sal_uInt64 nMinPeriod, bool bForce, sal_uInt64 nTime)
static void ProcessEventsToIdle()
Process all events until none is pending.
static void ImplStartTimer(sal_uInt64 nMS, bool bForce, sal_uInt64 nTime)
Start a new timer if we need to for nMS duration.
static constexpr unsigned int nDefaultTimeSlice
static unsigned int m_nTimeSlice
virtual sal_uInt64 UpdateMinPeriod(sal_uInt64 nTimeNow) const =0
How long (in MS) until the Task is ready to be dispatched?
bool mbActive
Currently in the scheduler.
void SetPriority(TaskPriority ePriority)
virtual ~Task() COVERITY_NOEXCEPT_FALSE
const char * GetDebugName() const
const char * mpDebugName
Useful for debugging.
ImplSchedulerData * mpSchedulerData
Pointer to the element in scheduler list.
TaskPriority mePriority
Task priority.
Task & operator=(const Task &rTask)
TaskPriority GetPriority() const
virtual void Start(bool bStartTimer=true)
Schedules the task for execution.
friend struct ImplSchedulerData
void SetStatic()
This function must be called for static tasks, so the Task destructor ignores the scheduler mutex,...
Task(const char *pDebugName)
virtual void SetDeletionFlags()
static void StartTimer(sal_uInt64 nMS)
sal_uInt64 GetTimeout() const
#define DBG_TESTSOLARMUTEX()
#define TOOLS_WARN_EXCEPTION(area, stream)
Reference< XOutputStream > stream
#define SAL_INFO_IF(condition, area, stream)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
static void AppendSchedulerData(ImplSchedulerContext &rSchedCtx, ImplSchedulerData *const pSchedulerData)
static bool g_bDeterministicMode
static ImplSchedulerData * DropSchedulerData(ImplSchedulerContext &rSchedCtx, ImplSchedulerData *const pPrevSchedulerData, const ImplSchedulerData *const pSchedulerData, const int nTaskPriority)
ImplSchedulerContext maSchedCtx
ImplSchedulerData * mpLastSchedulerData[PRIO_COUNT]
last item of each mpFirstSchedulerData list
bool mbActive
is the scheduler active?
ImplSchedulerData * mpFirstSchedulerData[PRIO_COUNT]
list of all active tasks per priority
ImplSchedulerData * mpSchedulerStack
stack of invoked tasks
SalTimer * mpSalTimer
interface to sal event loop / system timer
sal_uInt64 mnTimerStart
start time of the timer
std::mutex maMutex
the "scheduler mutex" (see vcl/README.scheduler)
sal_uInt64 mnTimerPeriod
current timer period
ImplSchedulerData * mpSchedulerStackTop
top most stack entry to detect needed rescheduling during pop
sal_uInt64 mnUpdateTime
Last Update Time.
ImplSchedulerData * mpNext
Pointer to the next element in list.
bool mbInScheduler
Is the Task currently processed / on the stack?
Task * mpTask
Pointer to VCL Task instance.
TaskPriority mePriority
Task priority.
ImplSVData * ImplGetSVData()
@ LOWEST
Low, very idle cleanup tasks.
@ HIGH_IDLE
Important idle events to be run before processing drawing events.