Changeset 149520 in webkit
- Timestamp:
- May 3, 2013 12:10:20 AM (11 years ago)
- Location:
- trunk/Source/WebKit2
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r149499 r149520 1 2013-05-02 Andy Estes <aestes@apple.com> 2 3 [WK2][CustomProtocols] NSURLProtocolClient methods should be dispatched on NSURLConnection's resource loader run loop 4 https://bugs.webkit.org/show_bug.cgi?id=115539 5 6 Reviewed by Alexey Proskuryakov. 7 8 It turns out that calling NSURLProtocolClient methods from a different 9 thread than the one running the NSURLConnection run loop is unsafe. 10 Although I can't capture it reliably in a test case, doing so can 11 sometimes result in a load timing out because the call to 12 -[NSURLProtocolClient URLProtocolDidFinishLoading:] was ignored by 13 NSURLConnection. 14 15 Fix this by dispatching these methods on the NSURLConnection resource 16 load run loop. This matches where NSURLProtocolClient methods are 17 dispatched by typical NSURLProtocol implementations, and in my testing 18 this solves the timeout issue. 19 20 * Shared/Network/CustomProtocols/CustomProtocolManager.h: Declare 21 dispatchOnResourceLoaderRunLoop(). 22 * Shared/Network/CustomProtocols/mac/CustomProtocolManagerMac.mm: 23 Declare +[NSURLConnection resourceLoaderRunLoop] on a category of 24 NSURLConnection. Also include the header that declares it if it's present. 25 (WebKit::CustomProtocolManager::didFailWithError): Call the 26 NSURLProtocolClient method via dispatchOnResourceLoaderRunLoop(). 27 (WebKit::CustomProtocolManager::didLoadData): Ditto. 28 (WebKit::CustomProtocolManager::didReceiveResponse): Ditto. 29 (WebKit::CustomProtocolManager::didFinishLoading): Ditto. 30 (WebKit::CustomProtocolManager::dispatchOnResourceLoaderRunLoop): 31 Dispatch a block on the NSURLConnection resource loader run loop and 32 then wake up the run loop. 33 1 34 2013-05-02 Brady Eidson <beidson@apple.com> 2 35 -
trunk/Source/WebKit2/Shared/Network/CustomProtocols/mac/CustomProtocolManagerMac.mm
r149198 r149520 44 44 #endif 45 45 46 #ifdef __has_include 47 #if __has_include(<Foundation/NSURLConnectionPrivate.h>) 48 #import <Foundation/NSURLConnectionPrivate.h> 49 #endif 50 #endif 51 52 @interface NSURLConnection (Details) 53 + (CFRunLoopRef)resourceLoaderRunLoop; 54 @end 55 46 56 using namespace WebKit; 47 57 … … 187 197 } 188 198 199 static inline void dispatchOnResourceLoaderRunLoop(void (^block)()) 200 { 201 CFRunLoopPerformBlock([NSURLConnection resourceLoaderRunLoop], kCFRunLoopDefaultMode, block); 202 CFRunLoopWakeUp([NSURLConnection resourceLoaderRunLoop]); 203 } 204 189 205 void CustomProtocolManager::didFailWithError(uint64_t customProtocolID, const WebCore::ResourceError& error) 190 206 { … … 193 209 return; 194 210 195 [[protocol.get() client] URLProtocol:protocol.get() didFailWithError:error.nsError()]; 211 RetainPtr<NSError> nsError = error.nsError(); 212 213 dispatchOnResourceLoaderRunLoop(^ { 214 [[protocol.get() client] URLProtocol:protocol.get() didFailWithError:nsError.get()]; 215 }); 216 196 217 removeCustomProtocol(protocol.get()); 197 218 } … … 202 223 if (!protocol) 203 224 return; 204 205 [[protocol.get() client] URLProtocol:protocol.get() didLoadData:[NSData dataWithBytes:(void*)data.data() length:data.size()]]; 225 226 RetainPtr<NSData> nsData = adoptNS([[NSData alloc] initWithBytes:data.data() length:data.size()]); 227 228 dispatchOnResourceLoaderRunLoop(^ { 229 [[protocol.get() client] URLProtocol:protocol.get() didLoadData:nsData.get()]; 230 }); 206 231 } 207 232 … … 211 236 if (!protocol) 212 237 return; 213 214 [[protocol.get() client] URLProtocol:protocol.get() didReceiveResponse:response.nsURLResponse() cacheStoragePolicy:static_cast<NSURLCacheStoragePolicy>(cacheStoragePolicy)]; 238 239 RetainPtr<NSURLResponse> nsResponse = response.nsURLResponse(); 240 241 dispatchOnResourceLoaderRunLoop(^ { 242 [[protocol.get() client] URLProtocol:protocol.get() didReceiveResponse:nsResponse.get() cacheStoragePolicy:static_cast<NSURLCacheStoragePolicy>(cacheStoragePolicy)]; 243 }); 215 244 } 216 245 … … 220 249 if (!protocol) 221 250 return; 222 223 [[protocol.get() client] URLProtocolDidFinishLoading:protocol.get()]; 251 252 dispatchOnResourceLoaderRunLoop(^ { 253 [[protocol.get() client] URLProtocolDidFinishLoading:protocol.get()]; 254 }); 255 224 256 removeCustomProtocol(protocol.get()); 225 257 }
Note: See TracChangeset
for help on using the changeset viewer.