vcl/inc/saltimer.hxx | 44 ++++++++++++++++++++++++++++++++++++++++++++ vcl/inc/win/saltimer.h | 7 ++++--- vcl/win/app/saltimer.cxx | 19 ++++++++++--------- 3 files changed, 58 insertions(+), 12 deletions(-)
New commits: commit afc9d80f6018ff42e55a22d3150dcc7b37e1e862 Author: Jan-Marek Glogowski <[email protected]> AuthorDate: Fri Sep 29 21:02:17 2017 +0200 Commit: Thorsten Behrens <[email protected]> CommitDate: Wed Jan 16 19:32:42 2019 +0100 Partial 'Convert tick-based timer events to versioned ones' bubli's note: removed OS X bits original commit message: Instead of storing the system ticks in the timer event message simply store a version. Moves the version handling code into a VersionedEvent class, inherited by WinSalTimer and AquaSalTimer. Change-Id: I5add85031d36b3424a26a9ef798294cbfb00b2e4 Reviewed-on: https://gerrit.libreoffice.org/42959 Tested-by: Jenkins <[email protected]> Reviewed-by: Jan-Marek Glogowski <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/66449 Reviewed-by: Thorsten Behrens <[email protected]> Tested-by: Thorsten Behrens <[email protected]> diff --git a/vcl/inc/saltimer.hxx b/vcl/inc/saltimer.hxx index 9b67e22fc9d4..5d4ffa32a625 100644 --- a/vcl/inc/saltimer.hxx +++ b/vcl/inc/saltimer.hxx @@ -34,6 +34,7 @@ class VCL_PLUGIN_PUBLIC SalTimer { SALTIMERPROC m_pProc; + public: SalTimer() : m_pProc( nullptr ) {} virtual ~SalTimer(); @@ -55,6 +56,49 @@ public: } }; +class VersionedEvent +{ + /** + * The "additional event data" members on macOS are integers, so we can't + * use an unsigned integer and rely on the defined unsigned overflow in + * InvalidateEvent(). + */ + sal_Int32 m_nEventVersion; + bool m_bIsValidVersion; + +public: + VersionedEvent() : m_nEventVersion( 0 ), m_bIsValidVersion( false ) {} + + sal_Int32 GetNextEventVersion() + { + InvalidateEvent(); + m_bIsValidVersion = true; + return m_nEventVersion; + } + + void InvalidateEvent() + { + if ( m_bIsValidVersion ) + { + if ( m_nEventVersion == SAL_MAX_INT32 ) + m_nEventVersion = 0; + else + ++m_nEventVersion; + m_bIsValidVersion = false; + } + } + + bool ExistsValidEvent() const + { + return m_bIsValidVersion; + } + + bool IsValidEventVersion( const sal_Int32 nEventVersion ) const + { + return m_bIsValidVersion && nEventVersion == m_nEventVersion; + } +}; + #endif // INCLUDED_VCL_INC_SALTIMER_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/win/saltimer.h b/vcl/inc/win/saltimer.h index f87361e55ed8..06e77b171cb3 100644 --- a/vcl/inc/win/saltimer.h +++ b/vcl/inc/win/saltimer.h @@ -22,13 +22,14 @@ #include <saltimer.hxx> -class WinSalTimer : public SalTimer +class WinSalTimer final : public SalTimer, protected VersionedEvent { // for access to Impl* functions friend LRESULT CALLBACK SalComWndProc( HWND, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef ); + // for access to m_bPollForMessage + friend static void CALLBACK SalTimerProc( PVOID data, BOOLEAN ); HANDLE m_nTimerId; ///< Windows timer id - sal_uInt32 m_nTimerStartTicks; ///< system ticks at timer start % SAL_MAX_UINT32 bool m_bPollForMessage; ///< Run yield until a message is caught (most likely the 0ms timer) void ImplStart( sal_uIntPtr nMS ); @@ -49,7 +50,7 @@ public: inline bool WinSalTimer::IsValidWPARAM( WPARAM aWPARAM ) const { - return aWPARAM == m_nTimerStartTicks; + return IsValidEventVersion( static_cast<sal_Int32>( aWPARAM ) ); } inline bool WinSalTimer::PollForMessage() const diff --git a/vcl/win/app/saltimer.cxx b/vcl/win/app/saltimer.cxx index a57fddf30426..fff4cb65a2c7 100644 --- a/vcl/win/app/saltimer.cxx +++ b/vcl/win/app/saltimer.cxx @@ -17,6 +17,8 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <sal/config.h> + #include <svsys.h> #include <win/saldata.hxx> #include <win/saltimer.h> @@ -46,8 +48,9 @@ void WinSalTimer::ImplStop() return; m_nTimerId = nullptr; - m_nTimerStartTicks = 0; DeleteTimerQueueTimer( nullptr, hTimer, INVALID_HANDLE_VALUE ); + // Keep both after DeleteTimerQueueTimer, because they are set in SalTimerProc + InvalidateEvent(); m_bPollForMessage = false; // remove as many pending SAL_MSG_TIMER_CALLBACK messages as possible @@ -71,18 +74,17 @@ void WinSalTimer::ImplStart( sal_uLong nMS ) // keep the yield running, if a 0ms Idle is scheduled m_bPollForMessage = ( 0 == nMS ); - m_nTimerStartTicks = tools::Time::GetMonotonicTicks() % SAL_MAX_UINT32; // probably WT_EXECUTEONLYONCE is not needed, but it enforces Period // to be 0 and should not hurt; also see // https://www.microsoft.com/msj/0499/pooling/pooling.aspx CreateTimerQueueTimer(&m_nTimerId, nullptr, SalTimerProc, - (void*) m_nTimerStartTicks, + reinterpret_cast<void*>( + sal_IntPtr(GetNextEventVersion())), nMS, 0, WT_EXECUTEINTIMERTHREAD | WT_EXECUTEONLYONCE); } WinSalTimer::WinSalTimer() : m_nTimerId( nullptr ) - , m_nTimerStartTicks( 0 ) , m_bPollForMessage( false ) { } @@ -118,11 +120,10 @@ void WinSalTimer::Stop() ImplStop(); } -/** This gets invoked from a Timer Queue thread. - -Don't acquire the SolarMutex to avoid deadlocks, just wake up the main thread -at better resolution than 10ms. -*/ +/** + * This gets invoked from a Timer Queue thread. + * Don't acquire the SolarMutex to avoid deadlocks. + */ static void CALLBACK SalTimerProc(PVOID data, BOOLEAN) { #if defined ( __MINGW32__ ) && !defined ( _WIN64 ) _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
