Fix a nasty crash:
* re-order stream schedule/open/setclient * stop unscheduling stream on complete when using persistent connections
Showing
1 changed file
with
24 additions
and
20 deletions
| @@ -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.5-24 2010-01-14"; | 24 | +NSString *ASIHTTPRequestVersion = @"v1.5-25 2010-01-18"; |
| 25 | 25 | ||
| 26 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; | 26 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; |
| 27 | 27 | ||
| @@ -780,7 +780,6 @@ static BOOL isiPhoneOS2; | @@ -780,7 +780,6 @@ static BOOL isiPhoneOS2; | ||
| 780 | // Create the stream for the request | 780 | // Create the stream for the request |
| 781 | [self setReadStreamIsScheduled:NO]; | 781 | [self setReadStreamIsScheduled:NO]; |
| 782 | 782 | ||
| 783 | - | ||
| 784 | // Do we need to stream the request body from disk | 783 | // Do we need to stream the request body from disk |
| 785 | if ([self shouldStreamPostDataFromDisk] && [self postBodyFilePath] && [[NSFileManager defaultManager] fileExistsAtPath:[self postBodyFilePath]]) { | 784 | if ([self shouldStreamPostDataFromDisk] && [self postBodyFilePath] && [[NSFileManager defaultManager] fileExistsAtPath:[self postBodyFilePath]]) { |
| 786 | 785 | ||
| @@ -965,17 +964,13 @@ static BOOL isiPhoneOS2; | @@ -965,17 +964,13 @@ static BOOL isiPhoneOS2; | ||
| 965 | 964 | ||
| 966 | [connectionsLock unlock]; | 965 | [connectionsLock unlock]; |
| 967 | 966 | ||
| 968 | - BOOL streamSuccessfullyOpened = NO; | 967 | + // Schedule the stream |
| 969 | - | 968 | + if (![self readStreamIsScheduled] && (!throttleWakeUpTime || [throttleWakeUpTime timeIntervalSinceDate:[NSDate date]] < 0)) { |
| 970 | - // Set the client | 969 | + [self scheduleReadStream]; |
| 971 | - CFStreamClientContext ctxt = {0, self, NULL, NULL, NULL}; | ||
| 972 | - if (CFReadStreamSetClient((CFReadStreamRef)[self readStream], kNetworkEvents, ReadStreamClientCallBack, &ctxt)) { | ||
| 973 | - // Start the HTTP connection | ||
| 974 | - if (CFReadStreamOpen((CFReadStreamRef)[self readStream])) { | ||
| 975 | - streamSuccessfullyOpened = YES; | ||
| 976 | - } | ||
| 977 | } | 970 | } |
| 978 | 971 | ||
| 972 | + BOOL streamSuccessfullyOpened = NO; | ||
| 973 | + | ||
| 979 | // Here, we'll close the stream that was previously using this connection, if there was one | 974 | // Here, we'll close the stream that was previously using this connection, if there was one |
| 980 | // We've kept it open until now (when we've just opened a new stream) so that the new stream can make use of the old connection | 975 | // We've kept it open until now (when we've just opened a new stream) so that the new stream can make use of the old connection |
| 981 | // http://lists.apple.com/archives/Macnetworkprog/2006/Mar/msg00119.html | 976 | // http://lists.apple.com/archives/Macnetworkprog/2006/Mar/msg00119.html |
| @@ -988,18 +983,24 @@ static BOOL isiPhoneOS2; | @@ -988,18 +983,24 @@ static BOOL isiPhoneOS2; | ||
| 988 | oldStream = nil; | 983 | oldStream = nil; |
| 989 | } | 984 | } |
| 990 | 985 | ||
| 986 | + // Set the client | ||
| 987 | + CFStreamClientContext ctxt = {0, self, NULL, NULL, NULL}; | ||
| 988 | + if (CFReadStreamSetClient((CFReadStreamRef)[self readStream], kNetworkEvents, ReadStreamClientCallBack, &ctxt)) { | ||
| 989 | + // Start the HTTP connection | ||
| 990 | + if (CFReadStreamOpen((CFReadStreamRef)[self readStream])) { | ||
| 991 | + streamSuccessfullyOpened = YES; | ||
| 992 | + } | ||
| 993 | + } | ||
| 994 | + | ||
| 991 | if (!streamSuccessfullyOpened) { | 995 | if (!streamSuccessfullyOpened) { |
| 996 | + [self setCanUsePersistentConnection:NO]; | ||
| 992 | [self destroyReadStream]; | 997 | [self destroyReadStream]; |
| 993 | [[self cancelledLock] unlock]; | 998 | [[self cancelledLock] unlock]; |
| 994 | [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileBuildingRequestType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Unable to start HTTP connection",NSLocalizedDescriptionKey,nil]]]; | 999 | [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileBuildingRequestType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Unable to start HTTP connection",NSLocalizedDescriptionKey,nil]]]; |
| 995 | return; | 1000 | return; |
| 996 | } | 1001 | } |
| 997 | 1002 | ||
| 998 | - | 1003 | + |
| 999 | - // Schedule the stream | ||
| 1000 | - if (![self readStreamIsScheduled] && (!throttleWakeUpTime || [throttleWakeUpTime timeIntervalSinceDate:[NSDate date]] < 0)) { | ||
| 1001 | - [self scheduleReadStream]; | ||
| 1002 | - } | ||
| 1003 | 1004 | ||
| 1004 | [[self cancelledLock] unlock]; | 1005 | [[self cancelledLock] unlock]; |
| 1005 | 1006 | ||
| @@ -2505,7 +2506,9 @@ static BOOL isiPhoneOS2; | @@ -2505,7 +2506,9 @@ static BOOL isiPhoneOS2; | ||
| 2505 | 2506 | ||
| 2506 | 2507 | ||
| 2507 | [connectionsLock lock]; | 2508 | [connectionsLock lock]; |
| 2508 | - [self unscheduleReadStream]; | 2509 | + if (![self canUsePersistentConnection]) { |
| 2510 | + [self unscheduleReadStream]; | ||
| 2511 | + } | ||
| 2509 | #if DEBUG_PERSISTENT_CONNECTIONS | 2512 | #if DEBUG_PERSISTENT_CONNECTIONS |
| 2510 | NSLog(@"Request #%@ finished using connection #%@",[[self connectionInfo] objectForKey:@"request"], [[self connectionInfo] objectForKey:@"id"]); | 2513 | NSLog(@"Request #%@ finished using connection #%@",[[self connectionInfo] objectForKey:@"request"], [[self connectionInfo] objectForKey:@"id"]); |
| 2511 | #endif | 2514 | #endif |
| @@ -2582,10 +2585,11 @@ static BOOL isiPhoneOS2; | @@ -2582,10 +2585,11 @@ static BOOL isiPhoneOS2; | ||
| 2582 | CFReadStreamSetClient((CFReadStreamRef)[self readStream], kCFStreamEventNone, NULL, NULL); | 2585 | CFReadStreamSetClient((CFReadStreamRef)[self readStream], kCFStreamEventNone, NULL, NULL); |
| 2583 | 2586 | ||
| 2584 | [connectionsLock lock]; | 2587 | [connectionsLock lock]; |
| 2585 | - if ([self readStreamIsScheduled]) { | 2588 | + |
| 2586 | - CFReadStreamUnscheduleFromRunLoop((CFReadStreamRef)[self readStream], CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); | ||
| 2587 | - } | ||
| 2588 | if (![self canUsePersistentConnection]) { | 2589 | if (![self canUsePersistentConnection]) { |
| 2590 | + if ([self readStreamIsScheduled]) { | ||
| 2591 | + CFReadStreamUnscheduleFromRunLoop((CFReadStreamRef)[self readStream], CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); | ||
| 2592 | + } | ||
| 2589 | CFStreamStatus status = CFReadStreamGetStatus((CFReadStreamRef)[self readStream]); | 2593 | CFStreamStatus status = CFReadStreamGetStatus((CFReadStreamRef)[self readStream]); |
| 2590 | if (status != kCFStreamStatusClosed && status != kCFStreamStatusError) { | 2594 | if (status != kCFStreamStatusClosed && status != kCFStreamStatusError) { |
| 2591 | CFReadStreamClose((CFReadStreamRef)[self readStream]); | 2595 | CFReadStreamClose((CFReadStreamRef)[self readStream]); |
-
Please register or login to post a comment