Title: [229471] trunk/Source/WebCore
Revision
229471
Author
[email protected]
Date
2018-03-09 10:51:27 -0800 (Fri, 09 Mar 2018)

Log Message

[Curl] Implement connection limit.
https://bugs.webkit.org/show_bug.cgi?id=183016

Implement both connection limit per host and total
connection limit on curl network layer.

Patch by Basuke Suzuki <[email protected]> on 2018-03-09
Reviewed by Youenn Fablet.

No new tests because there's no behavior change.

* platform/network/curl/CurlContext.cpp:
(WebCore::EnvironmentVariableReader::sscanTemplate<signed>):
(WebCore::CurlContext::CurlContext):
(WebCore::CurlMultiHandle::setMaxConnects):
(WebCore::CurlMultiHandle::setMaxTotalConnections):
(WebCore::CurlMultiHandle::setMaxHostConnections):
* platform/network/curl/CurlContext.h:
(WebCore::CurlContext::scheduler):
* platform/network/curl/CurlRequest.cpp:
(WebCore::CurlRequest::startWithJobManager):
(WebCore::CurlRequest::cancel):
(WebCore::CurlRequest::invokeDidReceiveResponseForFile):
(WebCore::CurlRequest::completeDidReceiveResponse):
(WebCore::CurlRequest::pausedStatusChanged):
* platform/network/curl/CurlRequestScheduler.cpp:
(WebCore::CurlRequestScheduler::CurlRequestScheduler):
(WebCore::CurlRequestScheduler::workerThread):
(WebCore::CurlRequestScheduler::singleton): Deleted.
* platform/network/curl/CurlRequestScheduler.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (229470 => 229471)


--- trunk/Source/WebCore/ChangeLog	2018-03-09 18:51:26 UTC (rev 229470)
+++ trunk/Source/WebCore/ChangeLog	2018-03-09 18:51:27 UTC (rev 229471)
@@ -1,3 +1,35 @@
+2018-03-09  Basuke Suzuki  <[email protected]>
+
+        [Curl] Implement connection limit.
+        https://bugs.webkit.org/show_bug.cgi?id=183016
+
+        Implement both connection limit per host and total
+        connection limit on curl network layer.
+
+        Reviewed by Youenn Fablet.
+
+        No new tests because there's no behavior change.
+
+        * platform/network/curl/CurlContext.cpp:
+        (WebCore::EnvironmentVariableReader::sscanTemplate<signed>):
+        (WebCore::CurlContext::CurlContext):
+        (WebCore::CurlMultiHandle::setMaxConnects):
+        (WebCore::CurlMultiHandle::setMaxTotalConnections):
+        (WebCore::CurlMultiHandle::setMaxHostConnections):
+        * platform/network/curl/CurlContext.h:
+        (WebCore::CurlContext::scheduler):
+        * platform/network/curl/CurlRequest.cpp:
+        (WebCore::CurlRequest::startWithJobManager):
+        (WebCore::CurlRequest::cancel):
+        (WebCore::CurlRequest::invokeDidReceiveResponseForFile):
+        (WebCore::CurlRequest::completeDidReceiveResponse):
+        (WebCore::CurlRequest::pausedStatusChanged):
+        * platform/network/curl/CurlRequestScheduler.cpp:
+        (WebCore::CurlRequestScheduler::CurlRequestScheduler):
+        (WebCore::CurlRequestScheduler::workerThread):
+        (WebCore::CurlRequestScheduler::singleton): Deleted.
+        * platform/network/curl/CurlRequestScheduler.h:
+
 2018-03-09  Jer Noble  <[email protected]>
 
         webkitfullscreenchange event not fired at the same time as :-webkit-full-screen pseudo selector changes; causes glitchiness

Modified: trunk/Source/WebCore/platform/network/curl/CurlContext.cpp (229470 => 229471)


--- trunk/Source/WebCore/platform/network/curl/CurlContext.cpp	2018-03-09 18:51:26 UTC (rev 229470)
+++ trunk/Source/WebCore/platform/network/curl/CurlContext.cpp	2018-03-09 18:51:27 UTC (rev 229471)
@@ -28,8 +28,10 @@
 #include "CurlContext.h"
 
 #if USE(CURL)
+#include "CurlRequestScheduler.h"
 #include "HTTPHeaderMap.h"
 #include <NetworkLoadMetrics.h>
+#include <mutex>
 #include <wtf/MainThread.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
@@ -66,6 +68,7 @@
     }
 
     // define specialized member function for specific type.
+    template<> constexpr const char* sscanTemplate<signed>() { return "%d"; }
     template<> constexpr const char* sscanTemplate<unsigned>() { return "%u"; }
 };
 
@@ -89,6 +92,21 @@
     if (auto value = envVar.readAs<unsigned>("WEBKIT_CURL_CONNECT_TIMEOUT"))
         m_connectTimeout = Seconds(*value);
 
+    long maxConnects { CurlDefaultMaxConnects };
+    long maxTotalConnections { CurlDefaultMaxTotalConnections };
+    long maxHostConnections { CurlDefaultMaxHostConnections };
+
+    if (auto value = envVar.readAs<signed>("WEBKIT_CURL_MAXCONNECTS"))
+        maxConnects = *value;
+
+    if (auto value = envVar.readAs<signed>("WEBKIT_CURL_MAX_TOTAL_CONNECTIONS"))
+        maxTotalConnections = *value;
+
+    if (auto value = envVar.readAs<signed>("WEBKIT_CURL_MAX_HOST_CONNECTIONS"))
+        maxHostConnections = *value;
+
+    m_scheduler = std::make_unique<CurlRequestScheduler>(maxConnects, maxTotalConnections, maxHostConnections);
+
 #ifndef NDEBUG
     m_verbose = envVar.defined("DEBUG_CURL");
 
@@ -213,6 +231,24 @@
         curl_multi_cleanup(m_multiHandle);
 }
 
+void CurlMultiHandle::setMaxConnects(long maxConnects)
+{
+    if (maxConnects < 0)
+        return;
+
+    curl_multi_setopt(m_multiHandle, CURLMOPT_MAXCONNECTS, maxConnects);
+}
+
+void CurlMultiHandle::setMaxTotalConnections(long maxTotalConnections)
+{
+    curl_multi_setopt(m_multiHandle, CURLMOPT_MAX_TOTAL_CONNECTIONS, maxTotalConnections);
+}
+
+void CurlMultiHandle::setMaxHostConnections(long maxHostConnections)
+{
+    curl_multi_setopt(m_multiHandle, CURLMOPT_MAX_HOST_CONNECTIONS, maxHostConnections);
+}
+
 CURLMcode CurlMultiHandle::addHandle(CURL* handle)
 {
     return curl_multi_add_handle(m_multiHandle, handle);

Modified: trunk/Source/WebCore/platform/network/curl/CurlContext.h (229470 => 229471)


--- trunk/Source/WebCore/platform/network/curl/CurlContext.h	2018-03-09 18:51:26 UTC (rev 229470)
+++ trunk/Source/WebCore/platform/network/curl/CurlContext.h	2018-03-09 18:51:27 UTC (rev 229471)
@@ -53,6 +53,12 @@
     Socks5Hostname = CURLPROXY_SOCKS5_HOSTNAME
 };
 
+// Values taken from http://www.browserscope.org/ following
+// the rule "Do What Every Other Modern Browser Is Doing".
+const long CurlDefaultMaxConnects { -1 }; // -1 : Does not set CURLMOPT_MAXCONNECTS
+const long CurlDefaultMaxTotalConnections { 17 };
+const long CurlDefaultMaxHostConnections { 6 };
+
 // CurlGlobal --------------------------------------------
 // to make the initialization of libcurl happen before other initialization of CurlContext
 
@@ -90,6 +96,8 @@
 
 // CurlContext --------------------------------------------
 
+class CurlRequestScheduler;
+
 class CurlContext : public CurlGlobal {
     WTF_MAKE_NONCOPYABLE(CurlContext);
     friend NeverDestroyed<CurlContext>;
@@ -110,6 +118,8 @@
 
     const CurlShareHandle& shareHandle() { return m_shareHandle; }
 
+    CurlRequestScheduler& scheduler() { return *m_scheduler; }
+
     // Proxy
     const ProxyInfo& proxyInfo() const { return m_proxy; }
     void setProxyInfo(const ProxyInfo& info) { m_proxy = info;  }
@@ -137,6 +147,7 @@
     ProxyInfo m_proxy;
     CurlShareHandle m_shareHandle;
     CurlSSLHandle m_sslHandle;
+    std::unique_ptr<CurlRequestScheduler> m_scheduler;
 
     Seconds m_dnsCacheTimeout { Seconds::fromMinutes(5) };
     Seconds m_connectTimeout { 30.0 };
@@ -156,6 +167,10 @@
     CurlMultiHandle();
     ~CurlMultiHandle();
 
+    void setMaxConnects(long);
+    void setMaxTotalConnections(long);
+    void setMaxHostConnections(long);
+
     CURLMcode addHandle(CURL*);
     CURLMcode removeHandle(CURL*);
 

Modified: trunk/Source/WebCore/platform/network/curl/CurlRequest.cpp (229470 => 229471)


--- trunk/Source/WebCore/platform/network/curl/CurlRequest.cpp	2018-03-09 18:51:26 UTC (rev 229470)
+++ trunk/Source/WebCore/platform/network/curl/CurlRequest.cpp	2018-03-09 18:51:27 UTC (rev 229471)
@@ -96,7 +96,7 @@
 {
     ASSERT(isMainThread());
 
-    CurlRequestScheduler::singleton().add(this);
+    CurlContext::singleton().scheduler().add(this);
 }
 
 void CurlRequest::cancel()
@@ -109,7 +109,7 @@
     m_cancelled = true;
 
     if (!m_isSyncRequest) {
-        auto& scheduler = CurlRequestScheduler::singleton();
+        auto& scheduler = CurlContext::singleton().scheduler();
 
         if (needToInvokeDidCancelTransfer()) {
             scheduler.callOnWorkerThread([protectedThis = makeRef(*this)]() {
@@ -517,7 +517,7 @@
 
     if (!m_isSyncRequest) {
         // DidReceiveResponse must not be called immediately
-        CurlRequestScheduler::singleton().callOnWorkerThread([protectedThis = makeRef(*this)]() {
+        CurlContext::singleton().scheduler().callOnWorkerThread([protectedThis = makeRef(*this)]() {
             protectedThis->invokeDidReceiveResponse(protectedThis->m_response, Action::StartTransfer);
         });
     } else {
@@ -560,7 +560,7 @@
         startWithJobManager();
     } else if (m_actionAfterInvoke == Action::FinishTransfer) {
         if (!m_isSyncRequest) {
-            CurlRequestScheduler::singleton().callOnWorkerThread([protectedThis = makeRef(*this), finishedResultCode = m_finishedResultCode]() {
+            CurlContext::singleton().scheduler().callOnWorkerThread([protectedThis = makeRef(*this), finishedResultCode = m_finishedResultCode]() {
                 protectedThis->didCompleteTransfer(finishedResultCode);
             });
         } else
@@ -602,7 +602,7 @@
         return;
 
     if (!m_isSyncRequest && isMainThread()) {
-        CurlRequestScheduler::singleton().callOnWorkerThread([protectedThis = makeRef(*this), paused = isPaused()]() {
+        CurlContext::singleton().scheduler().callOnWorkerThread([protectedThis = makeRef(*this), paused = isPaused()]() {
             if (protectedThis->isCompletedOrCancelled())
                 return;
 

Modified: trunk/Source/WebCore/platform/network/curl/CurlRequestScheduler.cpp (229470 => 229471)


--- trunk/Source/WebCore/platform/network/curl/CurlRequestScheduler.cpp	2018-03-09 18:51:26 UTC (rev 229470)
+++ trunk/Source/WebCore/platform/network/curl/CurlRequestScheduler.cpp	2018-03-09 18:51:27 UTC (rev 229471)
@@ -31,14 +31,14 @@
 #if USE(CURL)
 
 #include "CurlRequestSchedulerClient.h"
-#include <wtf/NeverDestroyed.h>
 
 namespace WebCore {
 
-CurlRequestScheduler& CurlRequestScheduler::singleton()
+CurlRequestScheduler::CurlRequestScheduler(long maxConnects, long maxTotalConnections, long maxHostConnections)
+    : m_maxConnects(maxConnects)
+    , m_maxTotalConnections(maxTotalConnections)
+    , m_maxHostConnections(maxHostConnections)
 {
-    static NeverDestroyed<CurlRequestScheduler> sharedInstance;
-    return sharedInstance;
 }
 
 bool CurlRequestScheduler::add(CurlRequestSchedulerClient* client)
@@ -135,6 +135,9 @@
     ASSERT(!isMainThread());
 
     m_curlMultiHandle = std::make_unique<CurlMultiHandle>();
+    m_curlMultiHandle->setMaxConnects(m_maxConnects);
+    m_curlMultiHandle->setMaxTotalConnections(m_maxTotalConnections);
+    m_curlMultiHandle->setMaxHostConnections(m_maxHostConnections);
 
     while (m_runThread) {
         executeTasks();

Modified: trunk/Source/WebCore/platform/network/curl/CurlRequestScheduler.h (229470 => 229471)


--- trunk/Source/WebCore/platform/network/curl/CurlRequestScheduler.h	2018-03-09 18:51:26 UTC (rev 229470)
+++ trunk/Source/WebCore/platform/network/curl/CurlRequestScheduler.h	2018-03-09 18:51:27 UTC (rev 229471)
@@ -41,8 +41,7 @@
     WTF_MAKE_NONCOPYABLE(CurlRequestScheduler);
     friend NeverDestroyed<CurlRequestScheduler>;
 public:
-    static CurlRequestScheduler& singleton();
-
+    CurlRequestScheduler(long maxConnects, long maxTotalConnections, long maxHostConnections);
     ~CurlRequestScheduler() { stopThread(); }
 
     bool add(CurlRequestSchedulerClient*);
@@ -51,8 +50,6 @@
     void callOnWorkerThread(WTF::Function<void()>&&);
 
 private:
-    CurlRequestScheduler() = default;
-
     void startThreadIfNeeded();
     void stopThreadIfNoMoreJobRunning();
     void stopThread();
@@ -74,6 +71,10 @@
     HashMap<CURL*, CurlRequestSchedulerClient*> m_activeJobs;
 
     std::unique_ptr<CurlMultiHandle> m_curlMultiHandle;
+
+    long m_maxConnects;
+    long m_maxTotalConnections;
+    long m_maxHostConnections;
 };
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to