summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/vcl/idle.hxx49
-rw-r--r--include/vcl/scheduler.hxx92
-rw-r--r--include/vcl/timer.hxx43
-rw-r--r--sfx2/source/appl/appinit.cxx6
-rw-r--r--toolkit/source/awt/vclxtoolkit.cxx4
-rw-r--r--vcl/Library_vcl.mk1
-rw-r--r--vcl/inc/svdata.hxx3
-rw-r--r--vcl/source/app/idle.cxx205
-rw-r--r--vcl/source/app/scheduler.cxx235
-rw-r--r--vcl/source/app/svapp.cxx14
-rw-r--r--vcl/source/app/svmain.cxx6
-rw-r--r--vcl/source/app/timer.cxx305
12 files changed, 399 insertions, 564 deletions
diff --git a/include/vcl/idle.hxx b/include/vcl/idle.hxx
index 3a63e6ef286a..9cb734546fb0 100644
--- a/include/vcl/idle.hxx
+++ b/include/vcl/idle.hxx
@@ -21,62 +21,23 @@
#define INCLUDED_VCL_IDLE_HXX
#include <tools/link.hxx>
-#include <tools/solar.h>
-#include <vcl/dllapi.h>
+#include <vcl/scheduler.hxx>
-struct ImplIdleData;
-struct ImplSVData;
-
-enum class IdlePriority {
- HIGHEST = 0,
- HIGH = 1,
- REPAINT = 2,
- RESIZE = 3,
- MEDIUM = 3,
- LOW = 4,
- LOWER = 5,
- LOWEST = 6
-};
-
-class VCL_DLLPUBLIC Idle
+class VCL_DLLPUBLIC Idle : public Scheduler
{
protected:
- ImplIdleData* mpIdleData; // Pointer to element in idle list
- sal_Int32 miPriority; // Idle priority ( maybe divergent to default)
- IdlePriority meDefaultPriority; // Default idle priority
- bool mbActive; // Currently in the scheduler
Link maIdleHdl; // Callback Link
- friend struct ImplIdleData;
-
public:
Idle();
Idle( const Idle& rIdle );
- virtual ~Idle();
-
- void SetPriority( IdlePriority ePriority );
- void SetSchedulingPriority( sal_Int32 iPriority );
- sal_Int32 GetPriority() const { return miPriority; }
- IdlePriority GetDefaultPriority() const { return meDefaultPriority; }
/// Make it possible to associate a callback with this idle handler
- /// of course, you can also sub-class and override 'DoIdle'
+ /// of course, you can also sub-class and override 'Invoke'
void SetIdleHdl( const Link& rLink ) { maIdleHdl = rLink; }
const Link& GetIdleHdl() const { return maIdleHdl; }
-
- // Call idle handler
- virtual void DoIdle();
-
- void Start();
- void Stop();
-
- bool IsActive() const { return mbActive; }
-
- Idle& operator=( const Idle& rIdle );
- static void ImplDeInitIdle();
-
- /// Process all pending idle tasks ahead of time in priority order.
- static void ProcessAllIdleHandlers();
+ virtual void Invoke() SAL_OVERRIDE;
+ Idle& operator=( const Idle& rIdle );
};
#endif // INCLUDED_VCL_IDLE_HXX
diff --git a/include/vcl/scheduler.hxx b/include/vcl/scheduler.hxx
new file mode 100644
index 000000000000..a18aa71e815a
--- /dev/null
+++ b/include/vcl/scheduler.hxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_SCHEDULER_HXX
+#define INCLUDED_VCL_SCHEDULER_HXX
+
+#include <vcl/dllapi.h>
+
+struct ImplSVData;
+class Scheduler;
+struct ImplSchedulerData
+{
+ ImplSchedulerData* mpNext; // Pointer to the next element in list
+ Scheduler* mpScheduler; // Pointer to VCL Idle instance
+ bool mbDelete; // Destroy this idle?
+ bool mbInScheduler; // Idle handler currently processed?
+ sal_uLong mnUpdateTime; // Last Update Time
+ sal_uLong mnUpdateStack; // Update Stack on stack
+
+ void Invoke();
+
+ static ImplSchedulerData *GetMostImportantTask( bool bTimer );
+};
+
+enum class SchedulerPriority {
+ HIGHEST = 0,
+ HIGH = 1,
+ REPAINT = 2,
+ RESIZE = 3,
+ MEDIUM = 3,
+ LOW = 4,
+ LOWER = 5,
+ LOWEST = 6
+};
+
+class VCL_DLLPUBLIC Scheduler
+{
+protected:
+ ImplSchedulerData* mpSchedulerData; // Pointer to element in idle list
+ sal_Int32 miPriority; // Idle priority ( maybe divergent to default)
+ SchedulerPriority meDefaultPriority; // Default idle priority
+ bool mbActive; // Currently in the scheduler
+
+ friend struct ImplSchedulerData;
+ virtual void SetDeletionFlags();
+ virtual bool ReadyForSchedule( bool bTimer ) { return !bTimer; }
+
+public:
+ Scheduler();
+ Scheduler( const Scheduler& rScheduler );
+ virtual ~Scheduler();
+
+ void SetPriority( SchedulerPriority ePriority );
+ void SetSchedulingPriority( sal_Int32 iPriority );
+ sal_Int32 GetPriority() const { return miPriority; }
+ SchedulerPriority GetDefaultPriority() const { return meDefaultPriority; }
+
+ // Call idle handler
+ virtual void Invoke() = 0;
+
+ virtual void Start();
+ virtual void Stop();
+
+ bool IsActive() const { return mbActive; }
+
+ Scheduler& operator=( const Scheduler& Scheduler );
+ static void ImplDeInitScheduler();
+
+ /// Process all pending idle tasks ahead of time in priority order.
+ static void CallbackTaskScheduling();
+ static void ProcessTaskScheduling( bool bTimer );
+};
+
+#endif // INCLUDED_VCL_SCHEDULER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/vcl/timer.hxx b/include/vcl/timer.hxx
index 2d0f31076db0..01fd36c82a16 100644
--- a/include/vcl/timer.hxx
+++ b/include/vcl/timer.hxx
@@ -21,50 +21,32 @@
#define INCLUDED_VCL_TIMER_HXX
#include <tools/link.hxx>
-#include <tools/solar.h>
-#include <vcl/dllapi.h>
+#include <vcl/scheduler.hxx>
-struct ImplTimerData;
-struct ImplSVData;
-
-/// Base-class for timers - usually a simple, one-shot timeout
-class VCL_DLLPUBLIC Timer
+class VCL_DLLPUBLIC Timer : public Scheduler
{
protected:
- ImplTimerData* mpTimerData;
+ Link maTimeoutHdl; // Callback Link
sal_uLong mnTimeout;
- bool mbActive;
bool mbAuto;
- Link maTimeoutHdl;
- friend struct ImplTimerData;
+ void SetDeletionFlags() SAL_OVERRIDE;
+ bool ReadyForSchedule( bool bTimer ) SAL_OVERRIDE;
public:
- Timer();
- Timer( const Timer& rTimer );
- virtual ~Timer();
-
- virtual void Timeout();
+ Timer();
+ Timer( const Timer& rTimer );
- void Start();
- void Stop();
-
- /// set the timeout in milliseconds
+ /// Make it possible to associate a callback with this timer handler
+ /// of course, you can also sub-class and override 'Invoke'
void SetTimeout( sal_uLong nTimeoutMs );
sal_uLong GetTimeout() const { return mnTimeout; }
- bool IsActive() const { return mbActive; }
-
- /// Make it possible to associate a callback with this timeout
void SetTimeoutHdl( const Link& rLink ) { maTimeoutHdl = rLink; }
const Link& GetTimeoutHdl() const { return maTimeoutHdl; }
-
+ virtual void Invoke() SAL_OVERRIDE;
+ virtual void Timeout() { Invoke(); }
Timer& operator=( const Timer& rTimer );
-
- /// @internal
- static void ImplDeInitTimer();
- static void ImplTimerCallbackProc();
- static bool TimerReady();
- static bool CheckExpiredTimer(const bool bDoInvoke);
+ void Start() SAL_OVERRIDE;
};
/// An auto-timer is a multi-shot timer re-emitting itself at
@@ -77,6 +59,7 @@ public:
AutoTimer& operator=( const AutoTimer& rTimer );
};
+
#endif // INCLUDED_VCL_TIMER_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/appl/appinit.cxx b/sfx2/source/appl/appinit.cxx
index edc31e094955..270ef7aa28a7 100644
--- a/sfx2/source/appl/appinit.cxx
+++ b/sfx2/source/appl/appinit.cxx
@@ -46,8 +46,7 @@
#include <cppuhelper/supportsservice.hxx>
#include <vcl/edit.hxx>
-#include <vcl/timer.hxx>
-#include <vcl/idle.hxx>
+#include <vcl/scheduler.hxx>
#include <sfx2/unoctitm.hxx>
#include "app.hrc"
@@ -110,8 +109,7 @@ void SAL_CALL SfxTerminateListener_Impl::notifyTermination( const EventObject& a
// Timers may access the SfxApplication and are only deleted in
// Application::Quit(), which is asynchronous (PostUserEvent) - disable!
- Timer::ImplDeInitTimer();
- Idle::ImplDeInitIdle();
+ Scheduler::ImplDeInitScheduler();
SfxApplication* pApp = SfxGetpApp();
pApp->Broadcast( SfxSimpleHint( SFX_HINT_DEINITIALIZING ) );
diff --git a/toolkit/source/awt/vclxtoolkit.cxx b/toolkit/source/awt/vclxtoolkit.cxx
index b720f96c7aab..006a216fa634 100644
--- a/toolkit/source/awt/vclxtoolkit.cxx
+++ b/toolkit/source/awt/vclxtoolkit.cxx
@@ -91,7 +91,7 @@
#include <vcl/fixed.hxx>
#include <vcl/floatwin.hxx>
#include <vcl/group.hxx>
-#include <vcl/idle.hxx>
+#include <vcl/scheduler.hxx>
#include <vcl/imgctrl.hxx>
#include <vcl/longcurr.hxx>
#include <vcl/lstbox.hxx>
@@ -1869,7 +1869,7 @@ void SAL_CALL VCLXToolkit::processEventsToIdle()
throw (::com::sun::star::uno::RuntimeException, std::exception)
{
SolarMutexGuard aSolarGuard;
- Idle::ProcessAllIdleHandlers();
+ Scheduler::ProcessTaskScheduling(false);
}
}
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index e468df4e102d..08b08e9c022d 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -329,6 +329,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/app/idle \
vcl/source/app/idlemgr \
vcl/source/app/salvtables \
+ vcl/source/app/scheduler \
vcl/source/app/session \
vcl/source/app/settings \
vcl/source/app/IconThemeInfo \
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index b22717386d31..132c27289b9f 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -311,8 +311,7 @@ struct ImplSVData
bool mbDeInit; // Is VCL deinitializing
sal_uLong mnThreadCount; // is VCL MultiThread enabled
ImplConfigData* mpFirstConfigData; // pointer to the first config block
- ImplTimerData* mpFirstTimerData; // list of all running timers
- ImplIdleData* mpFirstIdleData; // list of all running idles
+ ImplSchedulerData* mpFirstSchedulerData; // list of all running tasks
SalTimer* mpSalTimer; // interface to sal event loop/timers
SalI18NImeStatus* mpImeStatus; // interface to ime status window
SalSystem* mpSalSystem; // SalSystem interface
diff --git a/vcl/source/app/idle.cxx b/vcl/source/app/idle.cxx
index 09ffbc77af92..7fe239d199f7 100644
--- a/vcl/source/app/idle.cxx
+++ b/vcl/source/app/idle.cxx
@@ -17,220 +17,27 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#include <vcl/svapp.hxx>
#include <vcl/idle.hxx>
-#include <vcl/timer.hxx>
-#include <svdata.hxx>
-#include <salinst.hxx>
-
-struct ImplIdleData
-{
- ImplIdleData* mpNext; // Pointer to the next element in list
- Idle* mpIdle; // Pointer to VCL Idle instance
- bool mbDelete; // Destroy this idle?
- bool mbInIdle; // Idle handler currently processed?
-
- void Invoke()
- {
- if (mbDelete || mbInIdle )
- return;
-
- mpIdle->SetSchedulingPriority(static_cast<sal_Int32>(mpIdle->GetDefaultPriority()));
- mbDelete = true;
- mpIdle->mbActive = false;
-
- // invoke it
- mbInIdle = true;
- mpIdle->DoIdle();
- mbInIdle = false;
- }
-
- static ImplIdleData *GetFirstIdle()
- {
- ImplSVData* pSVData = ImplGetSVData();
- ImplIdleData *pMostUrgent = NULL;
-
- for ( ImplIdleData *p = pSVData->mpFirstIdleData; p; p = p->mpNext )
- {
- if ( !p->mpIdle || p->mbDelete )
- continue;
- if (!pMostUrgent)
- pMostUrgent = p;
- else
- {
- // Find the highest priority.
- // If the priority of the current idle is higher (numerical value is lower) than
- // the priority of the most urgent, the priority of most urgent is increased and
- // the current is the new most urgent. So starving is impossible.
- if ( p->mpIdle->GetPriority() < pMostUrgent->mpIdle->GetPriority() )
- {
- pMostUrgent->mpIdle->SetSchedulingPriority( pMostUrgent->mpIdle->GetPriority() - 1);
- pMostUrgent = p;
- }
- else
- p->mpIdle->SetSchedulingPriority( p->mpIdle->GetPriority() - 1);
- }
- }
-
- return pMostUrgent;
- }
-};
-
-void Idle::ImplDeInitIdle()
-{
- ImplSVData* pSVData = ImplGetSVData();
- ImplIdleData* pIdleData = pSVData->mpFirstIdleData;
-
- if ( pIdleData )
- {
- do
- {
- ImplIdleData* pTempIdleData = pIdleData;
- if ( pIdleData->mpIdle )
- {
- pIdleData->mpIdle->mbActive = false;
- pIdleData->mpIdle->mpIdleData = NULL;
- }
- pIdleData = pIdleData->mpNext;
- delete pTempIdleData;
- }
- while ( pIdleData );
-
- pSVData->mpFirstIdleData = NULL;
- }
-}
-
-void Idle::ProcessAllIdleHandlers()
-{
- // process all pending idle
- ImplIdleData* pIdleData = NULL;
- ImplIdleData* pPrevIdleData = NULL;
- ImplSVData* pSVData = ImplGetSVData();
- // timer can interrupt idle
- while (!Timer::TimerReady() && (pIdleData = ImplIdleData::GetFirstIdle()))
- {
- pIdleData->Invoke();
- }
-
- pIdleData = pSVData->mpFirstIdleData;
- while ( pIdleData )
- {
- // Should idle be released from scheduling?
- if ( pIdleData->mbDelete )
- {
- if ( pPrevIdleData )
- pPrevIdleData->mpNext = pIdleData->mpNext;
- else
- pSVData->mpFirstIdleData = pIdleData->mpNext;
- if ( pIdleData->mpIdle )
- pIdleData->mpIdle->mpIdleData = NULL;
- ImplIdleData* pTempIdleData = pIdleData;
- pIdleData = pIdleData->mpNext;
- delete pTempIdleData;
- }
- else
- {
- pPrevIdleData = pIdleData;
- pIdleData = pIdleData->mpNext;
- }
- }
-}
-
-void Idle::SetPriority( IdlePriority ePriority )
-{
- meDefaultPriority = ePriority;
-}
-
-void Idle::SetSchedulingPriority( sal_Int32 iPriority )
-{
- miPriority = iPriority;
-}
-
-void Idle::DoIdle()
+void Idle::Invoke()
{
maIdleHdl.Call( this );
}
-void Idle::Start()
-{
- // Mark timer active
- mbActive = true;
-
- ImplSVData* pSVData = ImplGetSVData();
- if ( !mpIdleData )
- {
- // insert Idle
- mpIdleData = new ImplIdleData;
- mpIdleData->mpIdle = this;
- mpIdleData->mbInIdle = false;
-
- // insert last due to SFX!
- ImplIdleData* pPrev = NULL;
- ImplIdleData* pData = pSVData->mpFirstIdleData;
- while ( pData )
- {
- pPrev = pData;
- pData = pData->mpNext;
- }
- mpIdleData->mpNext = NULL;
- if ( pPrev )
- pPrev->mpNext = mpIdleData;
- else
- pSVData->mpFirstIdleData = mpIdleData;
- }
- mpIdleData->mbDelete = false;
-}
-
-void Idle::Stop()
-{
- mbActive = false;
-
- if ( mpIdleData )
- mpIdleData->mbDelete = true;
-}
-
Idle& Idle::operator=( const Idle& rIdle )
{
- if ( IsActive() )
- Stop();
-
- mbActive = false;
- miPriority = rIdle.miPriority;
- meDefaultPriority = rIdle.meDefaultPriority;
- maIdleHdl = rIdle.maIdleHdl;
-
- if ( rIdle.IsActive() )
- Start();
-
+ Scheduler::operator=(rIdle);
+ maIdleHdl = rIdle.maIdleHdl;
return *this;
}
-Idle::Idle():
- mpIdleData(NULL),
- miPriority(static_cast<sal_Int32>(IdlePriority::HIGH)),
- meDefaultPriority(IdlePriority::HIGH),
- mbActive(false)
+Idle::Idle() : Scheduler()
{
}
-Idle::Idle( const Idle& rIdle ):
- mpIdleData(NULL),
- miPriority(rIdle.miPriority),
- meDefaultPriority(rIdle.meDefaultPriority),
- mbActive(false),
- maIdleHdl(rIdle.maIdleHdl)
+Idle::Idle( const Idle& rIdle ) : Scheduler(rIdle)
{
- if ( rIdle.IsActive() )
- Start();
+ maIdleHdl = rIdle.maIdleHdl;
}
-Idle::~Idle()
-{
- if ( mpIdleData )
- {
- mpIdleData->mbDelete = true;
- mpIdleData->mpIdle = NULL;
- }
-}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx
new file mode 100644
index 000000000000..e2465fecfda2
--- /dev/null
+++ b/vcl/source/app/scheduler.cxx
@@ -0,0 +1,235 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svdata.hxx>
+#include <tools/time.hxx>
+#include <vcl/scheduler.hxx>
+
+void ImplSchedulerData::Invoke()
+{
+ if (mbDelete || mbInScheduler )
+ return;
+
+ mpScheduler->SetSchedulingPriority(static_cast<sal_Int32>(mpScheduler->GetDefaultPriority()));
+ mpScheduler->SetDeletionFlags();
+
+ // invoke it
+ mbInScheduler = true;
+ mpScheduler->Invoke();
+ mbInScheduler = false;
+}
+
+ImplSchedulerData *ImplSchedulerData::GetMostImportantTask( bool bTimer )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplSchedulerData *pMostUrgent = NULL;
+
+ for ( ImplSchedulerData *p = pSVData->mpFirstSchedulerData; p; p = p->mpNext )
+ {
+ if ( !p->mpScheduler || p->mbDelete || p->mnUpdateStack >= pSVData->mnTimerUpdate || !p->mpScheduler->ReadyForSchedule( bTimer ) )
+ continue;
+ if (!pMostUrgent)
+ pMostUrgent = p;
+ else
+ {
+ // Find the highest priority.
+ // If the priority of the current idle is higher (numerical value is lower) than
+ // the priority of the most urgent, the priority of most urgent is increased and
+ // the current is the new most urgent. So starving is impossible.
+ if ( p->mpScheduler->GetPriority() < pMostUrgent->mpScheduler->GetPriority() )
+ {
+ pMostUrgent->mpScheduler->SetSchedulingPriority( pMostUrgent->mpScheduler->GetPriority());
+ pMostUrgent = p;
+ }
+ else
+ p->mpScheduler->SetSchedulingPriority( p->mpScheduler->GetPriority());
+ }
+ }
+
+ return pMostUrgent;
+}
+
+void Scheduler::SetDeletionFlags()
+{
+ mpSchedulerData->mbDelete = true;
+ mbActive = false;
+}
+
+void Scheduler::ImplDeInitScheduler()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplSchedulerData* pSchedulerData = pSVData->mpFirstSchedulerData;
+
+ if ( pSchedulerData )
+ {
+ do
+ {
+ ImplSchedulerData* pTempSchedulerData = pSchedulerData;
+ if ( pSchedulerData->mpScheduler )
+ {
+ pSchedulerData->mpScheduler->mbActive = false;
+ pSchedulerData->mpScheduler->mpSchedulerData = NULL;
+ }
+ pSchedulerData = pSchedulerData->mpNext;
+ delete pTempSchedulerData;
+ }
+ while ( pSchedulerData );
+
+ pSVData->mpFirstSchedulerData = NULL;
+ }
+}
+
+void Scheduler::CallbackTaskScheduling()
+{
+ Scheduler::ProcessTaskScheduling( true );
+}
+
+void Scheduler::ProcessTaskScheduling( bool bTimer )
+{
+ // process all pending Tasks
+ ImplSchedulerData* pSchedulerData = NULL;
+ ImplSchedulerData* pPrevSchedulerData = NULL;
+ ImplSVData* pSVData = ImplGetSVData();
+ pSVData->mnTimerUpdate++;
+
+ if ((pSchedulerData = ImplSchedulerData::GetMostImportantTask(bTimer)))
+ {
+ pSchedulerData->mnUpdateTime = tools::Time::GetSystemTicks();
+ pSchedulerData->Invoke();
+ }
+
+ pSchedulerData = pSVData->mpFirstSchedulerData;
+ while ( pSchedulerData )
+ {
+ // Should Task be released from scheduling?
+ if ( pSchedulerData->mbDelete )
+ {
+ if ( pPrevSchedulerData )
+ pPrevSchedulerData->mpNext = pSchedulerData->mpNext;
+ else
+ pSVData->mpFirstSchedulerData = pSchedulerData->mpNext;
+ if ( pSchedulerData->mpScheduler )
+ pSchedulerData->mpScheduler->mpSchedulerData = NULL;
+ ImplSchedulerData* pTempSchedulerData = pSchedulerData;
+ pSchedulerData = pSchedulerData->mpNext;
+ delete pTempSchedulerData;
+ }
+ else
+ {
+ if( !pSchedulerData->mbInScheduler )
+ pSchedulerData->mnUpdateStack = 0;
+ pPrevSchedulerData = pSchedulerData;
+ pSchedulerData = pSchedulerData->mpNext;
+ }
+ }
+ pSVData->mnTimerUpdate--;
+}
+
+void Scheduler::SetPriority( SchedulerPriority ePriority )
+{
+ meDefaultPriority = ePriority;
+}
+
+void Scheduler::SetSchedulingPriority( sal_Int32 iPriority )
+{
+ miPriority = iPriority;
+}
+
+void Scheduler::Start()
+{
+ // Mark timer active
+ mbActive = true;
+
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( !mpSchedulerData )
+ {
+ // insert Idle
+ mpSchedulerData = new ImplSchedulerData;
+ mpSchedulerData->mpScheduler = this;
+ mpSchedulerData->mbInScheduler = false;
+
+ // insert last due to SFX!
+ ImplSchedulerData* pPrev = NULL;
+ ImplSchedulerData* pData = pSVData->mpFirstSchedulerData;
+ while ( pData )
+ {
+ pPrev = pData;
+ pData = pData->mpNext;
+ }
+ mpSchedulerData->mpNext = NULL;
+ if ( pPrev )
+ pPrev->mpNext = mpSchedulerData;
+ else
+ pSVData->mpFirstSchedulerData = mpSchedulerData;
+ }
+ mpSchedulerData->mbDelete = false;
+ mpSchedulerData->mnUpdateTime = tools::Time::GetSystemTicks();
+ mpSchedulerData->mnUpdateStack = pSVData->mnTimerUpdate;
+}
+
+void Scheduler::Stop()
+{
+ mbActive = false;
+
+ if ( mpSchedulerData )
+ mpSchedulerData->mbDelete = true;
+}
+
+Scheduler& Scheduler::operator=( const Scheduler& rScheduler )
+{
+ if ( IsActive() )
+ Stop();
+
+ mbActive = false;
+ miPriority = rScheduler.miPriority;
+ meDefaultPriority = rScheduler.meDefaultPriority;
+
+ if ( rScheduler.IsActive() )
+ Start();
+
+ return *this;
+}
+
+Scheduler::Scheduler():
+ mpSchedulerData(NULL),
+ miPriority(static_cast<sal_Int32>(SchedulerPriority::HIGH)),
+ meDefaultPriority(SchedulerPriority::HIGH),
+ mbActive(false)
+{
+}
+
+Scheduler::Scheduler( const Scheduler& rScheduler ):
+ mpSchedulerData(NULL),
+ miPriority(rScheduler.miPriority),
+ meDefaultPriority(rScheduler.meDefaultPriority),
+ mbActive(false)
+{
+ if ( rScheduler.IsActive() )
+ Start();
+}
+
+Scheduler::~Scheduler()
+{
+ if ( mpSchedulerData )
+ {
+ mpSchedulerData->mbDelete = true;
+ mpSchedulerData->mpScheduler = NULL;
+ }
+}
+
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index f569bf90aece..33fbf0a55c1e 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -45,7 +45,7 @@
#include "vcl/cvtgrf.hxx"
#include "vcl/unowrap.hxx"
#include "vcl/timer.hxx"
-#include "vcl/idle.hxx"
+#include "vcl/scheduler.hxx"
#include "vcl/unohelp.hxx"
#include "vcl/lazydelete.hxx"
@@ -343,11 +343,11 @@ inline void ImplYield( bool i_bWait, bool i_bAllEvents )
ImplSVData* pSVData = ImplGetSVData();
// run timers that have timed out
- while ( pSVData->mbNotAllTimerCalled )
- Timer::ImplTimerCallbackProc();
+ //while ( pSVData->mbNotAllTimerCalled )
+ // Timer::ImplTimerCallbackProc();
//Process all idles
- Idle::Idle::ProcessAllIdleHandlers();
+ Scheduler::ProcessTaskScheduling(false);
pSVData->maAppData.mnDispatchLevel++;
// do not wait for events if application was already quit; in that
@@ -367,11 +367,7 @@ inline void ImplYield( bool i_bWait, bool i_bAllEvents )
// e.g. on OS X; need to trigger timer checks manually
if( pSVData->maAppData.mbNoYield )
{
- do
- {
- Timer::ImplTimerCallbackProc( !i_bWait );
- }
- while( pSVData->mbNotAllTimerCalled );
+ Scheduler::ProcessTaskScheduling(true);
}
// call post yield listeners
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index 96302e8ca23f..43f76be04b79 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -33,7 +33,7 @@
#include "vcl/svapp.hxx"
#include "vcl/wrkwin.hxx"
#include "vcl/cvtgrf.hxx"
-#include "vcl/idle.hxx"
+#include "vcl/scheduler.hxx"
#include "vcl/image.hxx"
#include "vcl/settings.hxx"
#include "vcl/unowrap.hxx"
@@ -387,8 +387,8 @@ void DeInitVCL()
if ( pSVData->maAppData.mpIdleMgr )
delete pSVData->maAppData.mpIdleMgr;
- Timer::ImplDeInitTimer();
- Idle::ImplDeInitIdle();
+ //Timer::ImplDeInitTimer();
+ Scheduler::ImplDeInitScheduler();
if ( pSVData->maWinData.mpMsgBoxImgList )
{
diff --git a/vcl/source/app/timer.cxx b/vcl/source/app/timer.cxx
index 97ab45c9fbd9..b8be2d7ef40b 100644
--- a/vcl/source/app/timer.cxx
+++ b/vcl/source/app/timer.cxx
@@ -18,83 +18,14 @@
*/
#include <tools/time.hxx>
-
-#include <vcl/svapp.hxx>
#include <vcl/timer.hxx>
-
#include <saltimer.hxx>
#include <svdata.hxx>
#include <salinst.hxx>
+#include <vcl/scheduler.hxx>
#define MAX_TIMER_PERIOD ((sal_uLong)0xFFFFFFFF)
-struct ImplTimerData
-{
- ImplTimerData* mpNext; // Pointer to the next Instance
- Timer* mpTimer; // Pointer to VCL Timer instance
- sal_uLong mnUpdateTime; // Last Update Time
- sal_uLong mnTimerUpdate; // TimerCallbackProcs on stack
- bool mbDelete; // Was timer deleted during Update()?
- bool mbInTimeout; // Are we in a timeout handler?
-
- void Invoke()
- {
- if (mbDelete || mbInTimeout )
- return;
-
- // if no AutoTimer than stop
- if ( !mpTimer->mbAuto )
- {
- mbDelete = true;
- mpTimer->mbActive = false;
- }
-
- // invoke it
- mbInTimeout = true;
- mpTimer->Timeout();
- mbInTimeout = false;
- }
-
- sal_uLong GetDeadline()
- {
- return mnUpdateTime + mpTimer->mnTimeout;
- }
-};
-
-void Timer::ImplDeInitTimer()
-{
- ImplSVData* pSVData = ImplGetSVData();
- ImplTimerData* pTimerData = pSVData->mpFirstTimerData;
-
- // on WNT the timer queue thread needs killing
- if (pSVData->mpSalTimer)
- {
- pSVData->mpSalTimer->Stop();
- }
-
- if ( pTimerData )
- {
- do
- {
- ImplTimerData* pTempTimerData = pTimerData;
- if ( pTimerData->mpTimer )
- {
- pTimerData->mpTimer->mbActive = false;
- pTimerData->mpTimer->mpTimerData = NULL;
- }
- pTimerData = pTimerData->mpNext;
- delete pTempTimerData;
- }
- while ( pTimerData );
-
- pSVData->mpFirstTimerData = NULL;
- pSVData->mnTimerPeriod = 0;
- }
-
- delete pSVData->mpSalTimer;
- pSVData->mpSalTimer = 0;
-}
-
static void ImplStartTimer( ImplSVData* pSVData, sal_uLong nMS )
{
if ( !nMS )
@@ -108,159 +39,59 @@ static void ImplStartTimer( ImplSVData* pSVData, sal_uLong nMS )
}
}
-void Timer::ImplTimerCallbackProc( bool idle )
+void Timer::SetDeletionFlags()
{
- ImplSVData* pSVData = ImplGetSVData();
- ImplTimerData* pTimerData;
- ImplTimerData* pPrevTimerData;
- sal_uLong nMinPeriod = MAX_TIMER_PERIOD;
- sal_uLong nDeltaTime;
- sal_uLong nTime = tools::Time::GetSystemTicks();
-
- pSVData->mnTimerUpdate++;
- pSVData->mbNotAllTimerCalled = true;
-
- Timer::CheckExpiredTimer(true);
-
- // determine new time
- sal_uLong nNewTime = tools::Time::GetSystemTicks();
- pPrevTimerData = NULL;
- pTimerData = pSVData->mpFirstTimerData;
- while ( pTimerData )
- {
- // ignore if timer is still in timeout handler
- if ( pTimerData->mbInTimeout )
- {
- pPrevTimerData = pTimerData;
- pTimerData = pTimerData->mpNext;
- }
- // Was timer destroyed in the meantime?
- else if ( pTimerData->mbDelete )
- {
- if ( pPrevTimerData )
- pPrevTimerData->mpNext = pTimerData->mpNext;
- else
- pSVData->mpFirstTimerData = pTimerData->mpNext;
- if ( pTimerData->mpTimer )
- pTimerData->mpTimer->mpTimerData = NULL;
- ImplTimerData* pTempTimerData = pTimerData;
- pTimerData = pTimerData->mpNext;
- delete pTempTimerData;
- }
- else
+ // if no AutoTimer than stop
+ if ( !mbAuto )
{
- pTimerData->mnTimerUpdate = 0;
- // determine smallest time slot
- if ( pTimerData->mnUpdateTime == nTime )
- {
- nDeltaTime = pTimerData->mpTimer->mnTimeout;
- if ( nDeltaTime < nMinPeriod )
- nMinPeriod = nDeltaTime;
- }
- else
- {
- nDeltaTime = pTimerData->mnUpdateTime + pTimerData->mpTimer->mnTimeout;
- if ( nDeltaTime < nNewTime )
- nMinPeriod = 1;
- else
- {
- nDeltaTime -= nNewTime;
- if ( nDeltaTime < nMinPeriod )
- nMinPeriod = nDeltaTime;
- }
- }
- pPrevTimerData = pTimerData;
- pTimerData = pTimerData->mpNext;
+ mpSchedulerData->mbDelete = true;
+ mbActive = false;
}
- }
-
- // delete clock if no more timers available
- if ( !pSVData->mpFirstTimerData )
- {
- pSVData->mpSalTimer->Stop();
- pSVData->mnTimerPeriod = MAX_TIMER_PERIOD;
- }
- else
- ImplStartTimer( pSVData, nMinPeriod );
-
- pSVData->mnTimerUpdate--;
- pSVData->mbNotAllTimerCalled = false;
}
-bool Timer::TimerReady()
+bool Timer::ReadyForSchedule( bool bTimer )
{
- return Timer::CheckExpiredTimer(false);
+ (void)bTimer;
+ return (mpSchedulerData->mnUpdateTime + mnTimeout) <= tools::Time::GetSystemTicks();
}
-bool Timer::CheckExpiredTimer(bool bDoInvoke)
+Timer::Timer() : Scheduler()
{
-// find timer where the timer handler needs to be called
- ImplSVData* pSVData = ImplGetSVData();
- ImplTimerData* pTimerData = pSVData->mpFirstTimerData;
- sal_uLong nTime = tools::Time::GetSystemTicks();
- bool timerExpired = false;
- while ( pTimerData )
- {
- // If the timer is not new, was not deleted, and if it is not in the timeout handler, then
- // call the handler as soon as the time is up.
- if ( (pTimerData->mnTimerUpdate < pSVData->mnTimerUpdate) &&
- !pTimerData->mbDelete && !pTimerData->mbInTimeout)
- {
- // time has expired
- if ( pTimerData->GetDeadline() <= nTime )
- {
- if(bDoInvoke)
- {
- //Set new update Timer
- pTimerData->mnUpdateTime = nTime;
- pTimerData->Invoke();
- }
- timerExpired = true;
- }
- }
-
- pTimerData = pTimerData->mpNext;
- }
- return timerExpired;
+ mnTimeout = 1;
+ mbAuto = false;
+ miPriority= static_cast<sal_Int32>(SchedulerPriority::HIGHEST);
+ meDefaultPriority = SchedulerPriority::HIGHEST;
}
-Timer::Timer():
- mpTimerData(NULL),
- mnTimeout(1),
- mbActive(false),
- mbAuto(false)
+Timer::Timer( const Timer& rTimer ) : Scheduler(rTimer)
{
+ mnTimeout = rTimer.mnTimeout;
+ mbAuto = rTimer.mbAuto;
+ maTimeoutHdl = rTimer.maTimeoutHdl;
}
-Timer::Timer( const Timer& rTimer ):
- mpTimerData(NULL),
- mnTimeout(rTimer.mnTimeout),
- mbActive(false),
- mbAuto(false),
- maTimeoutHdl(rTimer.maTimeoutHdl)
+void Timer::Invoke()
{
- if ( rTimer.IsActive() )
- Start();
+ maTimeoutHdl.Call( this );
}
-Timer::~Timer()
+void Timer::Start()
{
- if ( mpTimerData )
+ Scheduler::Start();
+ ImplSVData* pSVData = ImplGetSVData();
+ if( ! pSVData->mpSalTimer )
{
- mpTimerData->mbDelete = true;
- mpTimerData->mpTimer = NULL;
- }
-}
-
-void Timer::Timeout()
-{
- maTimeoutHdl.Call( this );
+ pSVData->mnTimerPeriod = MAX_TIMER_PERIOD;
+ pSVData->mpSalTimer = pSVData->mpDefInst->CreateSalTimer();
+ pSVData->mpSalTimer->SetCallback( CallbackTaskScheduling );
+ }
+ if ( mnTimeout < pSVData->mnTimerPeriod )
+ ImplStartTimer( pSVData, mnTimeout );
}
void Timer::SetTimeout( sal_uLong nNewTimeout )
{
mnTimeout = nNewTimeout;
-
// if timer is active then renew clock
if ( mbActive )
{
@@ -270,80 +101,12 @@ void Timer::SetTimeout( sal_uLong nNewTimeout )
}
}
-void Timer::Start()
-{
- mbActive = true;
-
- ImplSVData* pSVData = ImplGetSVData();
- if ( !mpTimerData )
- {
- if ( !pSVData->mpFirstTimerData )
- {
- pSVData->mnTimerPeriod = MAX_TIMER_PERIOD;
- if( ! pSVData->mpSalTimer )
- {
- pSVData->mpSalTimer = pSVData->mpDefInst->CreateSalTimer();
- pSVData->mpSalTimer->SetCallback( ImplTimerCallbackProc );
- }
- }
-
- // insert timer and start
- mpTimerData = new ImplTimerData;
- mpTimerData->mpTimer = this;
- mpTimerData->mnUpdateTime = tools::Time::GetSystemTicks();
- mpTimerData->mnTimerUpdate = pSVData->mnTimerUpdate;
- mpTimerData->mbDelete = false;
- mpTimerData->mbInTimeout = false;
-
- // insert last due to SFX!
- ImplTimerData* pPrev = NULL;
- ImplTimerData* pData = pSVData->mpFirstTimerData;
- while ( pData )
- {
- pPrev = pData;
- pData = pData->mpNext;
- }
- mpTimerData->mpNext = NULL;
- if ( pPrev )
- pPrev->mpNext = mpTimerData;
- else
- pSVData->mpFirstTimerData = mpTimerData;
-
- if ( mnTimeout < pSVData->mnTimerPeriod )
- ImplStartTimer( pSVData, mnTimeout );
- }
- else if( !mpTimerData->mpTimer ) // TODO: remove when guilty found
- {
- OSL_FAIL( "Timer::Start() on a destroyed Timer!" );
- }
- else
- {
- mpTimerData->mnUpdateTime = tools::Time::GetSystemTicks();
- mpTimerData->mnTimerUpdate = pSVData->mnTimerUpdate;
- mpTimerData->mbDelete = false;
- }
-}
-
-void Timer::Stop()
-{
- mbActive = false;
-
- if ( mpTimerData )
- mpTimerData->mbDelete = true;
-}
-
Timer& Timer::operator=( const Timer& rTimer )
{
- if ( IsActive() )
- Stop();
-
- mbActive = false;
- mnTimeout = rTimer.mnTimeout;
- maTimeoutHdl = rTimer.maTimeoutHdl;
-
- if ( rTimer.IsActive() )
- Start();
-
+ Scheduler::operator=(rTimer);
+ maTimeoutHdl = rTimer.maTimeoutHdl;
+ mnTimeout = rTimer.mnTimeout;
+ mbAuto = rTimer.mbAuto;
return *this;
}