Ben Copsey

Only invalidate+release the old status timer when the new one is scheduled - pre…

…vents a crash for async requests when only the timer is retaining the request
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 #import "ASIInputStream.h" 21 #import "ASIInputStream.h"
22 22
23 // Automatically set on build 23 // Automatically set on build
24 -NSString *ASIHTTPRequestVersion = @"v1.2-65 2010-01-05"; 24 +NSString *ASIHTTPRequestVersion = @"v1.2-66 2010-01-05";
25 25
26 NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; 26 NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain";
27 27
@@ -1021,7 +1021,7 @@ static BOOL isiPhoneOS2; @@ -1021,7 +1021,7 @@ static BOOL isiPhoneOS2;
1021 // Record when the request started, so we can timeout if nothing happens 1021 // Record when the request started, so we can timeout if nothing happens
1022 [self setLastActivityTime:[NSDate date]]; 1022 [self setLastActivityTime:[NSDate date]];
1023 1023
1024 - [[self statusTimer] invalidate]; 1024 +
1025 [self setStatusTimer:[NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(updateStatus:) userInfo:nil repeats:YES]]; 1025 [self setStatusTimer:[NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(updateStatus:) userInfo:nil repeats:YES]];
1026 1026
1027 // If we're running asynchronously on the main thread, the runloop will already be running and we can return control 1027 // If we're running asynchronously on the main thread, the runloop will already be running and we can return control
@@ -1032,6 +1032,17 @@ static BOOL isiPhoneOS2; @@ -1032,6 +1032,17 @@ static BOOL isiPhoneOS2;
1032 } 1032 }
1033 } 1033 }
1034 1034
  1035 +- (void)setStatusTimer:(NSTimer *)timer
  1036 +{
  1037 + // We must invalidate the old timer here, not before we've created and scheduled a new timer
  1038 + // This is because the timer may be the only thing retaining an asynchronous request
  1039 + if (timer != [self statusTimer]) {
  1040 + [[self statusTimer] invalidate];
  1041 + [[self statusTimer] release];
  1042 + }
  1043 + statusTimer = [timer retain];
  1044 +}
  1045 +
1035 - (void)performRedirect 1046 - (void)performRedirect
1036 { 1047 {
1037 [[self cancelledLock] lock]; 1048 [[self cancelledLock] lock];
@@ -1055,8 +1066,7 @@ static BOOL isiPhoneOS2; @@ -1055,8 +1066,7 @@ static BOOL isiPhoneOS2;
1055 - (void)updateStatus:(NSTimer*)timer 1066 - (void)updateStatus:(NSTimer*)timer
1056 { 1067 {
1057 [self checkRequestStatus]; 1068 [self checkRequestStatus];
1058 - if ([self complete] || [self error]) { 1069 + if (![self inProgress]) {
1059 - [timer invalidate];  
1060 [self setStatusTimer:nil]; 1070 [self setStatusTimer:nil];
1061 CFRunLoopStop(CFRunLoopGetCurrent()); 1071 CFRunLoopStop(CFRunLoopGetCurrent());
1062 } 1072 }