Changeset 224322 in webkit
- Timestamp:
- Nov 1, 2017 10:55:06 PM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r224321 r224322 1 2017-11-01 Basuke Suzuki <Basuke.Suzuki@sony.com> 2 3 [Curl] Make the order of scheduler job handling sequential 4 https://bugs.webkit.org/show_bug.cgi?id=179127 5 6 Reviewed by Alex Christensen. 7 8 * platform/network/curl/CurlRequestScheduler.cpp: 9 (WebCore::CurlRequestScheduler::add): 10 (WebCore::CurlRequestScheduler::cancel): 11 (WebCore::CurlRequestScheduler::stopThreadIfNoMoreJobRunning): 12 (WebCore::CurlRequestScheduler::executeTasks): 13 (WebCore::CurlRequestScheduler::workerThread): 14 (WebCore::CurlRequestScheduler::startTransfer): 15 (WebCore::CurlRequestScheduler::completeTransfer): 16 (WebCore::CurlRequestScheduler::cancelTransfer): 17 (WebCore::CurlRequestScheduler::finalizeTransfer): 18 (WebCore::CurlJobList::isEmpty const): Deleted. 19 (WebCore::CurlJobList::startJobs): Deleted. 20 (WebCore::CurlJobList::finishJobs): Deleted. 21 (WebCore::CurlRequestScheduler::updateJobList): Deleted. 22 * platform/network/curl/CurlRequestScheduler.h: 23 1 24 2017-11-01 Ryosuke Niwa <rniwa@webkit.org> 2 25 -
trunk/Source/WebCore/platform/network/curl/CurlRequestScheduler.cpp
r224037 r224322 36 36 namespace WebCore { 37 37 38 /*39 * CurlJobList is used only in background so that no need to manage mutex40 */41 class CurlJobList : public CurlMultiHandle {42 public:43 bool isEmpty() const { return m_activeJobs.isEmpty(); }44 45 void startJobs(HashSet<CurlRequestSchedulerClient*>&& jobs)46 {47 auto localJobs = WTFMove(jobs);48 for (auto& client : localJobs) {49 CURL* handle = client->setupTransfer();50 if (!handle)51 return;52 53 m_activeJobs.add(handle, client);54 addHandle(handle);55 }56 }57 58 void finishJobs(HashMap<CURL*, CURLcode>&& tickets, WTF::Function<void(CurlRequestSchedulerClient*, CURLcode)> completionHandler)59 {60 auto localTickets = WTFMove(tickets);61 for (auto& ticket : localTickets) {62 if (!m_activeJobs.contains(ticket.key))63 continue;64 65 CURL* handle = ticket.key;66 CURLcode result = ticket.value;67 CurlRequestSchedulerClient* client = m_activeJobs.inlineGet(handle);68 69 removeHandle(handle);70 m_activeJobs.remove(handle);71 completionHandler(client, result);72 73 callOnMainThread([client]() {74 client->release();75 });76 }77 }78 79 private:80 HashMap<CURL*, CurlRequestSchedulerClient*> m_activeJobs;81 };82 83 38 CurlRequestScheduler& CurlRequestScheduler::singleton() 84 39 { … … 94 49 return false; 95 50 96 client->retain(); 97 98 { 99 LockHolder locker(m_mutex); 100 m_pendingJobs.add(client); 101 } 102 51 startTransfer(client); 103 52 startThreadIfNeeded(); 104 53 … … 113 62 return; 114 63 115 LockHolder locker(m_mutex); 116 m_cancelledJobs.add(client->handle(), CURLE_OK); 64 cancelTransfer(client->handle()); 117 65 } 118 66 … … 148 96 ASSERT(!isMainThread()); 149 97 150 LockHolder locker(m_mutex); 151 152 if (m_pendingJobs.isEmpty()) 153 m_runThread = false; 98 if (m_activeJobs.size()) 99 return; 100 101 LockHolder locker(m_mutex); 102 if (m_taskQueue.size()) 103 return; 104 105 m_runThread = false; 154 106 } 155 107 … … 164 116 } 165 117 166 void CurlRequestScheduler:: updateJobList(CurlJobList& jobs)118 void CurlRequestScheduler::executeTasks() 167 119 { 168 120 ASSERT(!isMainThread()); 169 121 170 HashSet<CurlRequestSchedulerClient*> pendingJobs;171 HashMap<CURL*, CURLcode> cancelledJobs;172 122 Vector<WTF::Function<void()>> taskQueue; 173 123 174 124 { 175 125 LockHolder locker(m_mutex); 176 177 pendingJobs = WTFMove(m_pendingJobs);178 cancelledJobs = WTFMove(m_cancelledJobs);179 126 taskQueue = WTFMove(m_taskQueue); 180 127 } … … 182 129 for (auto& task : taskQueue) 183 130 task(); 184 185 jobs.startJobs(WTFMove(pendingJobs));186 187 jobs.finishJobs(WTFMove(cancelledJobs), [](CurlRequestSchedulerClient* client, CURLcode) {188 client->didCancelTransfer();189 });190 191 jobs.finishJobs(WTFMove(m_finishedJobs), [](CurlRequestSchedulerClient* client, CURLcode result) {192 client->didCompleteTransfer(result);193 });194 131 } 195 132 … … 198 135 ASSERT(!isMainThread()); 199 136 200 CurlJobList jobs;137 m_curlMultiHandle = std::make_unique<CurlMultiHandle>(); 201 138 202 139 while (m_runThread) { 203 updateJobList(jobs);140 executeTasks(); 204 141 205 142 // Retry 'select' if it was interrupted by a process signal. … … 217 154 timeout.tv_usec = selectTimeoutMS * 1000; // select waits microseconds 218 155 219 jobs.getFdSet(fdread, fdwrite, fdexcep, maxfd);156 m_curlMultiHandle->getFdSet(fdread, fdwrite, fdexcep, maxfd); 220 157 221 158 // When the 3 file descriptors are empty, winsock will return -1 … … 227 164 228 165 int activeCount = 0; 229 while ( jobs.perform(activeCount) == CURLM_CALL_MULTI_PERFORM) { }166 while (m_curlMultiHandle->perform(activeCount) == CURLM_CALL_MULTI_PERFORM) { } 230 167 231 168 // check the curl messages indicating completed transfers … … 233 170 while (true) { 234 171 int messagesInQueue = 0; 235 CURLMsg* msg = jobs.readInfo(messagesInQueue);172 CURLMsg* msg = m_curlMultiHandle->readInfo(messagesInQueue); 236 173 if (!msg) 237 174 break; 238 175 239 176 ASSERT(msg->msg == CURLMSG_DONE); 240 m_finishedJobs.add(msg->easy_handle, msg->data.result);177 completeTransfer(msg->easy_handle, msg->data.result); 241 178 } 242 179 243 if (jobs.isEmpty()) 244 stopThreadIfNoMoreJobRunning(); 245 } 180 stopThreadIfNoMoreJobRunning(); 181 } 182 183 m_curlMultiHandle = nullptr; 184 } 185 186 void CurlRequestScheduler::startTransfer(CurlRequestSchedulerClient* client) 187 { 188 client->retain(); 189 190 auto task = [this, client]() { 191 CURL* handle = client->setupTransfer(); 192 if (!handle) 193 return; 194 195 m_activeJobs.add(handle, client); 196 m_curlMultiHandle->addHandle(handle); 197 }; 198 199 LockHolder locker(m_mutex); 200 m_taskQueue.append(WTFMove(task)); 201 } 202 203 void CurlRequestScheduler::completeTransfer(CURL* handle, CURLcode result) 204 { 205 finalizeTransfer(handle, [result](CurlRequestSchedulerClient* client) { 206 client->didCompleteTransfer(result); 207 }); 208 } 209 210 void CurlRequestScheduler::cancelTransfer(CURL* handle) 211 { 212 finalizeTransfer(handle, [](CurlRequestSchedulerClient* client) { 213 client->didCancelTransfer(); 214 }); 215 } 216 217 void CurlRequestScheduler::finalizeTransfer(CURL* handle, Function<void(CurlRequestSchedulerClient*)> completionHandler) 218 { 219 auto task = [this, handle, completion = WTFMove(completionHandler)]() { 220 if (!m_activeJobs.contains(handle)) 221 return; 222 223 CurlRequestSchedulerClient* client = m_activeJobs.inlineGet(handle); 224 225 m_curlMultiHandle->removeHandle(handle); 226 m_activeJobs.remove(handle); 227 completion(client); 228 229 callOnMainThread([client]() { 230 client->release(); 231 }); 232 }; 233 234 LockHolder locker(m_mutex); 235 m_taskQueue.append(WTFMove(task)); 246 236 } 247 237 -
trunk/Source/WebCore/platform/network/curl/CurlRequestScheduler.h
r224037 r224322 30 30 #include "CurlContext.h" 31 31 #include <wtf/HashMap.h> 32 #include <wtf/HashSet.h>33 32 #include <wtf/Lock.h> 34 33 #include <wtf/Noncopyable.h> … … 37 36 namespace WebCore { 38 37 39 class CurlJobList;40 38 class CurlRequestSchedulerClient; 41 39 … … 60 58 void stopThread(); 61 59 62 void updateJobList(CurlJobList&);60 void executeTasks(); 63 61 64 62 void workerThread(); 65 63 64 void startTransfer(CurlRequestSchedulerClient*); 65 void completeTransfer(CURL*, CURLcode); 66 void cancelTransfer(CURL*); 67 void finalizeTransfer(CURL*, Function<void(CurlRequestSchedulerClient*)>); 68 69 mutable Lock m_mutex; 66 70 RefPtr<Thread> m_thread; 67 HashSet<CurlRequestSchedulerClient*> m_pendingJobs;68 HashMap<CURL*, CURLcode> m_finishedJobs;69 HashMap<CURL*, CURLcode> m_cancelledJobs;70 Vector<WTF::Function<void()>> m_taskQueue;71 mutable Lock m_mutex;72 71 bool m_runThread { false }; 72 73 Vector<Function<void()>> m_taskQueue; 74 HashMap<CURL*, CurlRequestSchedulerClient*> m_activeJobs; 75 76 std::unique_ptr<CurlMultiHandle> m_curlMultiHandle; 73 77 }; 74 78
Note: See TracChangeset
for help on using the changeset viewer.