Changeset 244684 in webkit
- Timestamp:
- Apr 26, 2019 2:52:49 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r244682 r244684 1 2019-04-26 Takashi Komori <Takashi.Komori@sony.com> 2 3 [Curl] Fix Curl Request Scheduler not to release wrong Curl handle when request is cancelled. 4 https://bugs.webkit.org/show_bug.cgi?id=191650 5 6 Reviewed by Fujii Hironori. 7 8 * http/tests/misc/repeat-open-cancel-expected.txt: Added. 9 * http/tests/misc/repeat-open-cancel.html: Added. 10 1 11 2019-04-25 Myles C. Maxfield <mmaxfield@apple.com> 2 12 -
trunk/Source/WebCore/ChangeLog
r244683 r244684 1 2019-04-26 Takashi Komori <Takashi.Komori@sony.com> 2 3 [Curl] Fix Curl Request Scheduler not to release wrong Curl handle when request is cancelled. 4 https://bugs.webkit.org/show_bug.cgi?id=191650 5 6 Reviewed by Fujii Hironori. 7 8 Test: http/tests/misc/repeat-open-cancel.html 9 10 * platform/network/curl/CurlRequest.cpp: 11 (WebCore::CurlRequest::cancel): 12 (WebCore::CurlRequest::isCancelled): 13 (WebCore::CurlRequest::isCompletedOrCancelled): 14 (WebCore::CurlRequest::didCompleteTransfer): 15 (WebCore::CurlRequest::completeDidReceiveResponse): 16 (WebCore::CurlRequest::pausedStatusChanged): 17 * platform/network/curl/CurlRequest.h: 18 (WebCore::CurlRequest::isCompleted const): Deleted. 19 (WebCore::CurlRequest::isCancelled const): Deleted. 20 (WebCore::CurlRequest::isCompletedOrCancelled const): Deleted. 21 * platform/network/curl/CurlRequestScheduler.cpp: 22 (WebCore::CurlRequestScheduler::cancel): 23 (WebCore::CurlRequestScheduler::callOnWorkerThread): 24 (WebCore::CurlRequestScheduler::startThreadIfNeeded): 25 (WebCore::CurlRequestScheduler::stopThreadIfNoMoreJobRunning): 26 (WebCore::CurlRequestScheduler::stopThread): 27 (WebCore::CurlRequestScheduler::executeTasks): 28 (WebCore::CurlRequestScheduler::workerThread): 29 (WebCore::CurlRequestScheduler::startTransfer): 30 (WebCore::CurlRequestScheduler::completeTransfer): 31 (WebCore::CurlRequestScheduler::cancelTransfer): 32 (WebCore::CurlRequestScheduler::finalizeTransfer): 33 * platform/network/curl/CurlRequestScheduler.h: 34 1 35 2019-04-25 Myles C. Maxfield <mmaxfield@apple.com> 2 36 -
trunk/Source/WebCore/platform/network/curl/CurlRequest.cpp
r243654 r244684 127 127 ASSERT(isMainThread()); 128 128 129 if (isCompletedOrCancelled()) 130 return; 131 132 m_cancelled = true; 129 { 130 auto locker = holdLock(m_statusMutex); 131 if (m_cancelled) 132 return; 133 134 m_cancelled = true; 135 } 133 136 134 137 auto& scheduler = CurlContext::singleton().scheduler(); … … 142 145 143 146 invalidateClient(); 147 } 148 149 bool CurlRequest::isCancelled() 150 { 151 auto locker = holdLock(m_statusMutex); 152 return m_cancelled; 153 } 154 155 bool CurlRequest::isCompletedOrCancelled() 156 { 157 auto locker = holdLock(m_statusMutex); 158 return m_completed || m_cancelled; 144 159 } 145 160 … … 416 431 void CurlRequest::didCompleteTransfer(CURLcode result) 417 432 { 418 if ( m_cancelled) {419 m_curlHandle = nullptr;433 if (isCancelled()) { 434 didCancelTransfer(); 420 435 return; 421 436 } … … 456 471 }); 457 472 } 473 474 { 475 auto locker = holdLock(m_statusMutex); 476 m_completed = true; 477 } 458 478 } 459 479 … … 568 588 ASSERT(!m_didReturnFromNotify || m_multipartHandle); 569 589 570 if (isCancelled()) 571 return; 572 573 if (m_actionAfterInvoke != Action::StartTransfer && isCompleted()) 590 if (isCompletedOrCancelled()) 574 591 return; 575 592 … … 636 653 637 654 runOnWorkerThreadIfRequired([this, protectedThis = makeRef(*this)]() { 638 if (isCompletedOrCancelled() )655 if (isCompletedOrCancelled() || !m_curlHandle) 639 656 return; 640 657 -
trunk/Source/WebCore/platform/network/curl/CurlRequest.h
r243654 r244684 84 84 85 85 const ResourceRequest& resourceRequest() const { return m_request; } 86 bool isCompleted() const { return !m_curlHandle; } 87 bool isCancelled() const { return m_cancelled; } 88 bool isCompletedOrCancelled() const { return isCompleted() || isCancelled(); } 86 bool isCancelled(); 87 bool isCompletedOrCancelled(); 89 88 Seconds timeoutInterval() const; 90 89 … … 167 166 168 167 CurlRequestClient* m_client { }; 168 Lock m_statusMutex; 169 169 bool m_cancelled { false }; 170 bool m_completed { false }; 170 171 MessageQueue<Function<void()>>* m_messageQueue { }; 171 172 -
trunk/Source/WebCore/platform/network/curl/CurlRequestScheduler.cpp
r229471 r244684 59 59 ASSERT(isMainThread()); 60 60 61 if (!client || !client->handle())61 if (!client) 62 62 return; 63 63 64 cancelTransfer(client ->handle());64 cancelTransfer(client); 65 65 } 66 66 … … 68 68 { 69 69 { 70 LockHolder locker(m_mutex);70 auto locker = holdLock(m_mutex); 71 71 m_taskQueue.append(WTFMove(task)); 72 72 } … … 79 79 ASSERT(isMainThread()); 80 80 81 LockHolder locker(m_mutex); 82 if (!m_runThread) { 83 if (m_thread) 84 m_thread->waitForCompletion(); 85 81 { 82 auto locker = holdLock(m_mutex); 83 if (m_runThread) 84 return; 85 } 86 87 if (m_thread) 88 m_thread->waitForCompletion(); 89 90 { 91 auto locker = holdLock(m_mutex); 86 92 m_runThread = true; 87 m_thread = Thread::create("curlThread", [this] { 88 workerThread(); 89 m_runThread = false; 90 }); 91 } 93 } 94 95 m_thread = Thread::create("curlThread", [this] { 96 workerThread(); 97 98 auto locker = holdLock(m_mutex); 99 m_runThread = false; 100 }); 92 101 } 93 102 … … 96 105 ASSERT(!isMainThread()); 97 106 98 if (m_activeJobs.size()) 107 auto locker = holdLock(m_mutex); 108 if (m_activeJobs.size() || m_taskQueue.size()) 99 109 return; 100 110 101 LockHolder locker(m_mutex);102 if (m_taskQueue.size())103 return;104 105 111 m_runThread = false; 106 112 } … … 108 114 void CurlRequestScheduler::stopThread() 109 115 { 110 m_runThread = false; 116 { 117 auto locker = holdLock(m_mutex); 118 m_runThread = false; 119 } 111 120 112 121 if (m_thread) { … … 123 132 124 133 { 125 LockHolder locker(m_mutex);134 auto locker = holdLock(m_mutex); 126 135 taskQueue = WTFMove(m_taskQueue); 127 136 } … … 140 149 m_curlMultiHandle->setMaxHostConnections(m_maxHostConnections); 141 150 142 while (m_runThread) { 151 while (true) { 152 { 153 auto locker = holdLock(m_mutex); 154 if (!m_runThread) 155 break; 156 } 157 143 158 executeTasks(); 144 159 … … 178 193 179 194 ASSERT(msg->msg == CURLMSG_DONE); 180 completeTransfer(msg->easy_handle, msg->data.result); 195 if (auto client = m_clientMaps.inlineGet(msg->easy_handle)) 196 completeTransfer(client, msg->data.result); 181 197 } 182 198 … … 193 209 auto task = [this, client]() { 194 210 CURL* handle = client->setupTransfer(); 195 if (!handle) 211 if (!handle) { 212 completeTransfer(client, CURLE_FAILED_INIT); 196 213 return; 197 198 m_activeJobs.add(handle, client); 214 } 215 199 216 m_curlMultiHandle->addHandle(handle); 217 218 ASSERT(!m_clientMaps.contains(handle)); 219 m_clientMaps.set(handle, client); 200 220 }; 201 221 202 LockHolder locker(m_mutex); 222 auto locker = holdLock(m_mutex); 223 m_activeJobs.add(client); 203 224 m_taskQueue.append(WTFMove(task)); 204 225 } 205 226 206 void CurlRequestScheduler::completeTransfer(C URL* handle, CURLcode result)207 { 208 finalizeTransfer( handle, [result](CurlRequestSchedulerClient* client) {227 void CurlRequestScheduler::completeTransfer(CurlRequestSchedulerClient* client, CURLcode result) 228 { 229 finalizeTransfer(client, [client, result]() { 209 230 client->didCompleteTransfer(result); 210 231 }); 211 232 } 212 233 213 void CurlRequestScheduler::cancelTransfer(C URL* handle)214 { 215 finalizeTransfer( handle, [](CurlRequestSchedulerClient* client) {234 void CurlRequestScheduler::cancelTransfer(CurlRequestSchedulerClient* client) 235 { 236 finalizeTransfer(client, [client]() { 216 237 client->didCancelTransfer(); 217 238 }); 218 239 } 219 240 220 void CurlRequestScheduler::finalizeTransfer(CURL* handle, Function<void(CurlRequestSchedulerClient*)> completionHandler) 221 { 222 auto task = [this, handle, completion = WTFMove(completionHandler)]() { 223 if (!m_activeJobs.contains(handle)) 224 return; 225 226 CurlRequestSchedulerClient* client = m_activeJobs.inlineGet(handle); 227 228 m_curlMultiHandle->removeHandle(handle); 229 m_activeJobs.remove(handle); 230 completion(client); 241 void CurlRequestScheduler::finalizeTransfer(CurlRequestSchedulerClient* client, Function<void()> completionHandler) 242 { 243 auto locker = holdLock(m_mutex); 244 245 if (!m_activeJobs.contains(client)) 246 return; 247 248 m_activeJobs.remove(client); 249 250 auto task = [this, client, completionHandler = WTFMove(completionHandler)]() { 251 if (client->handle()) { 252 ASSERT(m_clientMaps.contains(client->handle())); 253 m_clientMaps.remove(client->handle()); 254 m_curlMultiHandle->removeHandle(client->handle()); 255 } 256 257 completionHandler(); 231 258 232 259 callOnMainThread([client]() { … … 235 262 }; 236 263 237 LockHolder locker(m_mutex);238 264 m_taskQueue.append(WTFMove(task)); 239 265 } -
trunk/Source/WebCore/platform/network/curl/CurlRequestScheduler.h
r229471 r244684 60 60 61 61 void startTransfer(CurlRequestSchedulerClient*); 62 void completeTransfer(C URL*, CURLcode);63 void cancelTransfer(C URL*);64 void finalizeTransfer(C URL*, Function<void(CurlRequestSchedulerClient*)>);62 void completeTransfer(CurlRequestSchedulerClient*, CURLcode); 63 void cancelTransfer(CurlRequestSchedulerClient*); 64 void finalizeTransfer(CurlRequestSchedulerClient*, Function<void()>); 65 65 66 mutableLock m_mutex;66 Lock m_mutex; 67 67 RefPtr<Thread> m_thread; 68 68 bool m_runThread { false }; 69 69 70 70 Vector<Function<void()>> m_taskQueue; 71 HashMap<CURL*, CurlRequestSchedulerClient*> m_activeJobs; 71 HashSet<CurlRequestSchedulerClient*> m_activeJobs; 72 HashMap<CURL*, CurlRequestSchedulerClient*> m_clientMaps; 72 73 73 74 std::unique_ptr<CurlMultiHandle> m_curlMultiHandle;
Note: See TracChangeset
for help on using the changeset viewer.