[Libreoffice-commits] core.git: vcl/inc vcl/osx
Jan-Marek Glogowski
glogow at fbihome.de
Fri Sep 29 17:08:00 UTC 2017
vcl/inc/osx/saltimer.h | 14 ++++--
vcl/osx/salinst.cxx | 23 ++++-------
vcl/osx/salnstimer.mm | 14 ++----
vcl/osx/saltimer.cxx | 101 +++++++++++++++++++++++++++++++------------------
4 files changed, 90 insertions(+), 62 deletions(-)
New commits:
commit a60f687b5dd684260fc976c1216d65d30e77e5de
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date: Tue Sep 26 19:06:51 2017 +0200
tdf#112605 OSX refactor SalAquaTimer
Drops all the static calls and variables from SalAquaTimer
and moves all timer handling logic inside the class.
This also fixes the leak in timerElapsed.
Change-Id: Ie7a1a8fffb70b8579ec6876eed10a275d2f06d27
Reviewed-on: https://gerrit.libreoffice.org/42913
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>
diff --git a/vcl/inc/osx/saltimer.h b/vcl/inc/osx/saltimer.h
index 86964115d648..f70bd65491b8 100644
--- a/vcl/inc/osx/saltimer.h
+++ b/vcl/inc/osx/saltimer.h
@@ -43,6 +43,12 @@ public:
class AquaSalTimer : public SalTimer
{
+ NSTimer *m_pRunningTimer;
+ sal_Int32 m_nTimerStartTicks; ///< system ticks at timer start % SAL_MAX_INT32
+
+ void queueDispatchTimerEvent( bool bAtStart );
+ void callTimerCallback();
+
public:
AquaSalTimer();
virtual ~AquaSalTimer() override;
@@ -50,11 +56,11 @@ public:
void Start( sal_uLong nMS ) override;
void Stop() override;
- static void handleStartTimerEvent( NSEvent* pEvent );
- static void handleDispatchTimerEvent();
+ void handleStartTimerEvent( NSEvent* pEvent );
+ void handleDispatchTimerEvent( NSEvent* pEvent );
+ void handleTimerElapsed();
- static NSTimer* pRunningTimer;
- static bool bDispatchTimer;
+ bool IsTimerElapsed() const;
};
#endif // INCLUDED_VCL_INC_OSX_SALTIMER_H
diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx
index 89e3ae6d4e82..8af988a1de77 100644
--- a/vcl/osx/salinst.cxx
+++ b/vcl/osx/salinst.cxx
@@ -426,11 +426,13 @@ bool AquaSalInstance::IsMainThread() const
void AquaSalInstance::handleAppDefinedEvent( NSEvent* pEvent )
{
+ AquaSalTimer *pTimer = static_cast<AquaSalTimer*>( ImplGetSVData()->maSchedCtx.mpSalTimer );
int nSubtype = [pEvent subtype];
switch( nSubtype )
{
case AppStartTimerEvent:
- AquaSalTimer::handleStartTimerEvent( pEvent );
+ if ( pTimer )
+ pTimer->handleStartTimerEvent( pEvent );
break;
case AppEndLoopEvent:
[NSApp stop: NSApp];
@@ -450,7 +452,8 @@ void AquaSalInstance::handleAppDefinedEvent( NSEvent* pEvent )
break;
}
case DispatchTimerEvent:
- AquaSalTimer::handleDispatchTimerEvent();
+ if ( pTimer )
+ pTimer->handleDispatchTimerEvent( pEvent );
break;
#if !HAVE_FEATURE_MACOSX_SANDBOX
case AppleRemoteControlEvent: // Defined in <apple_remote/RemoteMainController.h>
@@ -566,7 +569,7 @@ bool AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents)
{
// handle available events
NSEvent* pEvent = nil;
- NSTimeInterval now = [[NSProcessInfo processInfo]systemUptime];
+ NSTimeInterval now = [[NSProcessInfo processInfo] systemUptime];
do
{
SolarMutexReleaser aReleaser;
@@ -598,12 +601,11 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
{
SolarMutexReleaser aReleaser;
- NSDate* pDt = AquaSalTimer::pRunningTimer ? [AquaSalTimer::pRunningTimer fireDate] : [NSDate distantFuture];
SAL_WNODEPRECATED_DECLARATIONS_PUSH
// 'NSAnyEventMask' is deprecated: first deprecated in macOS 10.12
pEvent = [NSApp nextEventMatchingMask: NSAnyEventMask
SAL_WNODEPRECATED_DECLARATIONS_POP
- untilDate: pDt
+ untilDate: [NSDate distantFuture]
inMode: NSDefaultRunLoopMode
dequeue: YES];
if( pEvent )
@@ -682,14 +684,9 @@ bool AquaSalInstance::AnyInput( VclInputFlags nType )
if( nType & VclInputFlags::TIMER )
{
- if( AquaSalTimer::pRunningTimer )
- {
- NSDate* pDt = [AquaSalTimer::pRunningTimer fireDate];
- if( pDt && [pDt timeIntervalSinceNow] < 0 )
- {
- return true;
- }
- }
+ AquaSalTimer *pTimer = static_cast<AquaSalTimer*>( ImplGetSVData()->maSchedCtx.mpSalTimer );
+ if (pTimer && pTimer->IsTimerElapsed())
+ return true;
}
unsigned/*NSUInteger*/ nEventMask = 0;
diff --git a/vcl/osx/salnstimer.mm b/vcl/osx/salnstimer.mm
index c9b657dcd776..9647bb6b87c1 100644
--- a/vcl/osx/salnstimer.mm
+++ b/vcl/osx/salnstimer.mm
@@ -27,16 +27,12 @@
@implementation TimerCallbackCaller
--(void)timerElapsed:(NSTimer*)pTimer
+-(void)timerElapsed:(NSTimer*)pNSTimer
{
- (void)pTimer;
- // nil the timer, as it is just invalidated after the firing function
- AquaSalTimer::pRunningTimer = nil;
- const AquaSalInstance *pInst = GetSalData()->mpFirstInstance;
- if (pInst->mbIsLiveResize)
- AquaSalTimer::handleDispatchTimerEvent();
- else
- ImplNSAppPostEvent( AquaSalInstance::DispatchTimerEvent, YES );
+ (void) pNSTimer;
+ AquaSalTimer *pTimer = static_cast<AquaSalTimer*>( ImplGetSVData()->maSchedCtx.mpSalTimer );
+ if (pTimer)
+ pTimer->handleTimerElapsed();
}
@end
diff --git a/vcl/osx/saltimer.cxx b/vcl/osx/saltimer.cxx
index 3667fd5dd3f5..4bc9706fc39d 100644
--- a/vcl/osx/saltimer.cxx
+++ b/vcl/osx/saltimer.cxx
@@ -20,6 +20,7 @@
#include <sal/config.h>
#include <rtl/math.hxx>
+#include <tools/time.hxx>
#include "osx/saltimer.h"
#include "osx/salnstimer.h"
@@ -27,9 +28,6 @@
#include "osx/salframe.h"
#include "osx/salinst.h"
-NSTimer* AquaSalTimer::pRunningTimer = nil;
-
-static void ImplSalStopTimer();
void ImplNSAppPostEvent( short nEventId, BOOL bAtStart, int nUserData )
{
@@ -73,7 +71,16 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
[NSApp postEvent: pEvent atStart: bAtStart];
}
-static void ImplSalStartTimer( sal_uLong nMS )
+void AquaSalTimer::queueDispatchTimerEvent( bool bAtStart )
+{
+ Stop();
+ m_nTimerStartTicks = tools::Time::GetMonotonicTicks() % SAL_MAX_INT32;
+ if ( 0 == m_nTimerStartTicks )
+ m_nTimerStartTicks++;
+ ImplNSAppPostEvent( AquaSalInstance::DispatchTimerEvent, bAtStart, m_nTimerStartTicks );
+}
+
+void AquaSalTimer::Start( sal_uLong nMS )
{
SalData* pSalData = GetSalData();
@@ -84,27 +91,26 @@ static void ImplSalStartTimer( sal_uLong nMS )
}
if ( 0 == nMS && !pSalData->mpFirstInstance->mbIsLiveResize )
- {
- ImplSalStopTimer();
- ImplNSAppPostEvent( AquaSalInstance::DispatchTimerEvent, NO );
- }
+ queueDispatchTimerEvent( NO );
else
{
NSTimeInterval aTI = double(nMS) / 1000.0;
- if( AquaSalTimer::pRunningTimer != nil )
+ if( m_pRunningTimer != nil )
{
- if ([AquaSalTimer::pRunningTimer isValid] && rtl::math::approxEqual(
- [AquaSalTimer::pRunningTimer timeInterval], aTI))
+ if ([m_pRunningTimer isValid] && rtl::math::approxEqual(
+ [m_pRunningTimer timeInterval], aTI))
{
// set new fire date
- [AquaSalTimer::pRunningTimer setFireDate: [NSDate dateWithTimeIntervalSinceNow: aTI]];
+ [m_pRunningTimer setFireDate: [NSDate dateWithTimeIntervalSinceNow: aTI]];
}
else
- ImplSalStopTimer();
+ Stop();
}
- if( AquaSalTimer::pRunningTimer == nil )
+ else
+ Stop();
+ if( m_pRunningTimer == nil )
{
- AquaSalTimer::pRunningTimer = [[NSTimer scheduledTimerWithTimeInterval: aTI
+ m_pRunningTimer = [[NSTimer scheduledTimerWithTimeInterval: aTI
target: [[[TimerCallbackCaller alloc] init] autorelease]
selector: @selector(timerElapsed:)
userInfo: nil
@@ -113,22 +119,25 @@ static void ImplSalStartTimer( sal_uLong nMS )
/* #i84055# add timer to tracking run loop mode,
so they also elapse while e.g. life resize
*/
- [[NSRunLoop currentRunLoop] addTimer: AquaSalTimer::pRunningTimer forMode: NSEventTrackingRunLoopMode];
+ [[NSRunLoop currentRunLoop] addTimer: m_pRunningTimer forMode: NSEventTrackingRunLoopMode];
}
}
}
-static void ImplSalStopTimer()
+void AquaSalTimer::Stop()
{
- if( AquaSalTimer::pRunningTimer != nil )
+ assert( GetSalData()->mpFirstInstance->IsMainThread() );
+
+ if( m_pRunningTimer != nil )
{
- [AquaSalTimer::pRunningTimer invalidate];
- [AquaSalTimer::pRunningTimer release];
- AquaSalTimer::pRunningTimer = nil;
+ [m_pRunningTimer invalidate];
+ [m_pRunningTimer release];
+ m_pRunningTimer = nil;
}
+ m_nTimerStartTicks = 0;
}
-void AquaSalTimer::handleDispatchTimerEvent()
+void AquaSalTimer::callTimerCallback()
{
ImplSVData* pSVData = ImplGetSVData();
SolarMutexGuard aGuard;
@@ -136,6 +145,23 @@ void AquaSalTimer::handleDispatchTimerEvent()
pSVData->maSchedCtx.mpSalTimer->CallCallback();
}
+void AquaSalTimer::handleTimerElapsed()
+{
+ // Stop the timer, as it is just invalidated after the firing function
+ Stop();
+
+ if ( GetSalData()->mpFirstInstance->mbIsLiveResize )
+ callTimerCallback();
+ else
+ queueDispatchTimerEvent( YES );
+}
+
+void AquaSalTimer::handleDispatchTimerEvent( NSEvent *pEvent )
+{
+ if (m_nTimerStartTicks == [pEvent data1])
+ callTimerCallback();
+}
+
void AquaSalTimer::handleStartTimerEvent( NSEvent* pEvent )
{
ImplSVData* pSVData = ImplGetSVData();
@@ -143,30 +169,33 @@ void AquaSalTimer::handleStartTimerEvent( NSEvent* pEvent )
{
NSTimeInterval posted = [pEvent timestamp] + NSTimeInterval([pEvent data1])/1000.0;
NSTimeInterval current = [NSDate timeIntervalSinceReferenceDate];
- if( (posted - current) <= 0.0 )
- handleDispatchTimerEvent();
- else
- ImplSalStartTimer( sal_uLong( [pEvent data1] ) );
+ sal_uLong nTimeoutMS = 0;
+ if( (posted - current) > 0.0 )
+ nTimeoutMS = ceil( (posted - current) * 1000 );
+ Start( nTimeoutMS );
}
}
-AquaSalTimer::AquaSalTimer( )
-{
-}
-
-AquaSalTimer::~AquaSalTimer()
+bool AquaSalTimer::IsTimerElapsed() const
{
- ImplSalStopTimer();
+ assert( !(m_nTimerStartTicks && m_pRunningTimer) );
+ if ( 0 != m_nTimerStartTicks )
+ return true;
+ if ( !m_pRunningTimer )
+ return false;
+ NSDate* pDt = [m_pRunningTimer fireDate];
+ return pDt && ([pDt timeIntervalSinceNow] < 0);
}
-void AquaSalTimer::Start( sal_uLong nMS )
+AquaSalTimer::AquaSalTimer( )
+ : m_pRunningTimer( nil )
+ , m_nTimerStartTicks( 0 )
{
- ImplSalStartTimer( nMS );
}
-void AquaSalTimer::Stop()
+AquaSalTimer::~AquaSalTimer()
{
- ImplSalStopTimer();
+ Stop();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list