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(),
"ImplHandleMouseMsg SalData::mpMouseLeaveTimer" )
164 || !strcmp( pTask->
GetDebugName(),
"sc ScModule IdleTimer" )
165 || !strcmp( pTask->
GetDebugName(),
"sd::CacheConfiguration maReleaseTimer" )
166 || !strcmp( pTask->
GetDebugName(),
"svtools::GraphicCache maReleaseTimer" )
167 || !strcmp( pTask->
GetDebugName(),
"svtools::GraphicObject mpSwapOutTimer" )
168 || !strcmp( pTask->
GetDebugName(),
"svx OLEObjCache pTimer UnloadCheck" )
169 || !strcmp( pTask->
GetDebugName(),
"vcl SystemDependentDataBuffer aSystemDependentDataBuffer" )
172 sIgnored =
" (ignored)";
175 const Timer *timer =
dynamic_cast<Timer*
>( pTask );
177 SAL_WARN(
"vcl.schedule.deinit",
"DeInit task: " << *timer << sIgnored );
179 SAL_WARN(
"vcl.schedule.deinit",
"DeInit task: " << *pTask << sIgnored );
187 pSchedulerData = pSchedulerData->
mpNext;
188 delete pDeleteSchedulerData;
195#if OSL_DEBUG_LEVEL > 0
196 SAL_INFO(
"vcl.schedule.deinit",
"DeInit the scheduler - finished" );
197 SAL_WARN_IF( 0 != nActiveTasks,
"vcl.schedule.deinit",
"DeInit active tasks: "
198 << nActiveTasks <<
" (ignored: " << nIgnoredTasks <<
")" );
202 for (nTaskPriority = 0; nTaskPriority <
PRIO_COUNT; ++nTaskPriority)
213 assert( pSVData !=
nullptr );
220 assert( pSVData !=
nullptr );
248 sal_uInt64 nProposedTimeout = nTime + nMS;
254 if (bForce || nProposedTimeout < nCurTimeout || (!nMS && rSchedCtx.
mnTimerPeriod))
256 SAL_INFO(
"vcl.schedule",
" Starting scheduler system timer (" << nMS <<
"ms)" );
276 const sal_uInt64 nMinPeriod,
277 const bool bForce,
const sal_uInt64 nTime )
281 SAL_INFO(
"vcl.schedule",
" Stopping system timer");
293 assert(pSchedulerData->
mpTask);
295 pSchedulerData->
mpNext =
nullptr;
297 const int nTaskPriority =
static_cast<int>(pSchedulerData->
mePriority);
314 assert( pSchedulerData );
315 if ( pPrevSchedulerData )
316 assert( pPrevSchedulerData->
mpNext == pSchedulerData );
321 if ( pPrevSchedulerData )
322 pPrevSchedulerData->
mpNext = pSchedulerDataNext;
325 if ( !pSchedulerDataNext )
327 return pSchedulerDataNext;
354 int nMostUrgentPriority = 0;
358 int nTaskPriority = 0;
360 for (; nTaskPriority <
PRIO_COUNT; ++nTaskPriority)
370 pPrevSchedulerData =
nullptr;
371 while (pSchedulerData)
377 << pSchedulerData <<
" " << *pSchedulerData <<
" " << *timer );
378 else if ( pSchedulerData->
mpTask )
380 << pSchedulerData <<
" " << *pSchedulerData
381 <<
" " << *pSchedulerData->
mpTask );
384 << pSchedulerData <<
" " << *pSchedulerData <<
" (to be deleted)" );
392 if ( pSchedulerData->
mpTask )
394 delete pSchedulerData;
395 pSchedulerData = pSchedulerDataNext;
399 assert(pSchedulerData->
mpTask);
407 pPrevMostUrgent = pPrevSchedulerData;
408 pMostUrgent = pSchedulerData;
409 nMostUrgentPriority = nTaskPriority;
417 else if (nMinPeriod > nReadyPeriod)
418 nMinPeriod = nReadyPeriod;
421 pPrevSchedulerData = pSchedulerData;
422 pSchedulerData = pSchedulerData->
mpNext;
431 "Calculated minimum timeout as " << nMinPeriod <<
" of " << nTasks <<
" tasks");
438 << pMostUrgent <<
" invoke-in " << *pMostUrgent->
mpTask );
461 bool bDelayInvoking = bIsHighPriorityIdle &&
476 <<
" delayed, system events pending" );
484 catch (css::uno::Exception&)
489 catch (std::exception& e)
491 SAL_WARN(
"vcl.schedule",
"Uncaught " <<
typeid(e).
name() <<
" " << e.what());
496 SAL_WARN(
"vcl.schedule",
"Uncaught exception during Task::Invoke()!");
505 << pMostUrgent <<
" invoke-out" );
509 assert(pSchedulerData == pMostUrgent);
534 if ( nMinPeriod > nReadyPeriod )
535 nMinPeriod = nReadyPeriod;
581 pSchedulerData->
mpTask =
this;
612 "Stop the task before changing the priority, as it will just "
613 "change after the task was scheduled with the old prio!");
635 : mpSchedulerData( nullptr )
636 , mpDebugName( pDebugName )
645 : mpSchedulerData( nullptr )
646 , mpDebugName( rTask.mpDebugName )
647 , 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.