27 #include <com/sun/star/uno/Exception.hpp>
45 template<
typename charT,
typename traits >
47 std::basic_ostream<charT, traits> & stream,
const Task& task )
52 return stream <<
" (nullptr)";
54 return stream <<
" " << name;
64 template<
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 )
73 stream <<
" (nullptr)";
75 stream <<
" " << name;
78 stream <<
" (" << &timer <<
")";
82 template<
typename charT,
typename traits >
84 std::basic_ostream<charT, traits> & stream,
const Idle& idle )
86 return stream << static_cast<const Timer*>( &idle );
89 template<
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;
192 if (nTaskPriority < PRIO_COUNT)
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)" );
267 g_bDeterministicMode = bDeterministic;
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)
363 pPrevSchedulerData =
nullptr;
364 while (pSchedulerData)
370 << pSchedulerData <<
" " << *pSchedulerData <<
" " << *timer );
371 else if ( pSchedulerData->
mpTask )
373 << pSchedulerData <<
" " << *pSchedulerData
374 <<
" " << *pSchedulerData->
mpTask );
377 << pSchedulerData <<
" " << *pSchedulerData <<
" (to be deleted)" );
385 if ( pSchedulerData->
mpTask )
387 delete pSchedulerData;
388 pSchedulerData = pSchedulerDataNext;
392 assert(pSchedulerData->
mpTask);
400 pPrevMostUrgent = pPrevSchedulerData;
401 pMostUrgent = pSchedulerData;
402 nMostUrgentPriority = nTaskPriority;
410 else if (nMinPeriod > nReadyPeriod)
411 nMinPeriod = nReadyPeriod;
414 pPrevSchedulerData = pSchedulerData;
415 pSchedulerData = pSchedulerData->
mpNext;
429 <<
" idle priority task " << pMostUrgent <<
" delayed, system events pending" );
430 pMostUrgent =
nullptr;
436 "Calculated minimum timeout as " << nMinPeriod <<
" of " << nTasks <<
" tasks");
443 << pMostUrgent <<
" invoke-in " << *pMostUrgent->
mpTask );
474 catch (css::uno::Exception&)
479 catch (std::exception& e)
481 SAL_WARN(
"vcl.schedule",
"Uncaught " <<
typeid(e).name() <<
" " << e.what());
486 SAL_WARN(
"vcl.schedule",
"Uncaught exception during Task::Invoke()!");
495 << pMostUrgent <<
" invoke-out" );
499 assert(pSchedulerData == pMostUrgent);
524 if ( nMinPeriod > nReadyPeriod )
525 nMinPeriod = nReadyPeriod;
571 pSchedulerData->
mpTask =
this;
602 "Stop the task before changing the priority, as it will just "
603 "change after the task was scheduled with the old prio!");
625 : mpSchedulerData( nullptr )
626 , mpDebugName( pDebugName )
635 : mpSchedulerData( nullptr )
636 , mpDebugName( rTask.mpDebugName )
637 , mePriority( rTask.mePriority )
static void AppendSchedulerData(ImplSchedulerContext &rSchedCtx, ImplSchedulerData *const pSchedulerData)
static void Wakeup()
Wakes up the scheduler.
#define SAL_INFO_IF(condition, area, stream)
Important idle events to be run before processing drawing events.
TaskPriority mePriority
Task priority.
void SetCallback(SALTIMERPROC pProc)
SalTimer * mpSalTimer
interface to sal event loop / system timer
ImplSchedulerData * mpFirstSchedulerData[PRIO_COUNT]
list of all active tasks per priority
sal_uInt64 mnUpdateTime
Last Update Time.
virtual void Start(bool bStartTimer=true)
Schedules the task for execution.
ImplSchedulerData * mpSchedulerData
Pointer to the element in scheduler list.
virtual SalTimer * CreateSalTimer()=0
static unsigned int m_nTimeSlice
static void ImplStartTimer(sal_uInt64 nMS, bool bForce, sal_uInt64 nTime)
Start a new timer if we need to for nMS duration.
ImplSchedulerData * mpNext
Pointer to the next element in list.
ImplSVData * ImplGetSVData()
virtual void Start(sal_uInt64 nMS)=0
#define TOOLS_WARN_EXCEPTION(area, stream)
static void UpdateSystemTimer(ImplSchedulerContext &rSchedCtx, sal_uInt64 nMinPeriod, bool bForce, sal_uInt64 nTime)
sal_uInt64 GetTimeout() const
Task(const char *pDebugName)
static bool AnyInput(VclInputFlags nType=VCL_INPUT_ANY)
Determine if there are any pending input events.
TaskPriority mePriority
Task priority.
Task * mpTask
Pointer to VCL Task instance.
ImplSchedulerData * mpSchedulerStack
stack of invoked tasks
void SetStatic()
This function must be called for static tasks, so the Task destructor ignores the scheduler mutex...
ImplSchedulerData * mpLastSchedulerData[PRIO_COUNT]
last item of each mpFirstSchedulerData list
bool mbActive
Currently in the scheduler.
TaskPriority GetPriority() const
static constexpr sal_uInt64 ImmediateTimeoutMs
Task & operator=(const Task &rTask)
ImplSchedulerContext maSchedCtx
static constexpr unsigned int nDefaultTimeSlice
static bool g_bDeterministicMode
static bool GetDeterministicMode()
Return the current state of deterministic mode.
sal_uInt64 mnTimerStart
start time of the timer
static constexpr sal_uInt64 InfiniteTimeoutMs
virtual void SetDeletionFlags()
virtual ~Task() COVERITY_NOEXCEPT_FALSE
#define SAL_WARN_IF(condition, area, stream)
static void StartTimer(sal_uInt64 nMS)
static void CallbackTaskScheduling()
System timer callback function, which processes one LO task.
#define SAL_INFO(area, stream)
bool mbActive
is the scheduler active?
if(aStr!=aBuf) UpdateName_Impl(m_xFollowLb.get()
static void SetDeterministicMode(bool bDeterministic)
Control the deterministic mode.
static void ProcessEventsToIdle()
Process all events until none is pending.
ImplSchedulerData * mpSchedulerStackTop
top most stack entry to detect needed rescheduling during pop
friend struct ImplSchedulerData
#define SAL_WARN(area, stream)
virtual sal_uInt64 UpdateMinPeriod(sal_uInt64 nTimeNow) const =0
How long (in MS) until the Task is ready to be dispatched?
void SetPriority(TaskPriority ePriority)
#define DBG_TESTSOLARMUTEX()
sal_uInt64 mnTimerPeriod
current timer period
const char * mpDebugName
Useful for debugging.
VCL_DLLPUBLIC std::ostream & operator<<(std::ostream &os, const ErrCode &err)
const char * GetDebugName() const
static void ImplDeInitScheduler()
An idle is a timer to be scheduled immediately.
std::mutex maMutex
the "scheduler mutex" (see vcl/README.scheduler)
bool mbInScheduler
Is the Task currently processed / on the stack?
static ImplSchedulerData * DropSchedulerData(ImplSchedulerContext &rSchedCtx, ImplSchedulerData *const pPrevSchedulerData, const ImplSchedulerData *const pSchedulerData, const int nTaskPriority)
bool m_bDetectedRangeSegmentation false