Make firing of timers more robust

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31420 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2010-09-25 21:28:07 +00:00
parent 6d16a28788
commit 8bd0177292
2 changed files with 45 additions and 24 deletions

View file

@ -1,3 +1,9 @@
2010-09-25 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSTimer.m: ([-fire]) make firing more robust by retaining
the target so it cannot be deallocated while we are performing a
method on it. Do nothing if timer is already invalidated.
2010-09-24 Richard Frith-Macdonald <rfm@gnu.org> 2010-09-24 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSCharacterSet.m: Build using the faster but more memory * Source/NSCharacterSet.m: Build using the faster but more memory

View file

@ -223,19 +223,31 @@ static Class NSDate_class;
* Exceptions raised during firing of the timer are caught and logged. * Exceptions raised during firing of the timer are caught and logged.
*/ */
- (void) fire - (void) fire
{
id target;
/* We retain the target so it won't be deallocated while we are using it
* (if this timer gets invalidated while we are firing).
*/
target = [_target retain];
/* We check that we have not been invalidated before we fire.
*/
if (NO == _invalidated)
{ {
if (_selector == 0) if (_selector == 0)
{ {
NS_DURING NS_DURING
{ {
[(NSInvocation*)_target invoke]; [(NSInvocation*)target invoke];
} }
NS_HANDLER NS_HANDLER
{ {
NSLog(@"*** NSTimer ignoring exception '%@' (reason '%@') " NSLog(@"*** NSTimer ignoring exception '%@' (reason '%@') "
@"raised during posting of timer with target %p and selector '%@'", @"raised during posting of timer with target %p "
[localException name], [localException reason], _target, @"and selector '%@'",
NSStringFromSelector([_target selector])); [localException name], [localException reason], target,
NSStringFromSelector([target selector]));
} }
NS_ENDHANDLER NS_ENDHANDLER
} }
@ -243,17 +255,20 @@ static Class NSDate_class;
{ {
NS_DURING NS_DURING
{ {
[_target performSelector: _selector withObject: self]; [target performSelector: _selector withObject: self];
} }
NS_HANDLER NS_HANDLER
{ {
NSLog(@"*** NSTimer ignoring exception '%@' (reason '%@') " NSLog(@"*** NSTimer ignoring exception '%@' (reason '%@') "
@"raised during posting of timer with target %p and selector '%@'", @"raised during posting of timer with target %p and "
[localException name], [localException reason], _target, @"selector '%@'",
[localException name], [localException reason], target,
NSStringFromSelector(_selector)); NSStringFromSelector(_selector));
} }
NS_ENDHANDLER NS_ENDHANDLER
} }
}
[target release];
if (_repeats == NO) if (_repeats == NO)
{ {