Proposed fix to the race condition that occurs when stressing AFURLConnectionOperation.

Cancels the NSURLConnection on the same thread as the one where it was created.
This commit is contained in:
Erik Olsson 2012-02-23 18:05:27 +01:00
parent 5ad4ca34f5
commit f0ce3a86e3

View file

@ -334,22 +334,26 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat
self.state = AFHTTPOperationFinishedState; self.state = AFHTTPOperationFinishedState;
} }
- (void)cancel { -(void)cancelConnection {
[self.lock lock];
if (![self isFinished] && ![self isCancelled]) {
[super cancel];
[self willChangeValueForKey:@"isCancelled"]; [self willChangeValueForKey:@"isCancelled"];
_cancelled = YES; _cancelled = YES;
if (self.connection) { if (self.connection) {
[self.connection cancel]; [self.connection cancel];
//We must send this delegate protcol message ourselves since the above [self.connection cancel] causes the connection to never send another message to its delegate. //We must send this delegate protcol message ourselves since the above [self.connection cancel] causes the connection to never send another message to its delegate.
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[self.request URL] forKey:NSURLErrorFailingURLErrorKey]; NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[self.request URL] forKey:NSURLErrorFailingURLErrorKey];
[self performSelector:@selector(connection:didFailWithError:) withObject:self.connection withObject:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:userInfo]]; [self performSelector:@selector(connection:didFailWithError:) withObject:self.connection withObject:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:userInfo]];
} }
[self didChangeValueForKey:@"isCancelled"]; [self didChangeValueForKey:@"isCancelled"];
} }
- (void)cancel {
[self.lock lock];
if (![self isFinished] && ![self isCancelled]) {
[super cancel];
[self performSelector:@selector(cancelConnection) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];
}
[self.lock unlock]; [self.lock unlock];
} }