Changeset 219089 in webkit
- Timestamp:
- Jul 3, 2017 1:17:40 PM (7 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r219082 r219089 1 2017-06-30 Alex Christensen <achristensen@webkit.org> 2 3 Stop using dispatch_async in ResourceHandleCFURLConnectionDelegateWithOperationQueue 4 https://bugs.webkit.org/show_bug.cgi?id=174059 5 6 Reviewed by Andy Estes. 7 8 Use dispatch_async_f and callOnMainThread instead. 9 No change in behavior. 10 This will allow me to use this code on Windows. 11 12 * platform/network/cf/ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp: 13 (WebCore::ResourceHandleCFURLConnectionDelegateWithOperationQueue::willSendRequest): 14 (WebCore::ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveResponse): 15 (WebCore::ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveData): 16 (WebCore::ResourceHandleCFURLConnectionDelegateWithOperationQueue::didFinishLoading): 17 (WebCore::ResourceHandleCFURLConnectionDelegateWithOperationQueue::didFail): 18 (WebCore::ResourceHandleCFURLConnectionDelegateWithOperationQueue::willCacheResponse): 19 (WebCore::ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveChallenge): 20 (WebCore::ResourceHandleCFURLConnectionDelegateWithOperationQueue::didSendBodyData): 21 (WebCore::ResourceHandleCFURLConnectionDelegateWithOperationQueue::canRespondToProtectionSpace): 22 1 23 2017-07-03 Andy Estes <aestes@apple.com> 2 24 -
trunk/Source/WebCore/platform/network/cf/ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp
r215686 r219089 102 102 103 103 ASSERT(!isMainThread()); 104 105 // FIXME: The block implicitly copies protector object, which is wasteful. We should just call ref(), 106 // capture "this" by pointer value, and use a C++ lambda to prevent other unintentional capturing. 107 RefPtr<ResourceHandleCFURLConnectionDelegateWithOperationQueue> protectedThis(this); 108 109 dispatch_async(dispatch_get_main_queue(), ^{ 104 105 struct ProtectedParameters { 106 Ref<ResourceHandleCFURLConnectionDelegateWithOperationQueue> protectedThis; 107 RetainPtr<CFURLRequestRef> cfRequest; 108 RetainPtr<CFURLResponseRef> originalRedirectResponse; 109 }; 110 111 auto work = [] (void* context) { 112 auto& parameters = *reinterpret_cast<ProtectedParameters*>(context); 113 auto& protectedThis = parameters.protectedThis; 114 auto& handle = protectedThis->m_handle; 115 auto& cfRequest = parameters.cfRequest; 116 110 117 if (!protectedThis->hasHandle()) { 111 continueWillSendRequest(nullptr);112 return; 113 } 114 115 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::willSendRequest(handle=%p) (%s)", m_handle, m_handle->firstRequest().url().string().utf8().data());116 117 RetainPtr<CFURLResponseRef> redirectResponse = synthesizeRedirectResponseIfNecessary(cfRequest, originalRedirectResponse);118 protectedThis->continueWillSendRequest(nullptr); 119 return; 120 } 121 122 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::willSendRequest(handle=%p) (%s)", handle, handle->firstRequest().url().string().utf8().data()); 123 124 RetainPtr<CFURLResponseRef> redirectResponse = protectedThis->synthesizeRedirectResponseIfNecessary(cfRequest.get(), parameters.originalRedirectResponse.get()); 118 125 ASSERT(redirectResponse); 119 126 120 ResourceRequest request = createResourceRequest(cfRequest, redirectResponse.get()); 121 m_handle->willSendRequest(WTFMove(request), redirectResponse.get()); 122 }); 123 127 ResourceRequest request = protectedThis->createResourceRequest(cfRequest.get(), redirectResponse.get()); 128 handle->willSendRequest(WTFMove(request), redirectResponse.get()); 129 }; 130 131 ProtectedParameters parameters { makeRef(*this), cfRequest, originalRedirectResponse }; 132 dispatch_async_f(dispatch_get_main_queue(), ¶meters, work); 124 133 dispatch_semaphore_wait(m_semaphore, DISPATCH_TIME_FOREVER); 125 134 … … 129 138 void ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveResponse(CFURLConnectionRef connection, CFURLResponseRef cfResponse) 130 139 { 131 // FIXME: The block implicitly copies protector object, which is wasteful. We should just call ref(), 132 // capture "this" by pointer value, and use a C++ lambda to prevent other unintentional capturing. 133 RefPtr<ResourceHandleCFURLConnectionDelegateWithOperationQueue> protectedThis(this); 134 135 dispatch_async(dispatch_get_main_queue(), ^{ 136 if (!protectedThis->hasHandle() || !m_handle->client()) { 137 continueDidReceiveResponse(); 138 return; 139 } 140 141 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveResponse(handle=%p) (%s)", m_handle, m_handle->firstRequest().url().string().utf8().data()); 140 struct ProtectedParameters { 141 Ref<ResourceHandleCFURLConnectionDelegateWithOperationQueue> protectedThis; 142 RetainPtr<CFURLConnectionRef> connection; 143 RetainPtr<CFURLResponseRef> cfResponse; 144 }; 145 146 auto work = [] (void* context) { 147 auto& parameters = *reinterpret_cast<ProtectedParameters*>(context); 148 auto& protectedThis = parameters.protectedThis; 149 auto& handle = protectedThis->m_handle; 150 auto& cfResponse = parameters.cfResponse; 151 152 if (!protectedThis->hasHandle() || !handle->client()) { 153 protectedThis->continueDidReceiveResponse(); 154 return; 155 } 156 157 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveResponse(handle=%p) (%s)", handle, handle->firstRequest().url().string().utf8().data()); 142 158 143 159 // Avoid MIME type sniffing if the response comes back as 304 Not Modified. 144 auto msg = CFURLResponseGetHTTPResponse(cfResponse );160 auto msg = CFURLResponseGetHTTPResponse(cfResponse.get()); 145 161 int statusCode = msg ? CFHTTPMessageGetResponseStatusCode(msg) : 0; 146 162 147 163 if (statusCode != 304) { 148 bool isMainResourceLoad = m_handle->firstRequest().requester() == ResourceRequest::Requester::Main;149 adjustMIMETypeIfNecessary(cfResponse , isMainResourceLoad);164 bool isMainResourceLoad = handle->firstRequest().requester() == ResourceRequest::Requester::Main; 165 adjustMIMETypeIfNecessary(cfResponse.get(), isMainResourceLoad); 150 166 } 151 167 152 168 #if !PLATFORM(IOS) 153 if (_CFURLRequestCopyProtocolPropertyForKey( m_handle->firstRequest().cfURLRequest(DoNotUpdateHTTPBody), CFSTR("ForceHTMLMIMEType")))154 CFURLResponseSetMIMEType(cfResponse , CFSTR("text/html"));169 if (_CFURLRequestCopyProtocolPropertyForKey(handle->firstRequest().cfURLRequest(DoNotUpdateHTTPBody), CFSTR("ForceHTMLMIMEType"))) 170 CFURLResponseSetMIMEType(cfResponse.get(), CFSTR("text/html")); 155 171 #endif // !PLATFORM(IOS) 156 172 157 ResourceResponse resourceResponse(cfResponse );173 ResourceResponse resourceResponse(cfResponse.get()); 158 174 #if ENABLE(WEB_TIMING) 159 ResourceHandle::getConnectionTimingData(connection, resourceResponse.deprecatedNetworkLoadMetrics()); 160 #else 161 UNUSED_PARAM(connection); 175 ResourceHandle::getConnectionTimingData(parameters.connection.get(), resourceResponse.deprecatedNetworkLoadMetrics()); 162 176 #endif 163 177 164 m_handle->didReceiveResponse(WTFMove(resourceResponse)); 165 }); 178 handle->didReceiveResponse(WTFMove(resourceResponse)); 179 }; 180 181 ProtectedParameters parameters { makeRef(*this), connection, cfResponse }; 182 dispatch_async_f(dispatch_get_main_queue(), ¶meters, work); 166 183 dispatch_semaphore_wait(m_semaphore, DISPATCH_TIME_FOREVER); 167 184 } … … 169 186 void ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveData(CFDataRef data, CFIndex originalLength) 170 187 { 171 // FIXME: The block implicitly copies protector object, which is wasteful. We should just call ref(), 172 // capture "this" by pointer value, and use a C++ lambda to prevent other unintentional capturing. 173 RefPtr<ResourceHandleCFURLConnectionDelegateWithOperationQueue> protectedThis(this); 174 CFRetain(data); 175 176 dispatch_async(dispatch_get_main_queue(), ^{ 177 if (protectedThis->hasHandle() && m_handle->client()) { 178 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveData(handle=%p) (%s)", m_handle, m_handle->firstRequest().url().string().utf8().data()); 179 180 m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::create(data), originalLength); 181 } 182 183 CFRelease(data); 188 callOnMainThread([protectedThis = makeRef(*this), data = RetainPtr<CFDataRef>(data), originalLength = originalLength] () mutable { 189 auto& handle = protectedThis->m_handle; 190 if (!protectedThis->hasHandle() || !handle->client()) 191 return; 192 193 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveData(handle=%p) (%s)", handle, handle->firstRequest().url().string().utf8().data()); 194 195 handle->client()->didReceiveBuffer(handle, SharedBuffer::create(data.get()), originalLength); 184 196 }); 185 197 } … … 187 199 void ResourceHandleCFURLConnectionDelegateWithOperationQueue::didFinishLoading() 188 200 { 189 // FIXME: The block implicitly copies protector object, which is wasteful. We should just call ref(), 190 // capture "this" by pointer value, and use a C++ lambda to prevent other unintentional capturing. 191 RefPtr<ResourceHandleCFURLConnectionDelegateWithOperationQueue> protectedThis(this); 192 dispatch_async(dispatch_get_main_queue(), ^{ 193 if (!protectedThis->hasHandle() || !m_handle->client()) 194 return; 195 196 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::didFinishLoading(handle=%p) (%s)", m_handle, m_handle->firstRequest().url().string().utf8().data()); 197 198 m_handle->client()->didFinishLoading(m_handle); 201 callOnMainThread([protectedThis = makeRef(*this)] () mutable { 202 auto& handle = protectedThis->m_handle; 203 if (!protectedThis->hasHandle() || !handle->client()) 204 return; 205 206 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::didFinishLoading(handle=%p) (%s)", handle, handle->firstRequest().url().string().utf8().data()); 207 208 handle->client()->didFinishLoading(handle); 199 209 }); 200 210 } … … 202 212 void ResourceHandleCFURLConnectionDelegateWithOperationQueue::didFail(CFErrorRef error) 203 213 { 204 // FIXME: The block implicitly copies protector object, which is wasteful. We should just call ref(), 205 // capture "this" by pointer value, and use a C++ lambda to prevent other unintentional capturing. 206 RefPtr<ResourceHandleCFURLConnectionDelegateWithOperationQueue> protectedThis(this); 207 CFRetain(error); 208 dispatch_async(dispatch_get_main_queue(), ^{ 209 if (protectedThis->hasHandle() && m_handle->client()) { 210 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::didFail(handle=%p) (%s)", m_handle, m_handle->firstRequest().url().string().utf8().data()); 211 212 m_handle->client()->didFail(m_handle, ResourceError(error)); 213 } 214 215 CFRelease(error); 214 callOnMainThread([protectedThis = makeRef(*this), error = RetainPtr<CFErrorRef>(error)] () mutable { 215 auto& handle = protectedThis->m_handle; 216 if (!protectedThis->hasHandle() || !handle->client()) 217 return; 218 219 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::didFail(handle=%p) (%s)", handle, handle->firstRequest().url().string().utf8().data()); 220 221 handle->client()->didFail(handle, ResourceError(error.get())); 216 222 }); 217 223 } … … 219 225 CFCachedURLResponseRef ResourceHandleCFURLConnectionDelegateWithOperationQueue::willCacheResponse(CFCachedURLResponseRef cachedResponse) 220 226 { 221 // FIXME: The block implicitly copies protector object, which is wasteful. We should just call ref(), 222 // capture "this" by pointer value, and use a C++ lambda to prevent other unintentional capturing. 223 RefPtr<ResourceHandleCFURLConnectionDelegateWithOperationQueue> protectedThis(this); 224 225 dispatch_async(dispatch_get_main_queue(), ^{ 226 if (!protectedThis->hasHandle() || !m_handle->client()) { 227 continueWillCacheResponse(nullptr); 228 return; 229 } 230 231 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::willCacheResponse(handle=%p) (%s)", m_handle, m_handle->firstRequest().url().string().utf8().data()); 232 233 m_handle->client()->willCacheResponseAsync(m_handle, cachedResponse); 234 }); 227 struct ProtectedParameters { 228 Ref<ResourceHandleCFURLConnectionDelegateWithOperationQueue> protectedThis; 229 RetainPtr<CFCachedURLResponseRef> cachedResponse; 230 }; 231 232 auto work = [] (void* context) { 233 auto& parameters = *reinterpret_cast<ProtectedParameters*>(context); 234 auto& protectedThis = parameters.protectedThis; 235 auto& handle = protectedThis->m_handle; 236 237 if (!protectedThis->hasHandle() || !handle->client()) { 238 protectedThis->continueWillCacheResponse(nullptr); 239 return; 240 } 241 242 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::willCacheResponse(handle=%p) (%s)", handle, handle->firstRequest().url().string().utf8().data()); 243 244 handle->client()->willCacheResponseAsync(handle, parameters.cachedResponse.get()); 245 }; 246 247 ProtectedParameters parameters { makeRef(*this), cachedResponse }; 248 dispatch_async_f(dispatch_get_main_queue(), ¶meters, work); 235 249 dispatch_semaphore_wait(m_semaphore, DISPATCH_TIME_FOREVER); 236 250 return m_cachedResponseResult.leakRef(); … … 239 253 void ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveChallenge(CFURLAuthChallengeRef challenge) 240 254 { 241 // FIXME: The block implicitly copies protector object, which is wasteful. We should just call ref(), 242 // capture "this" by pointer value, and use a C++ lambda to prevent other unintentional capturing. 243 RefPtr<ResourceHandleCFURLConnectionDelegateWithOperationQueue> protectedThis(this); 244 CFRetain(challenge); 245 dispatch_async(dispatch_get_main_queue(), ^{ 246 if (protectedThis->hasHandle()) { 247 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveChallenge(handle=%p) (%s)", m_handle, m_handle->firstRequest().url().string().utf8().data()); 248 249 m_handle->didReceiveAuthenticationChallenge(AuthenticationChallenge(challenge, m_handle)); 250 } 251 252 CFRelease(challenge); 255 callOnMainThread([protectedThis = makeRef(*this), challenge = RetainPtr<CFURLAuthChallengeRef>(challenge)] () mutable { 256 auto& handle = protectedThis->m_handle; 257 if (!protectedThis->hasHandle()) 258 return; 259 260 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveChallenge(handle=%p) (%s)", handle, handle->firstRequest().url().string().utf8().data()); 261 262 handle->didReceiveAuthenticationChallenge(AuthenticationChallenge(challenge.get(), handle)); 253 263 }); 254 264 } … … 256 266 void ResourceHandleCFURLConnectionDelegateWithOperationQueue::didSendBodyData(CFIndex totalBytesWritten, CFIndex totalBytesExpectedToWrite) 257 267 { 258 // FIXME: The block implicitly copies protector object, which is wasteful. We should just call ref(), 259 // capture "this" by pointer value, and use a C++ lambda to prevent other unintentional capturing. 260 RefPtr<ResourceHandleCFURLConnectionDelegateWithOperationQueue> protectedThis(this); 261 dispatch_async(dispatch_get_main_queue(), ^{ 262 if (!protectedThis->hasHandle() || !m_handle->client()) 263 return; 264 265 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::didSendBodyData(handle=%p) (%s)", m_handle, m_handle->firstRequest().url().string().utf8().data()); 266 267 m_handle->client()->didSendData(m_handle, totalBytesWritten, totalBytesExpectedToWrite); 268 callOnMainThread([protectedThis = makeRef(*this), totalBytesWritten, totalBytesExpectedToWrite] () mutable { 269 auto& handle = protectedThis->m_handle; 270 if (!protectedThis->hasHandle() || !handle->client()) 271 return; 272 273 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::didSendBodyData(handle=%p) (%s)", handle, handle->firstRequest().url().string().utf8().data()); 274 275 handle->client()->didSendData(handle, totalBytesWritten, totalBytesExpectedToWrite); 268 276 }); 269 277 } … … 277 285 Boolean ResourceHandleCFURLConnectionDelegateWithOperationQueue::canRespondToProtectionSpace(CFURLProtectionSpaceRef protectionSpace) 278 286 { 279 // FIXME: The block implicitly copies protector object, which is wasteful. We should just call ref(), 280 // capture "this" by pointer value, and use a C++ lambda to prevent other unintentional capturing. 281 RefPtr<ResourceHandleCFURLConnectionDelegateWithOperationQueue> protectedThis(this); 282 283 dispatch_async(dispatch_get_main_queue(), ^{ 287 struct ProtectedParameters { 288 Ref<ResourceHandleCFURLConnectionDelegateWithOperationQueue> protectedThis; 289 RetainPtr<CFURLProtectionSpaceRef> protectionSpace; 290 }; 291 292 auto work = [] (void* context) { 293 auto& parameters = *reinterpret_cast<ProtectedParameters*>(context); 294 auto& protectedThis = parameters.protectedThis; 295 auto& handle = protectedThis->m_handle; 296 284 297 if (!protectedThis->hasHandle()) { 285 continueCanAuthenticateAgainstProtectionSpace(false);286 return; 287 } 288 289 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::canRespondToProtectionSpace(handle=%p) (%s)", m_handle, m_handle->firstRequest().url().string().utf8().data());290 291 ProtectionSpace coreProtectionSpace = ProtectionSpace(p rotectionSpace);298 protectedThis->continueCanAuthenticateAgainstProtectionSpace(false); 299 return; 300 } 301 302 LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::canRespondToProtectionSpace(handle=%p) (%s)", handle, handle->firstRequest().url().string().utf8().data()); 303 304 ProtectionSpace coreProtectionSpace = ProtectionSpace(parameters.protectionSpace.get()); 292 305 #if PLATFORM(IOS) 293 306 if (coreProtectionSpace.authenticationScheme() == ProtectionSpaceAuthenticationSchemeUnknown) { … … 297 310 } 298 311 #endif // PLATFORM(IOS) 299 m_handle->canAuthenticateAgainstProtectionSpace(coreProtectionSpace); 300 }); 312 handle->canAuthenticateAgainstProtectionSpace(coreProtectionSpace); 313 }; 314 315 ProtectedParameters parameters { makeRef(*this), protectionSpace }; 316 dispatch_async_f(dispatch_get_main_queue(), ¶meters, work); 301 317 dispatch_semaphore_wait(m_semaphore, DISPATCH_TIME_FOREVER); 302 318 return m_boolResult;
Note: See TracChangeset
for help on using the changeset viewer.