From dd0b17ac3cf1a9a991b0febbb428d4a70509d118 Mon Sep 17 00:00:00 2001 From: Richard Frith-MacDonald Date: Sun, 3 Feb 2013 06:37:42 +0000 Subject: [PATCH] thread exist safety fixup git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/performance/trunk@36058 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 6 ++++++ GSTicker.m | 35 ++++++++++++++++++++--------------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index c443584..7221bd2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-02-03 Richard Frith-Macdonald + + * GSTicker.m: Retain timer so that we can safely invalidate it even + on thread exit when the runloop of the current thread may have been + deallocated already. + 2012-01-11 Niels Grewe * GSSkipMutableArray.m: Change -initWithObjects:count: declaration diff --git a/GSTicker.m b/GSTicker.m index 12e8d02..2b6c62b 100644 --- a/GSTicker.m +++ b/GSTicker.m @@ -66,6 +66,12 @@ static volatile NSTimeInterval lastTime = 0; @interface GSTickerThread : NSObject { @public + /* NB. We retain theTimer rather than depending on the run loop to do it. + * This is because tis object is typically deallocated on thread exist, + * so the thread's run loop may be deallocated before this object is + * deallocated, and we want to be sure the timer is not already deallocated + * when we invalidate it. + */ NSTimer *theTimer; NSMutableArray *observers; unsigned last; @@ -76,6 +82,7 @@ static volatile NSTimeInterval lastTime = 0; - (void) dealloc { [theTimer invalidate]; + [theTimer release]; theTimer = nil; [observers release]; observers = nil; @@ -88,11 +95,11 @@ static volatile NSTimeInterval lastTime = 0; NSTimeInterval ti = GSTickerTimeNow(); observers = [NSMutableArray new]; - theTimer = [NSTimer scheduledTimerWithTimeInterval: ti - (int)ti - target: [GSTicker class] - selector: @selector(_tick:) - userInfo: self - repeats: NO]; + theTimer = [[NSTimer scheduledTimerWithTimeInterval: ti - (int)ti + target: [GSTicker class] + selector: @selector(_tick:) + userInfo: self + repeats: NO] retain]; } return self; } @@ -307,11 +314,9 @@ NSTimeInterval GSTickerTimeNow() { NSTimeInterval ti; - if (tt->theTimer != t) - { - [tt->theTimer invalidate]; - tt->theTimer = nil; - } + [tt->theTimer invalidate]; + [tt->theTimer release]; + tt->theTimer = nil; if ([tt->observers count] > 0) { @@ -339,11 +344,11 @@ NSTimeInterval GSTickerTimeNow() } ti = GSTickerTimeNow(); - tt->theTimer = [NSTimer scheduledTimerWithTimeInterval: ti - (int)ti - target: self - selector: @selector(_tick:) - userInfo: tt - repeats: NO]; + tt->theTimer = [[NSTimer scheduledTimerWithTimeInterval: ti - (int)ti + target: self + selector: @selector(_tick:) + userInfo: tt + repeats: NO] retain]; } else {