[Libreoffice-commits] core.git: Branch 'libreoffice-6-1-1' - include/vcl sw/inc sw/source vcl/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Mon Sep 10 15:40:36 UTC 2018


 include/vcl/scheduler.hxx                   |   12 +++++++
 sw/inc/IDocumentTimerAccess.hxx             |    9 +++--
 sw/source/core/doc/DocumentTimerManager.cxx |   45 ++++++++++++++++------------
 sw/source/core/inc/DocumentTimerManager.hxx |    8 ++--
 vcl/source/app/scheduler.cxx                |    5 +++
 5 files changed, 53 insertions(+), 26 deletions(-)

New commits:
commit 3abec366a3fdb8657d69e24b69b4338121f80b22
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Fri Aug 24 08:05:26 2018 +0200
Commit:     Xisco Faulí <xiscofauli at libreoffice.org>
CommitDate: Mon Sep 10 17:40:15 2018 +0200

    tdf#119458 reorganize sw background Idle handling
    
    This is the squashed version of the following commits:
    - ce68889678bc tdf#119458 always start the SwDocIdle
    - 107f0e6dba57 tdf#119458 fix sw background Idle state handling
    - 771544544ee1 tdf#119458 fix sw background Idle unblocking
    - 3bd8316718fd tdf#119458 just wakeup Scheduler on active Idle
    
    While the first commit was really wrong, the third is just an
    optimization to prevent unnecessary wakeups and Idle task
    interrups from new calls to StartIdling(). The 4th one contains
    the reset of the Idle state on run, which was probably the main
    origin of the problem and allows to wake up the Scheduler
    without moving the Task to the end of the queue.
    
    Starting the SwDocIdle in StartIdeling() just reintroduces the
    bug fixed in commit 401cba4c20fb ("tdf#116370 cleanup Writer idle
    job handing"), so trading one bug for the other.
    
    For the real solution we have to handle two states:
    1. The SwDocIdle being active
    2. The SwDocIdle being blocked
    
    For the first state we can just use the active state of the Idle
    itself. Since it's not a AutoIdle, it will be turned of, if
    invoked. Either some Idle handler will want to be run it again or
    some other thread might start it again, if needed.
    Since we're now tracking the wanted Idle state via the active task
    flag, we can drop the explicit mbStartIdleTimer handling.
    
    As a result of the first change, we can't stop the Idle anymore
    when blocking it. But the Idle itself checks its ready state via
    IsDocIdle() in its UpdateMinPeriod function, so we have to add
    the blocking state to IsDocIdle().
    
    But we can't handle the correct state when blocking via a tasks
    mbActive bool, as this also schedules the task and starts the
    scheduler timer. So reintroduce a bool for the unblock state.
    
    This should prevent fdo#73165, which I couldn't reproduce, but
    just to be sure.
    
    More importantly this patch resets the m_bStartOnUnblock when
    the Idle job actually runs. This run should already determinates
    if more Idle work needs to be done, and others can still call
    BeginIdling() to ensure further processing.
    
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>
    Tested-by: Jenkins
    Reviewed-on: https://gerrit.libreoffice.org/59536
    (cherry picked from commit ce68889678bca3b51c258452f7bfdd21982e4a0d)
    Reviewed-on: https://gerrit.libreoffice.org/59586
    (cherry picked from commit 107f0e6dba57a5b27366a35a5cdb184079546df0)
    Reviewed-on: https://gerrit.libreoffice.org/59692
    (cherry picked from commit 771544544ee13ec98961f93b5313a7d2e29429cd)
    Reviewed-on: https://gerrit.libreoffice.org/59730
    (cherry picked from commit 3bd8316718fdfed454c01a9c4ae6af6beb34437d)
    
    Change-Id: I2d4328f31644017b09786ff4cba45cf7643f0a4b
    (cherry picked from commit f1fb30cf43eda45137ab96177238a29c3725789d)
    Reviewed-on: https://gerrit.libreoffice.org/59757
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit 20e46a6ca5b62f7177f799eae9e0f26e659fd03b)
    Reviewed-on: https://gerrit.libreoffice.org/59769
    Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice at googlemail.com>
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
    Reviewed-by: Xisco Faulí <xiscofauli at libreoffice.org>
    Tested-by: Xisco Faulí <xiscofauli at libreoffice.org>

diff --git a/include/vcl/scheduler.hxx b/include/vcl/scheduler.hxx
index ac429ed33b09..6233d134a8ed 100644
--- a/include/vcl/scheduler.hxx
+++ b/include/vcl/scheduler.hxx
@@ -65,6 +65,18 @@ public:
      */
     static void       ProcessEventsToIdle();
 
+    /**
+     * Wakes up the scheduler
+     *
+     * This doesn't handle any events! It just ensures the Scheduler is run as
+     * soon as possible by forcing the Scheduler timer to fire.
+     *
+     * Can be used for complex UpdateMinPeriod function, where the task is
+     * actually active but not ready and we want to skip the Task::Start()
+     * queue append for faster reaction.
+     */
+    static void       Wakeup();
+
     /// Control the deterministic mode.  In this mode, two subsequent runs of
     /// LibreOffice fire about the same amount idles.
     static void       SetDeterministicMode(bool bDeterministic);
diff --git a/sw/inc/IDocumentTimerAccess.hxx b/sw/inc/IDocumentTimerAccess.hxx
index 1ed8679c00ac..f3e2738485af 100644
--- a/sw/inc/IDocumentTimerAccess.hxx
+++ b/sw/inc/IDocumentTimerAccess.hxx
@@ -21,7 +21,7 @@
 #define INCLUDED_SW_INC_IDOCUMENTTIMERACCESS_HXX
 
 /**
- * Handle the background job of the Writer document.
+ * Handle the background jobs of a Writer document.
  *
  * Initially it's disabled and unblocked.
  *
@@ -34,7 +34,9 @@ class IDocumentTimerAccess
 {
 public:
     /**
-     * Start the idle job depending on the block count.
+     * Start the idle task.
+     *
+     * Depends on the block count and various document states.
      */
     virtual void StartIdling() = 0;
 
@@ -47,13 +49,14 @@ public:
      * Increment block count.
      *
      * Prevents further background idle processing.
+     * This doesn't guarantee the Idle task is not currently running!
      */
     virtual void BlockIdling() = 0;
 
     /**
      * Decrement block count.
      *
-     * May start the idle job.
+     * May re-start the idle task, if active.
      */
     virtual void UnblockIdling() = 0;
 
diff --git a/sw/source/core/doc/DocumentTimerManager.cxx b/sw/source/core/doc/DocumentTimerManager.cxx
index 35f2eb94dcbd..7bd2e505a3a4 100644
--- a/sw/source/core/doc/DocumentTimerManager.cxx
+++ b/sw/source/core/doc/DocumentTimerManager.cxx
@@ -33,50 +33,56 @@
 #include <docsh.hxx>
 #include <docfld.hxx>
 #include <fldbas.hxx>
+#include <vcl/scheduler.hxx>
 
 namespace sw
 {
 
 DocumentTimerManager::DocumentTimerManager( SwDoc& i_rSwdoc ) : m_rDoc( i_rSwdoc ),
-                                                                mbStartIdleTimer( false ),
-                                                                mIdleBlockCount( 0 ),
-                                                                maDocIdle( i_rSwdoc )
+                                                                m_nIdleBlockCount( 0 ),
+                                                                m_bStartOnUnblock( false ),
+                                                                m_aDocIdle( i_rSwdoc )
 {
-    maDocIdle.SetPriority( TaskPriority::LOWEST );
-    maDocIdle.SetInvokeHandler( LINK( this, DocumentTimerManager, DoIdleJobs) );
-    maDocIdle.SetDebugName( "sw::DocumentTimerManager maDocIdle" );
+    m_aDocIdle.SetPriority(TaskPriority::LOWEST);
+    m_aDocIdle.SetInvokeHandler(LINK( this, DocumentTimerManager, DoIdleJobs));
+    m_aDocIdle.SetDebugName("sw::DocumentTimerManager m_aDocIdle");
 }
 
 void DocumentTimerManager::StartIdling()
 {
-    if( !mIdleBlockCount && !maDocIdle.IsActive() )
+    m_bStartOnUnblock = true;
+    if (0 == m_nIdleBlockCount)
     {
-        mbStartIdleTimer = false;
-        maDocIdle.Start();
+        if (!m_aDocIdle.IsActive())
+            m_aDocIdle.Start();
+        else
+            Scheduler::Wakeup();
     }
-    else
-        mbStartIdleTimer = true;
 }
 
 void DocumentTimerManager::StopIdling()
 {
-    mbStartIdleTimer = false;
-    maDocIdle.Stop();
+    m_bStartOnUnblock = false;
+    m_aDocIdle.Stop();
 }
 
 void DocumentTimerManager::BlockIdling()
 {
-    maDocIdle.Stop();
-    ++mIdleBlockCount;
+    assert(SAL_MAX_UINT32 != m_nIdleBlockCount);
+    ++m_nIdleBlockCount;
 }
 
 void DocumentTimerManager::UnblockIdling()
 {
-    --mIdleBlockCount;
-    if( !mIdleBlockCount && mbStartIdleTimer && !maDocIdle.IsActive() )
+    assert(0 != m_nIdleBlockCount);
+    --m_nIdleBlockCount;
+
+    if ((0 == m_nIdleBlockCount) && m_bStartOnUnblock)
     {
-        mbStartIdleTimer = false;
-        maDocIdle.Start();
+        if (!m_aDocIdle.IsActive())
+            m_aDocIdle.Start();
+        else
+            Scheduler::Wakeup();
     }
 }
 
@@ -131,6 +137,7 @@ IMPL_LINK_NOARG( DocumentTimerManager, DoIdleJobs, Timer*, void )
         pModLogFile = new ::rtl::Logfile( "First DoIdleJobs" );
 #endif
     BlockIdling();
+    StopIdling();
 
     IdleJob eJob = GetNextIdleJob();
 
diff --git a/sw/source/core/inc/DocumentTimerManager.hxx b/sw/source/core/inc/DocumentTimerManager.hxx
index 214c0f626a75..2caaf608c40d 100644
--- a/sw/source/core/inc/DocumentTimerManager.hxx
+++ b/sw/source/core/inc/DocumentTimerManager.hxx
@@ -66,14 +66,14 @@ private:
 
     SwDoc& m_rDoc;
 
-    bool mbStartIdleTimer; //< idle timer mode start/stop
-    sal_Int32 mIdleBlockCount;
-    SwDocIdle maDocIdle;
+    sal_uInt32 m_nIdleBlockCount; ///< Don't run the Idle, if > 0
+    bool m_bStartOnUnblock; ///< true, if the last unblock should start the timer
+    SwDocIdle m_aDocIdle;
 };
 
 inline bool DocumentTimerManager::IsDocIdle() const
 {
-    return( GetNextIdleJob() != IdleJob::Busy );
+    return ((0 == m_nIdleBlockCount) && (GetNextIdleJob() != IdleJob::Busy));
 }
 
 }
diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx
index d7f80e1f1783..c6a0c3a2e1fc 100644
--- a/vcl/source/app/scheduler.cxx
+++ b/vcl/source/app/scheduler.cxx
@@ -503,6 +503,11 @@ next_entry:
     return !!pMostUrgent;
 }
 
+void Scheduler::Wakeup()
+{
+    Scheduler::ImplStartTimer( 0, false, tools::Time::GetSystemTicks() );
+}
+
 void Task::StartTimer( sal_uInt64 nMS )
 {
     Scheduler::ImplStartTimer( nMS, false, tools::Time::GetSystemTicks() );


More information about the Libreoffice-commits mailing list