Change timer behaviour to prevent endless recursion
Stop running runloop in checkRequestStatus, it's not nescessary and it meant we were updating progress every 0.5 secs rather than every 0.25 secs Remove authenticationLock, delegate-style auth is now non-blocking Requests on standard run loop
Showing
2 changed files
with
24 additions
and
72 deletions
@@ -228,9 +228,6 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | @@ -228,9 +228,6 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | ||
228 | // Last amount of data sent (used for incrementing progress) | 228 | // Last amount of data sent (used for incrementing progress) |
229 | unsigned long long lastBytesSent; | 229 | unsigned long long lastBytesSent; |
230 | 230 | ||
231 | - // This lock will block the request until the delegate supplies authentication info | ||
232 | - NSConditionLock *authenticationLock; | ||
233 | - | ||
234 | // This lock prevents the operation from being cancelled at an inopportune moment | 231 | // This lock prevents the operation from being cancelled at an inopportune moment |
235 | NSRecursiveLock *cancelledLock; | 232 | NSRecursiveLock *cancelledLock; |
236 | 233 |
@@ -20,10 +20,6 @@ | @@ -20,10 +20,6 @@ | ||
20 | #endif | 20 | #endif |
21 | #import "ASIInputStream.h" | 21 | #import "ASIInputStream.h" |
22 | 22 | ||
23 | - | ||
24 | -// We use our own custom run loop mode as CoreAnimation seems to want to hijack our threads otherwise | ||
25 | -static CFStringRef ASIHTTPRequestRunMode = CFSTR("ASIHTTPRequest"); | ||
26 | - | ||
27 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; | 23 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; |
28 | 24 | ||
29 | static const CFOptionFlags kNetworkEvents = kCFStreamEventOpenCompleted | kCFStreamEventHasBytesAvailable | kCFStreamEventEndEncountered | kCFStreamEventErrorOccurred; | 25 | static const CFOptionFlags kNetworkEvents = kCFStreamEventOpenCompleted | kCFStreamEventHasBytesAvailable | kCFStreamEventEndEncountered | kCFStreamEventErrorOccurred; |
@@ -134,7 +130,6 @@ static BOOL isiPhoneOS2; | @@ -134,7 +130,6 @@ static BOOL isiPhoneOS2; | ||
134 | @property (assign, nonatomic) int redirectCount; | 130 | @property (assign, nonatomic) int redirectCount; |
135 | @property (retain, nonatomic) NSData *compressedPostBody; | 131 | @property (retain, nonatomic) NSData *compressedPostBody; |
136 | @property (retain, nonatomic) NSString *compressedPostBodyFilePath; | 132 | @property (retain, nonatomic) NSString *compressedPostBodyFilePath; |
137 | -@property (retain) NSConditionLock *authenticationLock; | ||
138 | @property (retain) NSString *authenticationRealm; | 133 | @property (retain) NSString *authenticationRealm; |
139 | @property (retain) NSString *proxyAuthenticationRealm; | 134 | @property (retain) NSString *proxyAuthenticationRealm; |
140 | @property (retain) NSString *responseStatusMessage; | 135 | @property (retain) NSString *responseStatusMessage; |
@@ -240,7 +235,6 @@ static BOOL isiPhoneOS2; | @@ -240,7 +235,6 @@ static BOOL isiPhoneOS2; | ||
240 | [proxyAuthenticationScheme release]; | 235 | [proxyAuthenticationScheme release]; |
241 | [proxyCredentials release]; | 236 | [proxyCredentials release]; |
242 | [url release]; | 237 | [url release]; |
243 | - [authenticationLock release]; | ||
244 | [lastActivityTime release]; | 238 | [lastActivityTime release]; |
245 | [responseCookies release]; | 239 | [responseCookies release]; |
246 | [rawResponseData release]; | 240 | [rawResponseData release]; |
@@ -722,8 +716,6 @@ static BOOL isiPhoneOS2; | @@ -722,8 +716,6 @@ static BOOL isiPhoneOS2; | ||
722 | 716 | ||
723 | [self requestStarted]; | 717 | [self requestStarted]; |
724 | 718 | ||
725 | - [self setAuthenticationLock:[[[NSConditionLock alloc] initWithCondition:1] autorelease]]; | ||
726 | - | ||
727 | [self setComplete:NO]; | 719 | [self setComplete:NO]; |
728 | [self setTotalBytesRead:0]; | 720 | [self setTotalBytesRead:0]; |
729 | [self setLastBytesRead:0]; | 721 | [self setLastBytesRead:0]; |
@@ -850,12 +842,12 @@ static BOOL isiPhoneOS2; | @@ -850,12 +842,12 @@ static BOOL isiPhoneOS2; | ||
850 | } | 842 | } |
851 | 843 | ||
852 | // Schedule the stream | 844 | // Schedule the stream |
853 | - CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), ASIHTTPRequestRunMode); | 845 | + CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); |
854 | 846 | ||
855 | // Start the HTTP connection | 847 | // Start the HTTP connection |
856 | if (!CFReadStreamOpen(readStream)) { | 848 | if (!CFReadStreamOpen(readStream)) { |
857 | CFReadStreamSetClient(readStream, 0, NULL, NULL); | 849 | CFReadStreamSetClient(readStream, 0, NULL, NULL); |
858 | - CFReadStreamUnscheduleFromRunLoop(readStream, CFRunLoopGetCurrent(), ASIHTTPRequestRunMode); | 850 | + CFReadStreamUnscheduleFromRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); |
859 | CFRelease(readStream); | 851 | CFRelease(readStream); |
860 | readStream = NULL; | 852 | readStream = NULL; |
861 | [[self cancelledLock] unlock]; | 853 | [[self cancelledLock] unlock]; |
@@ -884,12 +876,12 @@ static BOOL isiPhoneOS2; | @@ -884,12 +876,12 @@ static BOOL isiPhoneOS2; | ||
884 | 876 | ||
885 | - (void)loadAsynchronous | 877 | - (void)loadAsynchronous |
886 | { | 878 | { |
887 | - [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(updateStatus:) userInfo:nil repeats:NO]; | 879 | + [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(updateStatus:) userInfo:nil repeats:YES]; |
888 | 880 | ||
889 | // If we're running asynchronously on the main thread, the runloop will already be running | 881 | // If we're running asynchronously on the main thread, the runloop will already be running |
890 | if (![NSThread isMainThread]) { | 882 | if (![NSThread isMainThread]) { |
891 | // Will stop automatically when the request is done | 883 | // Will stop automatically when the request is done |
892 | - CFRunLoopRun(); | 884 | + CFRunLoopRun(); |
893 | } | 885 | } |
894 | } | 886 | } |
895 | 887 | ||
@@ -899,7 +891,7 @@ static BOOL isiPhoneOS2; | @@ -899,7 +891,7 @@ static BOOL isiPhoneOS2; | ||
899 | { | 891 | { |
900 | while (!complete) { | 892 | while (!complete) { |
901 | [self checkRequestStatus]; | 893 | [self checkRequestStatus]; |
902 | - CFRunLoopRunInMode(ASIHTTPRequestRunMode, 0.25, NO); | 894 | + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.25, NO); |
903 | } | 895 | } |
904 | } | 896 | } |
905 | 897 | ||
@@ -908,10 +900,9 @@ static BOOL isiPhoneOS2; | @@ -908,10 +900,9 @@ static BOOL isiPhoneOS2; | ||
908 | { | 900 | { |
909 | [self checkRequestStatus]; | 901 | [self checkRequestStatus]; |
910 | if ([self complete] || [self error]) { | 902 | if ([self complete] || [self error]) { |
903 | + [timer invalidate]; | ||
911 | [self willChangeValueForKey:@"isFinished"]; | 904 | [self willChangeValueForKey:@"isFinished"]; |
912 | [self didChangeValueForKey:@"isFinished"]; | 905 | [self didChangeValueForKey:@"isFinished"]; |
913 | - } else { | ||
914 | - [self loadAsynchronous]; | ||
915 | } | 906 | } |
916 | } | 907 | } |
917 | 908 | ||
@@ -962,26 +953,27 @@ static BOOL isiPhoneOS2; | @@ -962,26 +953,27 @@ static BOOL isiPhoneOS2; | ||
962 | return; | 953 | return; |
963 | } | 954 | } |
964 | 955 | ||
956 | + // readStream will be null if we aren't currently running (perhaps we're waiting for a delegate to supply credentials) | ||
965 | if (readStream) { | 957 | if (readStream) { |
958 | + | ||
959 | + // Find out if we've sent any more data than last time, and reset the timeout if so | ||
960 | + if (totalBytesSent > lastBytesSent) { | ||
961 | + [self setLastActivityTime:[NSDate date]]; | ||
962 | + [self setLastBytesSent:totalBytesSent]; | ||
963 | + } | ||
966 | 964 | ||
967 | - // Find out if we've sent any more data than last time, and reset the timeout if so | 965 | + // Find out how much data we've uploaded so far |
968 | - if (totalBytesSent > lastBytesSent) { | 966 | + [self setTotalBytesSent:[[(NSNumber *)CFReadStreamCopyProperty(readStream, kCFStreamPropertyHTTPRequestBytesWrittenCount) autorelease] unsignedLongLongValue]]; |
969 | - [self setLastActivityTime:[NSDate date]]; | 967 | + |
970 | - [self setLastBytesSent:totalBytesSent]; | 968 | + |
971 | - } | 969 | + [self updateProgressIndicators]; |
972 | - | 970 | + |
973 | - // Find out how much data we've uploaded so far | 971 | + // Measure bandwidth used, and throttle if nescessary |
974 | - [self setTotalBytesSent:[[(NSNumber *)CFReadStreamCopyProperty(readStream, kCFStreamPropertyHTTPRequestBytesWrittenCount) autorelease] unsignedLongLongValue]]; | 972 | + [ASIHTTPRequest measureBandwidthUsage]; |
975 | - | ||
976 | - | ||
977 | - [self updateProgressIndicators]; | ||
978 | - | ||
979 | - // Measure bandwidth used, and throttle if nescessary | ||
980 | - [ASIHTTPRequest measureBandwidthUsage]; | ||
981 | } | 973 | } |
982 | 974 | ||
983 | // This thread should wait for 1/4 second for the stream to do something | 975 | // This thread should wait for 1/4 second for the stream to do something |
984 | - CFRunLoopRunInMode(ASIHTTPRequestRunMode,0.25,NO); | 976 | + //CFRunLoopRunInMode(kCFRunLoopDefaultMode,0.25,NO); |
985 | 977 | ||
986 | 978 | ||
987 | [[self cancelledLock] unlock]; | 979 | [[self cancelledLock] unlock]; |
@@ -993,7 +985,7 @@ static BOOL isiPhoneOS2; | @@ -993,7 +985,7 @@ static BOOL isiPhoneOS2; | ||
993 | { | 985 | { |
994 | if (readStream) { | 986 | if (readStream) { |
995 | CFReadStreamSetClient(readStream, kCFStreamEventNone, NULL, NULL); | 987 | CFReadStreamSetClient(readStream, kCFStreamEventNone, NULL, NULL); |
996 | - CFReadStreamUnscheduleFromRunLoop(readStream, CFRunLoopGetCurrent(), ASIHTTPRequestRunMode); | 988 | + CFReadStreamUnscheduleFromRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); |
997 | CFReadStreamClose(readStream); | 989 | CFReadStreamClose(readStream); |
998 | CFRelease(readStream); | 990 | CFRelease(readStream); |
999 | readStream = NULL; | 991 | readStream = NULL; |
@@ -1750,8 +1742,6 @@ static BOOL isiPhoneOS2; | @@ -1750,8 +1742,6 @@ static BOOL isiPhoneOS2; | ||
1750 | - (void)cancelAuthentication | 1742 | - (void)cancelAuthentication |
1751 | { | 1743 | { |
1752 | [self failWithError:ASIAuthenticationError]; | 1744 | [self failWithError:ASIAuthenticationError]; |
1753 | - [[self authenticationLock] lockWhenCondition:1]; | ||
1754 | - [[self authenticationLock] unlockWithCondition:2]; | ||
1755 | } | 1745 | } |
1756 | 1746 | ||
1757 | - (BOOL)showProxyAuthenticationDialog | 1747 | - (BOOL)showProxyAuthenticationDialog |
@@ -1761,11 +1751,6 @@ static BOOL isiPhoneOS2; | @@ -1761,11 +1751,6 @@ static BOOL isiPhoneOS2; | ||
1761 | // Cannot show the dialog when we are running on the main thread, as the locks will cause the app to hang | 1751 | // Cannot show the dialog when we are running on the main thread, as the locks will cause the app to hang |
1762 | if ([self shouldPresentProxyAuthenticationDialog] && ![NSThread isMainThread]) { | 1752 | if ([self shouldPresentProxyAuthenticationDialog] && ![NSThread isMainThread]) { |
1763 | [ASIAuthenticationDialog performSelectorOnMainThread:@selector(presentProxyAuthenticationDialogForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; | 1753 | [ASIAuthenticationDialog performSelectorOnMainThread:@selector(presentProxyAuthenticationDialogForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; |
1764 | - [[self authenticationLock] lockWhenCondition:2]; | ||
1765 | - [[self authenticationLock] unlockWithCondition:1]; | ||
1766 | - if ([self error]) { | ||
1767 | - return NO; | ||
1768 | - } | ||
1769 | return YES; | 1754 | return YES; |
1770 | } | 1755 | } |
1771 | return NO; | 1756 | return NO; |
@@ -1791,13 +1776,6 @@ static BOOL isiPhoneOS2; | @@ -1791,13 +1776,6 @@ static BOOL isiPhoneOS2; | ||
1791 | 1776 | ||
1792 | if ([authenticationDelegate respondsToSelector:@selector(proxyAuthenticationNeededForRequest:)]) { | 1777 | if ([authenticationDelegate respondsToSelector:@selector(proxyAuthenticationNeededForRequest:)]) { |
1793 | [authenticationDelegate performSelectorOnMainThread:@selector(proxyAuthenticationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; | 1778 | [authenticationDelegate performSelectorOnMainThread:@selector(proxyAuthenticationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; |
1794 | - [[self authenticationLock] lockWhenCondition:2]; | ||
1795 | - [[self authenticationLock] unlockWithCondition:1]; | ||
1796 | - | ||
1797 | - // Was the request cancelled? | ||
1798 | - if ([self error] || [[self mainRequest] error]) { | ||
1799 | - return NO; | ||
1800 | - } | ||
1801 | return YES; | 1779 | return YES; |
1802 | } | 1780 | } |
1803 | return NO; | 1781 | return NO; |
@@ -1941,13 +1919,11 @@ static BOOL isiPhoneOS2; | @@ -1941,13 +1919,11 @@ static BOOL isiPhoneOS2; | ||
1941 | } | 1919 | } |
1942 | 1920 | ||
1943 | if ([self askDelegateForProxyCredentials]) { | 1921 | if ([self askDelegateForProxyCredentials]) { |
1944 | - [self attemptToApplyProxyCredentialsAndResume]; | ||
1945 | [delegateAuthenticationLock unlock]; | 1922 | [delegateAuthenticationLock unlock]; |
1946 | return; | 1923 | return; |
1947 | } | 1924 | } |
1948 | 1925 | ||
1949 | if ([self showProxyAuthenticationDialog]) { | 1926 | if ([self showProxyAuthenticationDialog]) { |
1950 | - [self attemptToApplyProxyCredentialsAndResume]; | ||
1951 | [delegateAuthenticationLock unlock]; | 1927 | [delegateAuthenticationLock unlock]; |
1952 | return; | 1928 | return; |
1953 | } | 1929 | } |
@@ -1967,11 +1943,6 @@ static BOOL isiPhoneOS2; | @@ -1967,11 +1943,6 @@ static BOOL isiPhoneOS2; | ||
1967 | // Cannot show the dialog when we are running on the main thread, as the locks will cause the app to hang | 1943 | // Cannot show the dialog when we are running on the main thread, as the locks will cause the app to hang |
1968 | if ([self shouldPresentAuthenticationDialog]) { | 1944 | if ([self shouldPresentAuthenticationDialog]) { |
1969 | [ASIAuthenticationDialog performSelectorOnMainThread:@selector(presentAuthenticationDialogForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; | 1945 | [ASIAuthenticationDialog performSelectorOnMainThread:@selector(presentAuthenticationDialogForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; |
1970 | - [[self authenticationLock] lockWhenCondition:2]; | ||
1971 | - [[self authenticationLock] unlockWithCondition:1]; | ||
1972 | - if ([self error]) { | ||
1973 | - return NO; | ||
1974 | - } | ||
1975 | return YES; | 1946 | return YES; |
1976 | } | 1947 | } |
1977 | return NO; | 1948 | return NO; |
@@ -1982,11 +1953,6 @@ static BOOL isiPhoneOS2; | @@ -1982,11 +1953,6 @@ static BOOL isiPhoneOS2; | ||
1982 | 1953 | ||
1983 | - (BOOL)askDelegateForCredentials | 1954 | - (BOOL)askDelegateForCredentials |
1984 | { | 1955 | { |
1985 | -// // Can't use delegate authentication when running on the main thread | ||
1986 | -// if ([NSThread isMainThread]) { | ||
1987 | -// return NO; | ||
1988 | -// } | ||
1989 | - | ||
1990 | // If we have a delegate, we'll see if it can handle proxyAuthenticationNeededForRequest:. | 1956 | // If we have a delegate, we'll see if it can handle proxyAuthenticationNeededForRequest:. |
1991 | // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate | 1957 | // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate |
1992 | id authenticationDelegate = [self delegate]; | 1958 | id authenticationDelegate = [self delegate]; |
@@ -1996,13 +1962,6 @@ static BOOL isiPhoneOS2; | @@ -1996,13 +1962,6 @@ static BOOL isiPhoneOS2; | ||
1996 | 1962 | ||
1997 | if ([authenticationDelegate respondsToSelector:@selector(authenticationNeededForRequest:)]) { | 1963 | if ([authenticationDelegate respondsToSelector:@selector(authenticationNeededForRequest:)]) { |
1998 | [authenticationDelegate performSelectorOnMainThread:@selector(authenticationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; | 1964 | [authenticationDelegate performSelectorOnMainThread:@selector(authenticationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; |
1999 | - //[[self authenticationLock] lockWhenCondition:2]; | ||
2000 | -// [[self authenticationLock] unlockWithCondition:1]; | ||
2001 | -// | ||
2002 | -// // Was the request cancelled? | ||
2003 | -// if ([self error] || [[self mainRequest] error]) { | ||
2004 | -// return NO; | ||
2005 | - //} | ||
2006 | return YES; | 1965 | return YES; |
2007 | } | 1966 | } |
2008 | return NO; | 1967 | return NO; |
@@ -2077,12 +2036,10 @@ static BOOL isiPhoneOS2; | @@ -2077,12 +2036,10 @@ static BOOL isiPhoneOS2; | ||
2077 | [self setLastActivityTime:nil]; | 2036 | [self setLastActivityTime:nil]; |
2078 | 2037 | ||
2079 | if ([self askDelegateForCredentials]) { | 2038 | if ([self askDelegateForCredentials]) { |
2080 | - [self attemptToApplyCredentialsAndResume]; | ||
2081 | [delegateAuthenticationLock unlock]; | 2039 | [delegateAuthenticationLock unlock]; |
2082 | return; | 2040 | return; |
2083 | } | 2041 | } |
2084 | if ([self showAuthenticationDialog]) { | 2042 | if ([self showAuthenticationDialog]) { |
2085 | - [self attemptToApplyCredentialsAndResume]; | ||
2086 | [delegateAuthenticationLock unlock]; | 2043 | [delegateAuthenticationLock unlock]; |
2087 | return; | 2044 | return; |
2088 | } | 2045 | } |
@@ -2150,7 +2107,6 @@ static BOOL isiPhoneOS2; | @@ -2150,7 +2107,6 @@ static BOOL isiPhoneOS2; | ||
2150 | } | 2107 | } |
2151 | 2108 | ||
2152 | if ([self showAuthenticationDialog]) { | 2109 | if ([self showAuthenticationDialog]) { |
2153 | - [self attemptToApplyCredentialsAndResume]; | ||
2154 | [delegateAuthenticationLock unlock]; | 2110 | [delegateAuthenticationLock unlock]; |
2155 | return; | 2111 | return; |
2156 | } | 2112 | } |
@@ -2304,7 +2260,7 @@ static BOOL isiPhoneOS2; | @@ -2304,7 +2260,7 @@ static BOOL isiPhoneOS2; | ||
2304 | 2260 | ||
2305 | if (readStream) { | 2261 | if (readStream) { |
2306 | CFReadStreamSetClient(readStream, kCFStreamEventNone, NULL, NULL); | 2262 | CFReadStreamSetClient(readStream, kCFStreamEventNone, NULL, NULL); |
2307 | - CFReadStreamUnscheduleFromRunLoop(readStream, CFRunLoopGetCurrent(), ASIHTTPRequestRunMode); | 2263 | + CFReadStreamUnscheduleFromRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); |
2308 | CFReadStreamClose(readStream); | 2264 | CFReadStreamClose(readStream); |
2309 | CFRelease(readStream); | 2265 | CFRelease(readStream); |
2310 | readStream = NULL; | 2266 | readStream = NULL; |
@@ -3268,7 +3224,6 @@ static BOOL isiPhoneOS2; | @@ -3268,7 +3224,6 @@ static BOOL isiPhoneOS2; | ||
3268 | @synthesize needsRedirect; | 3224 | @synthesize needsRedirect; |
3269 | @synthesize redirectCount; | 3225 | @synthesize redirectCount; |
3270 | @synthesize shouldCompressRequestBody; | 3226 | @synthesize shouldCompressRequestBody; |
3271 | -@synthesize authenticationLock; | ||
3272 | @synthesize needsProxyAuthentication; | 3227 | @synthesize needsProxyAuthentication; |
3273 | @synthesize proxyCredentials; | 3228 | @synthesize proxyCredentials; |
3274 | @synthesize proxyHost; | 3229 | @synthesize proxyHost; |
-
Please register or login to post a comment