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