Changeset 224322 in webkit


Ignore:
Timestamp:
Nov 1, 2017 10:55:06 PM (6 years ago)
Author:
commit-queue@webkit.org
Message:

[Curl] Make the order of scheduler job handling sequential
https://bugs.webkit.org/show_bug.cgi?id=179127

Patch by Basuke Suzuki <Basuke Suzuki> on 2017-11-01
Reviewed by Alex Christensen.

  • platform/network/curl/CurlRequestScheduler.cpp:

(WebCore::CurlRequestScheduler::add):
(WebCore::CurlRequestScheduler::cancel):
(WebCore::CurlRequestScheduler::stopThreadIfNoMoreJobRunning):
(WebCore::CurlRequestScheduler::executeTasks):
(WebCore::CurlRequestScheduler::workerThread):
(WebCore::CurlRequestScheduler::startTransfer):
(WebCore::CurlRequestScheduler::completeTransfer):
(WebCore::CurlRequestScheduler::cancelTransfer):
(WebCore::CurlRequestScheduler::finalizeTransfer):
(WebCore::CurlJobList::isEmpty const): Deleted.
(WebCore::CurlJobList::startJobs): Deleted.
(WebCore::CurlJobList::finishJobs): Deleted.
(WebCore::CurlRequestScheduler::updateJobList): Deleted.

  • platform/network/curl/CurlRequestScheduler.h:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r224321 r224322  
     12017-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
    1242017-11-01  Ryosuke Niwa  <rniwa@webkit.org>
    225
  • trunk/Source/WebCore/platform/network/curl/CurlRequestScheduler.cpp

    r224037 r224322  
    3636namespace WebCore {
    3737
    38 /*
    39  * CurlJobList is used only in background so that no need to manage mutex
    40  */
    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 
    8338CurlRequestScheduler& CurlRequestScheduler::singleton()
    8439{
     
    9449        return false;
    9550
    96     client->retain();
    97 
    98     {
    99         LockHolder locker(m_mutex);
    100         m_pendingJobs.add(client);
    101     }
    102 
     51    startTransfer(client);
    10352    startThreadIfNeeded();
    10453
     
    11362        return;
    11463
    115     LockHolder locker(m_mutex);
    116     m_cancelledJobs.add(client->handle(), CURLE_OK);
     64    cancelTransfer(client->handle());
    11765}
    11866
     
    14896    ASSERT(!isMainThread());
    14997
    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;
    154106}
    155107
     
    164116}
    165117
    166 void CurlRequestScheduler::updateJobList(CurlJobList& jobs)
     118void CurlRequestScheduler::executeTasks()
    167119{
    168120    ASSERT(!isMainThread());
    169121
    170     HashSet<CurlRequestSchedulerClient*> pendingJobs;
    171     HashMap<CURL*, CURLcode> cancelledJobs;
    172122    Vector<WTF::Function<void()>> taskQueue;
    173123
    174124    {
    175125        LockHolder locker(m_mutex);
    176 
    177         pendingJobs = WTFMove(m_pendingJobs);
    178         cancelledJobs = WTFMove(m_cancelledJobs);
    179126        taskQueue = WTFMove(m_taskQueue);
    180127    }
     
    182129    for (auto& task : taskQueue)
    183130        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     });
    194131}
    195132
     
    198135    ASSERT(!isMainThread());
    199136
    200     CurlJobList jobs;
     137    m_curlMultiHandle = std::make_unique<CurlMultiHandle>();
    201138
    202139    while (m_runThread) {
    203         updateJobList(jobs);
     140        executeTasks();
    204141
    205142        // Retry 'select' if it was interrupted by a process signal.
     
    217154            timeout.tv_usec = selectTimeoutMS * 1000; // select waits microseconds
    218155
    219             jobs.getFdSet(fdread, fdwrite, fdexcep, maxfd);
     156            m_curlMultiHandle->getFdSet(fdread, fdwrite, fdexcep, maxfd);
    220157
    221158            // When the 3 file descriptors are empty, winsock will return -1
     
    227164
    228165        int activeCount = 0;
    229         while (jobs.perform(activeCount) == CURLM_CALL_MULTI_PERFORM) { }
     166        while (m_curlMultiHandle->perform(activeCount) == CURLM_CALL_MULTI_PERFORM) { }
    230167
    231168        // check the curl messages indicating completed transfers
     
    233170        while (true) {
    234171            int messagesInQueue = 0;
    235             CURLMsg* msg = jobs.readInfo(messagesInQueue);
     172            CURLMsg* msg = m_curlMultiHandle->readInfo(messagesInQueue);
    236173            if (!msg)
    237174                break;
    238175
    239176            ASSERT(msg->msg == CURLMSG_DONE);
    240             m_finishedJobs.add(msg->easy_handle, msg->data.result);
     177            completeTransfer(msg->easy_handle, msg->data.result);
    241178        }
    242179
    243         if (jobs.isEmpty())
    244             stopThreadIfNoMoreJobRunning();
    245     }
     180        stopThreadIfNoMoreJobRunning();
     181    }
     182
     183    m_curlMultiHandle = nullptr;
     184}
     185
     186void 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
     203void CurlRequestScheduler::completeTransfer(CURL* handle, CURLcode result)
     204{
     205    finalizeTransfer(handle, [result](CurlRequestSchedulerClient* client) {
     206        client->didCompleteTransfer(result);
     207    });
     208}
     209
     210void CurlRequestScheduler::cancelTransfer(CURL* handle)
     211{
     212    finalizeTransfer(handle, [](CurlRequestSchedulerClient* client) {
     213        client->didCancelTransfer();
     214    });
     215}
     216
     217void 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));
    246236}
    247237
  • trunk/Source/WebCore/platform/network/curl/CurlRequestScheduler.h

    r224037 r224322  
    3030#include "CurlContext.h"
    3131#include <wtf/HashMap.h>
    32 #include <wtf/HashSet.h>
    3332#include <wtf/Lock.h>
    3433#include <wtf/Noncopyable.h>
     
    3736namespace WebCore {
    3837
    39 class CurlJobList;
    4038class CurlRequestSchedulerClient;
    4139
     
    6058    void stopThread();
    6159
    62     void updateJobList(CurlJobList&);
     60    void executeTasks();
    6361
    6462    void workerThread();
    6563
     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;
    6670    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;
    7271    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;
    7377};
    7478
Note: See TracChangeset for help on using the changeset viewer.