[Libreoffice-commits] core.git: include/tools include/vcl svtools/source svx/source vcl/qa vcl/source

Michael Meeks michael.meeks at collabora.com
Wed Jun 10 09:21:21 PDT 2015


 include/tools/time.hxx              |    4 +++-
 include/vcl/idle.hxx                |    8 ++++++--
 include/vcl/scheduler.hxx           |   16 ++++++++++------
 include/vcl/timer.hxx               |    2 +-
 svtools/source/graphic/grfcache.cxx |    1 +
 svx/source/svdraw/svdetc.cxx        |    1 +
 vcl/qa/cppunit/timer.cxx            |   26 +++++++++++++++++++++++++-
 vcl/source/app/idle.cxx             |   25 ++++++++++++++++++++++++-
 vcl/source/app/scheduler.cxx        |   15 ++++++---------
 vcl/source/app/timer.cxx            |    2 +-
 vcl/source/window/window.cxx        |    2 ++
 11 files changed, 80 insertions(+), 22 deletions(-)

New commits:
commit 48c2815dd20cf20eeec8bb4e003000f4a3d13291
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Wed Jun 10 12:08:00 2015 +0100

    tdf#91727 - Unwind non-dispatch of idle handlers.
    
    This clobbers the functionality from commit:
    
        06d731428ef6cf93c7333e8228bfb6088853b52f
    
        make idle timers actually activate only when idle
    
    Since now all rendering and re-sizing is done in idle handlers it
    does effectively the opposite of what was intended. A better solution
    would allow special-casing the processing of just rendering,
    re-sizing and window management to spin for eg. progress bar
    rendering.
    
    Also add helpful debugging labels to the idle & timeouts.
    
    Also cleanup the Idle vs. Scheduler handling.
    
    Also ensure that starting an Idle triggers a mainloop wakeup.
    
    Also add a unit test.
    
    Change-Id: Ifb0756714378fdb790be599b93c7a3ac1f9209e6

diff --git a/include/tools/time.hxx b/include/tools/time.hxx
index 2b950b8..e25b2de 100644
--- a/include/tools/time.hxx
+++ b/include/tools/time.hxx
@@ -123,7 +123,9 @@ public:
                     { return (nTime <= rTime.nTime); }
 
     static Time     GetUTCOffset();
-    static sal_uInt64 GetSystemTicks();       // Elapsed time
+
+    /// Elapsed time since epoch in milliseconds
+    static sal_uInt64 GetSystemTicks();
 
     void            ConvertToUTC()       { *this -= Time::GetUTCOffset(); }
     void            ConvertToLocalTime() { *this += Time::GetUTCOffset(); }
diff --git a/include/vcl/idle.hxx b/include/vcl/idle.hxx
index b66a889..258fd48 100644
--- a/include/vcl/idle.hxx
+++ b/include/vcl/idle.hxx
@@ -29,14 +29,18 @@ protected:
     Link<Idle *, void> maIdleHdl;          // Callback Link
 
 public:
-    Idle();
+    Idle( const sal_Char *pDebugName = NULL );
     Idle( const Idle& rIdle );
 
+    virtual void    Start();
+
     /// Make it possible to associate a callback with this idle handler
     /// of course, you can also sub-class and override 'Invoke'
     void            SetIdleHdl( const Link<Idle *, void>& rLink ) { maIdleHdl = rLink; }
     const Link<Idle *, void>& GetIdleHdl() const { return maIdleHdl; }
-    virtual void    Invoke() SAL_OVERRIDE;
+    virtual void Invoke() SAL_OVERRIDE;
+    virtual bool ReadyForSchedule( bool bTimer ) SAL_OVERRIDE;
+    virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) SAL_OVERRIDE;
     Idle&           operator=( const Idle& rIdle );
 };
 
diff --git a/include/vcl/scheduler.hxx b/include/vcl/scheduler.hxx
index dfa1483..6c4e211 100644
--- a/include/vcl/scheduler.hxx
+++ b/include/vcl/scheduler.hxx
@@ -52,23 +52,27 @@ enum class SchedulerPriority {
 class VCL_DLLPUBLIC Scheduler
 {
 protected:
-    ImplSchedulerData*  mpSchedulerData;    // Pointer to element in scheduler list
-    SchedulerPriority   mePriority;         // Scheduler priority
-    bool                mbActive;           // Currently in the scheduler
+    ImplSchedulerData*  mpSchedulerData;    /// Pointer to element in scheduler list
+    const sal_Char     *mpDebugName;        /// Useful for debugging
+    SchedulerPriority   mePriority;         /// Scheduler priority
+    bool                mbActive;           /// Currently in the scheduler
 
     friend struct ImplSchedulerData;
     virtual void SetDeletionFlags();
-    virtual bool ReadyForSchedule( bool bTimer ) { return !bTimer; }
-    virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime );
+    virtual bool ReadyForSchedule( bool bTimer ) = 0;
+    virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) = 0;
 
 public:
-    Scheduler();
+    Scheduler( const sal_Char *pDebugName = NULL );
     Scheduler( const Scheduler& rScheduler );
     virtual ~Scheduler();
 
     void SetPriority( SchedulerPriority ePriority );
     SchedulerPriority GetPriority() const { return mePriority; }
 
+    void            SetDebugName( const sal_Char *pDebugName ) { mpDebugName = pDebugName; }
+    const sal_Char *GetDebugName() { return mpDebugName; }
+
     // Call handler
     virtual void    Invoke() = 0;
 
diff --git a/include/vcl/timer.hxx b/include/vcl/timer.hxx
index 458ad4e..8835291 100644
--- a/include/vcl/timer.hxx
+++ b/include/vcl/timer.hxx
@@ -38,7 +38,7 @@ private:
     static void InitSystemTimer();
 
 public:
-    Timer();
+    Timer( const sal_Char *pDebugName = NULL );
     Timer( const Timer& rTimer );
 
     /// Make it possible to associate a callback with this timer handler
diff --git a/svtools/source/graphic/grfcache.cxx b/svtools/source/graphic/grfcache.cxx
index 011f79a..21aa7d7 100644
--- a/svtools/source/graphic/grfcache.cxx
+++ b/svtools/source/graphic/grfcache.cxx
@@ -805,6 +805,7 @@ void GraphicDisplayCacheEntry::Draw( OutputDevice* pOut, const Point& rPt, const
 }
 
 GraphicCache::GraphicCache( sal_uLong nDisplayCacheSize, sal_uLong nMaxObjDisplayCacheSize ) :
+    maReleaseTimer          ( "GraphicCache maReleaseTimer" ),
     mnReleaseTimeoutSeconds ( 0UL ),
     mnMaxDisplaySize        ( nDisplayCacheSize ),
     mnMaxObjDisplaySize     ( nMaxObjDisplayCacheSize ),
diff --git a/svx/source/svdraw/svdetc.cxx b/svx/source/svdraw/svdetc.cxx
index 7f04c4a..abdb896 100644
--- a/svx/source/svdraw/svdetc.cxx
+++ b/svx/source/svdraw/svdetc.cxx
@@ -102,6 +102,7 @@ OLEObjCache::OLEObjCache()
     pTimer->SetTimeoutHdl(aLink);
     pTimer->SetTimeout(20000);
     pTimer->Start();
+    pTimer->SetDebugName("OLEObjCache pTimer UnloadCheck");
 
     aLink.Call(pTimer);
 }
diff --git a/vcl/qa/cppunit/timer.cxx b/vcl/qa/cppunit/timer.cxx
index 976853c..12110b7 100644
--- a/vcl/qa/cppunit/timer.cxx
+++ b/vcl/qa/cppunit/timer.cxx
@@ -18,6 +18,10 @@
 #include <vcl/timer.hxx>
 #include <vcl/idle.hxx>
 #include <vcl/svapp.hxx>
+#include "svdata.hxx"
+#include "salinst.hxx"
+
+// #define TEST_WATCHDOG
 
 /// Avoid our timer tests just wedging the build if they fail.
 class WatchDog : public osl::Thread
@@ -47,6 +51,7 @@ class TimerTest : public test::BootstrapFixture
 public:
     TimerTest() : BootstrapFixture(true, false) {}
 
+    void testIdleMainloop();
     void testIdle();
 #ifdef TEST_WATCHDOG
     void testWatchdog();
@@ -58,6 +63,7 @@ public:
 
     CPPUNIT_TEST_SUITE(TimerTest);
     CPPUNIT_TEST(testIdle);
+    CPPUNIT_TEST(testIdleMainloop);
 #ifdef TEST_WATCHDOG
     CPPUNIT_TEST(testWatchdog);
 #endif
@@ -105,7 +111,25 @@ void TimerTest::testIdle()
     bool bTriggered = false;
     IdleBool aTest( bTriggered );
     Scheduler::ProcessTaskScheduling(false);
-    CPPUNIT_ASSERT_MESSAGE("watchdog triggered", bTriggered);
+    CPPUNIT_ASSERT_MESSAGE("idle triggered", bTriggered);
+}
+
+// tdf#91727
+void TimerTest::testIdleMainloop()
+{
+    bool bTriggered = false;
+    IdleBool aTest( bTriggered );
+    while (!bTriggered)
+    {
+        ImplSVData* pSVData = ImplGetSVData();
+
+        // can't test this via Application::Yield since this
+        // also processes all tasks directly via the scheduler.
+        pSVData->maAppData.mnDispatchLevel++;
+        pSVData->mpDefInst->Yield( true, false );
+        pSVData->maAppData.mnDispatchLevel--;
+    }
+    CPPUNIT_ASSERT_MESSAGE("mainloop idle triggered", bTriggered);
 }
 
 // --------------------------------------------------------------------
diff --git a/vcl/source/app/idle.cxx b/vcl/source/app/idle.cxx
index 7fe239d..0dd8593 100644
--- a/vcl/source/app/idle.cxx
+++ b/vcl/source/app/idle.cxx
@@ -18,6 +18,8 @@
  */
 
 #include <vcl/idle.hxx>
+#include <vcl/timer.hxx>
+#include "svdata.hxx"
 
 void Idle::Invoke()
 {
@@ -31,7 +33,7 @@ Idle& Idle::operator=( const Idle& rIdle )
     return *this;
 }
 
-Idle::Idle() : Scheduler()
+Idle::Idle( const sal_Char *pDebugName ) : Scheduler( pDebugName )
 {
 }
 
@@ -40,4 +42,25 @@ Idle::Idle( const Idle& rIdle ) : Scheduler(rIdle)
     maIdleHdl = rIdle.maIdleHdl;
 }
 
+void Idle::Start()
+{
+    Scheduler::Start();
+    ImplSVData* pSVData = ImplGetSVData();
+    Timer::ImplStartTimer( pSVData, 0 );
+}
+
+bool Idle::ReadyForSchedule( bool bTimer )
+{
+    // tdf#91727 - We need to re-work this to allow only UI idle handlers
+    //             and not timeouts to be processed in some limited scenarios
+    (void)bTimer;
+    return true; // !bTimer
+}
+
+sal_uInt64 Idle::UpdateMinPeriod( sal_uInt64 /* nMinPeriod */, sal_uInt64 /* nTime */ )
+{
+    return 1;
+}
+
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx
index 20b11dc..c3cea78 100644
--- a/vcl/source/app/scheduler.cxx
+++ b/vcl/source/app/scheduler.cxx
@@ -120,6 +120,7 @@ void Scheduler::ProcessTaskScheduling( bool bTimer )
     sal_uInt64         nMinPeriod = MAX_TIMER_PERIOD;
     pSVData->mnUpdateStack++;
 
+    // tdf#91727 - NB. bTimer is ultimately not used
     if ((pSchedulerData = ImplSchedulerData::GetMostImportantTask(bTimer)))
     {
         pSchedulerData->mnUpdateTime = nTime;
@@ -164,18 +165,12 @@ void Scheduler::ProcessTaskScheduling( bool bTimer )
         pSVData->mnTimerPeriod = MAX_TIMER_PERIOD;
     }
     else
+    {
         Timer::ImplStartTimer( pSVData, nMinPeriod );
+    }
     pSVData->mnUpdateStack--;
 }
 
-sal_uInt64 Scheduler::UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime )
-{
-    // this period is only useful for timer
-    // so in this implementation it' only a pass through
-    (void)nTime;
-    return nMinPeriod;
-}
-
 void Scheduler::SetPriority( SchedulerPriority ePriority )
 {
     mePriority = ePriority;
@@ -235,8 +230,9 @@ Scheduler& Scheduler::operator=( const Scheduler& rScheduler )
     return *this;
 }
 
-Scheduler::Scheduler():
+Scheduler::Scheduler(const sal_Char *pDebugName):
     mpSchedulerData(NULL),
+    mpDebugName(pDebugName),
     mePriority(SchedulerPriority::HIGH),
     mbActive(false)
 {
@@ -244,6 +240,7 @@ Scheduler::Scheduler():
 
 Scheduler::Scheduler( const Scheduler& rScheduler ):
     mpSchedulerData(NULL),
+    mpDebugName(rScheduler.mpDebugName),
     mePriority(rScheduler.mePriority),
     mbActive(false)
 {
diff --git a/vcl/source/app/timer.cxx b/vcl/source/app/timer.cxx
index a49f4f5..7d92283 100644
--- a/vcl/source/app/timer.cxx
+++ b/vcl/source/app/timer.cxx
@@ -98,7 +98,7 @@ void Timer::InitSystemTimer()
     }
 }
 
-Timer::Timer() : Scheduler()
+Timer::Timer(const sal_Char *pDebugName) : Scheduler(pDebugName)
 {
     mnTimeout = 1;
     mbAuto = false;
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 497fc42..9754f33 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -1058,9 +1058,11 @@ void Window::ImplInit( vcl::Window* pParent, WinBits nStyle, SystemParentData* p
         {
             mpWindowImpl->mpFrameData->maPaintIdle.SetPriority( SchedulerPriority::REPAINT );
             mpWindowImpl->mpFrameData->maPaintIdle.SetIdleHdl( LINK( this, Window, ImplHandlePaintHdl ) );
+            mpWindowImpl->mpFrameData->maPaintIdle.SetDebugName( "vcl::Window maPaintIdle" );
         }
         mpWindowImpl->mpFrameData->maResizeIdle.SetPriority( SchedulerPriority::RESIZE );
         mpWindowImpl->mpFrameData->maResizeIdle.SetIdleHdl( LINK( this, Window, ImplHandleResizeTimerHdl ) );
+        mpWindowImpl->mpFrameData->maResizeIdle.SetDebugName( "vcl::Window maResizeIdle" );
         mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = false;
 
         if ( pRealParent && IsTopWindow() )


More information about the Libreoffice-commits mailing list