WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-173557-20170621094831.patch (text/plain), 34.68 KB, created by
Alex Christensen
on 2017-06-21 09:48:30 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Alex Christensen
Created:
2017-06-21 09:48:30 PDT
Size:
34.68 KB
patch
obsolete
>Index: Source/WebCore/ChangeLog >=================================================================== >--- Source/WebCore/ChangeLog (revision 218635) >+++ Source/WebCore/ChangeLog (working copy) >@@ -1,3 +1,80 @@ >+2017-06-21 Basuke Suzuki <Basuke.Suzuki@sony.com> >+ >+ [Curl] Extract CurlDownloadManager as shared background task handler >+ https://bugs.webkit.org/show_bug.cgi?id=173557 >+ >+ Curl resource handling should be shared by other part of Curl >+ network stack. CurlDownloadManager is extracted as stand alone >+ CurlManager singleton class to be ready for others >+ (i.e. ResourceHandle). >+ >+ Reviewed by Alex Christensen. >+ >+ * PlatformWinCairo.cmake: >+ * platform/network/curl/CookieJarCurl.cpp: >+ (WebCore::setCookiesFromDOM): >+ (WebCore::cookiesForSession): >+ * platform/network/curl/CurlDownload.cpp: >+ (WebCore::CurlDownload::init): >+ (WebCore::CurlDownload::start): >+ (WebCore::CurlDownload::cancel): >+ (WebCore::CurlDownload::didReceiveHeader): >+ (WebCore::CurlDownload::handleCurlMsg): >+ (WebCore::CurlDownloadManager::CurlDownloadManager): Deleted. >+ (WebCore::CurlDownloadManager::~CurlDownloadManager): Deleted. >+ (WebCore::CurlDownloadManager::add): Deleted. >+ (WebCore::CurlDownloadManager::remove): Deleted. >+ (WebCore::CurlDownloadManager::getActiveDownloadCount): Deleted. >+ (WebCore::CurlDownloadManager::getPendingDownloadCount): Deleted. >+ (WebCore::CurlDownloadManager::startThreadIfNeeded): Deleted. >+ (WebCore::CurlDownloadManager::stopThread): Deleted. >+ (WebCore::CurlDownloadManager::stopThreadIfIdle): Deleted. >+ (WebCore::CurlDownloadManager::updateHandleList): Deleted. >+ (WebCore::CurlDownloadManager::addToCurl): Deleted. >+ (WebCore::CurlDownloadManager::removeFromCurl): Deleted. >+ (WebCore::CurlDownloadManager::downloadThread): Deleted. >+ * platform/network/curl/CurlDownload.h: >+ (WebCore::CurlDownloadManager::getMultiHandle): Deleted. >+ (WebCore::CurlDownloadManager::runThread): Deleted. >+ (WebCore::CurlDownloadManager::setRunThread): Deleted. >+ * platform/network/curl/CurlManager.cpp: Added. >+ (WebCore::CurlManager::CurlManager): >+ (WebCore::CurlManager::~CurlManager): >+ (WebCore::CurlManager::add): >+ (WebCore::CurlManager::remove): >+ (WebCore::CurlManager::getActiveCount): >+ (WebCore::CurlManager::getPendingCount): >+ (WebCore::CurlManager::startThreadIfNeeded): >+ (WebCore::CurlManager::stopThread): >+ (WebCore::CurlManager::stopThreadIfIdle): >+ (WebCore::CurlManager::updateHandleList): >+ (WebCore::CurlManager::addToCurl): >+ (WebCore::CurlManager::removeFromCurl): >+ (WebCore::CurlManager::workerThread): >+ (WebCore::CurlUtils::getEffectiveURL): >+ (WebCore::CurlSharedResources::mutexFor): >+ (WebCore::CurlSharedResources::lock): >+ (WebCore::CurlSharedResources::unlock): >+ * platform/network/curl/CurlManager.h: Added. >+ (WebCore::CurlManager::singleton): >+ (WebCore::CurlManager::getCurlShareHandle): >+ (WebCore::CurlManager::getMultiHandle): >+ (WebCore::CurlManager::runThread): >+ (WebCore::CurlManager::setRunThread): >+ * platform/network/curl/ResourceHandleManager.cpp: >+ (WebCore::ResourceHandleManager::ResourceHandleManager): >+ (WebCore::ResourceHandleManager::~ResourceHandleManager): >+ (WebCore::handleLocalReceiveResponse): >+ (WebCore::getProtectionSpace): >+ (WebCore::headerCallback): >+ (WebCore::ResourceHandleManager::downloadTimerCallback): >+ (WebCore::getCurlEffectiveURL): Deleted. >+ (WebCore::sharedResourceMutex): Deleted. >+ (WebCore::curl_lock_callback): Deleted. >+ (WebCore::curl_unlock_callback): Deleted. >+ (WebCore::ResourceHandleManager::getCurlShareHandle): Deleted. >+ * platform/network/curl/ResourceHandleManager.h: >+ > 2017-06-21 Jeremy Jones <jeremyj@apple.com> > > Include audio/vnd.wave as a valid mime-type for wav files. >Index: Source/WebCore/PlatformWinCairo.cmake >=================================================================== >--- Source/WebCore/PlatformWinCairo.cmake (revision 218635) >+++ Source/WebCore/PlatformWinCairo.cmake (working copy) >@@ -34,6 +34,7 @@ list(APPEND WebCore_SOURCES > platform/network/curl/CurlCacheEntry.cpp > platform/network/curl/CurlCacheManager.cpp > platform/network/curl/CurlDownload.cpp >+ platform/network/curl/CurlManager.cpp > platform/network/curl/DNSCurl.cpp > platform/network/curl/FormDataStreamCurl.cpp > platform/network/curl/MultipartHandle.cpp >Index: Source/WebCore/platform/network/curl/CookieJarCurl.cpp >=================================================================== >--- Source/WebCore/platform/network/curl/CookieJarCurl.cpp (revision 218635) >+++ Source/WebCore/platform/network/curl/CookieJarCurl.cpp (working copy) >@@ -1,4 +1,6 @@ > /* >+ * Copyright (C) 2011 Apple Inc. All rights reserved. >+ * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Lesser General Public > * License as published by the Free Software Foundation; either >@@ -20,9 +22,10 @@ > #if USE(CURL) > > #include "Cookie.h" >+#include "CurlManager.h" > #include "NotImplemented.h" >-#include "URL.h" > #include "ResourceHandleManager.h" >+#include "URL.h" > > #include <wtf/DateMath.h> > #include <wtf/HashMap.h> >@@ -246,7 +249,7 @@ void setCookiesFromDOM(const NetworkStor > return; > > const char* cookieJarFileName = ResourceHandleManager::sharedInstance()->getCookieJarFileName(); >- CURLSH* curlsh = ResourceHandleManager::sharedInstance()->getCurlShareHandle(); >+ CURLSH* curlsh = CurlManager::singleton().getCurlShareHandle(); > > curl_easy_setopt(curl, CURLOPT_COOKIEJAR, cookieJarFileName); > curl_easy_setopt(curl, CURLOPT_SHARE, curlsh); >@@ -275,7 +278,7 @@ static String cookiesForSession(const Ne > if (!curl) > return cookies; > >- CURLSH* curlsh = ResourceHandleManager::sharedInstance()->getCurlShareHandle(); >+ CURLSH* curlsh = CurlManager::singleton().getCurlShareHandle(); > > curl_easy_setopt(curl, CURLOPT_SHARE, curlsh); > >Index: Source/WebCore/platform/network/curl/CurlDownload.cpp >=================================================================== >--- Source/WebCore/platform/network/curl/CurlDownload.cpp (revision 218635) >+++ Source/WebCore/platform/network/curl/CurlDownload.cpp (working copy) >@@ -31,7 +31,6 @@ > > #include "HTTPHeaderNames.h" > #include "HTTPParsers.h" >-#include "ResourceHandleManager.h" > #include "ResourceRequest.h" > #include <wtf/MainThread.h> > #include <wtf/text/CString.h> >@@ -40,197 +39,8 @@ using namespace WebCore; > > namespace WebCore { > >-// CurlDownloadManager ------------------------------------------------------------------- >- >-CurlDownloadManager::CurlDownloadManager() >-{ >- curl_global_init(CURL_GLOBAL_ALL); >- m_curlMultiHandle = curl_multi_init(); >-} >- >-CurlDownloadManager::~CurlDownloadManager() >-{ >- stopThread(); >- curl_multi_cleanup(m_curlMultiHandle); >- curl_global_cleanup(); >-} >- >-bool CurlDownloadManager::add(CURL* curlHandle) >-{ >- { >- LockHolder locker(m_mutex); >- m_pendingHandleList.append(curlHandle); >- } >- >- startThreadIfNeeded(); >- >- return true; >-} >- >-bool CurlDownloadManager::remove(CURL* curlHandle) >-{ >- LockHolder locker(m_mutex); >- >- m_removedHandleList.append(curlHandle); >- >- return true; >-} >- >-int CurlDownloadManager::getActiveDownloadCount() const >-{ >- LockHolder locker(m_mutex); >- return m_activeHandleList.size(); >-} >- >-int CurlDownloadManager::getPendingDownloadCount() const >-{ >- LockHolder locker(m_mutex); >- return m_pendingHandleList.size(); >-} >- >-void CurlDownloadManager::startThreadIfNeeded() >-{ >- if (!runThread()) { >- if (m_thread) >- m_thread->waitForCompletion(); >- setRunThread(true); >- m_thread = Thread::create(downloadThread, this, "downloadThread"); >- } >-} >- >-void CurlDownloadManager::stopThread() >-{ >- setRunThread(false); >- >- if (m_thread) { >- m_thread->waitForCompletion(); >- m_thread = nullptr; >- } >-} >- >-void CurlDownloadManager::stopThreadIfIdle() >-{ >- if (!getActiveDownloadCount() && !getPendingDownloadCount()) >- setRunThread(false); >-} >- >-void CurlDownloadManager::updateHandleList() >-{ >- LockHolder locker(m_mutex); >- >- // Remove curl easy handles from multi list >- int size = m_removedHandleList.size(); >- for (int i = 0; i < size; i++) { >- removeFromCurl(m_removedHandleList[0]); >- m_removedHandleList.remove(0); >- } >- >- // Add pending curl easy handles to multi list >- size = m_pendingHandleList.size(); >- for (int i = 0; i < size; i++) { >- addToCurl(m_pendingHandleList[0]); >- m_pendingHandleList.remove(0); >- } >-} >- >-bool CurlDownloadManager::addToCurl(CURL* curlHandle) >-{ >- CURLMcode retval = curl_multi_add_handle(m_curlMultiHandle, curlHandle); >- if (retval == CURLM_OK) { >- m_activeHandleList.append(curlHandle); >- return true; >- } >- return false; >-} >- >-bool CurlDownloadManager::removeFromCurl(CURL* curlHandle) >-{ >- int handlePos = m_activeHandleList.find(curlHandle); >- >- if (handlePos < 0) >- return true; >- >- CURLMcode retval = curl_multi_remove_handle(m_curlMultiHandle, curlHandle); >- if (retval == CURLM_OK) { >- m_activeHandleList.remove(handlePos); >- curl_easy_cleanup(curlHandle); >- return true; >- } >- return false; >-} >- >-void CurlDownloadManager::downloadThread(void* data) >-{ >- CurlDownloadManager* downloadManager = reinterpret_cast<CurlDownloadManager*>(data); >- >- while (downloadManager->runThread()) { >- >- downloadManager->updateHandleList(); >- >- // Retry 'select' if it was interrupted by a process signal. >- int rc = 0; >- do { >- fd_set fdread; >- fd_set fdwrite; >- fd_set fdexcep; >- >- int maxfd = 0; >- >- const int selectTimeoutMS = 5; >- >- struct timeval timeout; >- timeout.tv_sec = 0; >- timeout.tv_usec = selectTimeoutMS * 1000; // select waits microseconds >- >- FD_ZERO(&fdread); >- FD_ZERO(&fdwrite); >- FD_ZERO(&fdexcep); >- curl_multi_fdset(downloadManager->getMultiHandle(), &fdread, &fdwrite, &fdexcep, &maxfd); >- // When the 3 file descriptors are empty, winsock will return -1 >- // and bail out, stopping the file download. So make sure we >- // have valid file descriptors before calling select. >- if (maxfd >= 0) >- rc = ::select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); >- } while (rc == -1 && errno == EINTR); >- >- int activeDownloadCount = 0; >- while (curl_multi_perform(downloadManager->getMultiHandle(), &activeDownloadCount) == CURLM_CALL_MULTI_PERFORM) { } >- >- int messagesInQueue = 0; >- CURLMsg* msg = curl_multi_info_read(downloadManager->getMultiHandle(), &messagesInQueue); >- >- if (!msg) >- continue; >- >- CurlDownload* download = 0; >- CURLcode err = curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &download); >- UNUSED_PARAM(err); >- >- if (msg->msg == CURLMSG_DONE) { >- if (download) { >- if (msg->data.result == CURLE_OK) { >- callOnMainThread([download] { >- download->didFinish(); >- download->deref(); // This matches the ref() in CurlDownload::start(). >- }); >- } else { >- callOnMainThread([download] { >- download->didFail(); >- download->deref(); // This matches the ref() in CurlDownload::start(). >- }); >- } >- } >- downloadManager->removeFromCurl(msg->easy_handle); >- } >- >- downloadManager->stopThreadIfIdle(); >- } >-} >- > // CurlDownload -------------------------------------------------------------------------- > >-CurlDownloadManager CurlDownload::m_downloadManager; >- > CurlDownload::CurlDownload() = default; > > CurlDownload::~CurlDownload() >@@ -275,7 +85,7 @@ void CurlDownload::init(CurlDownloadList > if (certPath) > curl_easy_setopt(m_curlHandle, CURLOPT_CAINFO, certPath); > >- CURLSH* curlsh = ResourceHandleManager::sharedInstance()->getCurlShareHandle(); >+ CURLSH* curlsh = CurlManager::singleton().getCurlShareHandle(); > if (curlsh) > curl_easy_setopt(m_curlHandle, CURLOPT_SHARE, curlsh); > >@@ -297,12 +107,12 @@ void CurlDownload::init(CurlDownloadList > bool CurlDownload::start() > { > ref(); // CurlDownloadManager::downloadThread will call deref when the download has finished. >- return m_downloadManager.add(m_curlHandle); >+ return CurlManager::singleton().add(m_curlHandle); > } > > bool CurlDownload::cancel() > { >- return m_downloadManager.remove(m_curlHandle); >+ return CurlManager::singleton().remove(m_curlHandle); > } > > String CurlDownload::getTempPath() const >@@ -393,7 +203,7 @@ void CurlDownload::didReceiveHeader(cons > UNUSED_PARAM(err); > > if (httpCode >= 200 && httpCode < 300) { >- URL url = getCurlEffectiveURL(m_curlHandle); >+ URL url = CurlUtils::getEffectiveURL(m_curlHandle); > callOnMainThread([this, url = url.isolatedCopy(), protectedThis = makeRef(*this)] { > m_response.setURL(url); > m_response.setMimeType(extractMIMETypeFromMediaType(m_response.httpHeaderField(HTTPHeaderName::ContentType))); >@@ -506,6 +316,29 @@ void CurlDownload::receivedResponseCallb > download->didReceiveResponse(); > } > >+CurlJobAction CurlDownload::handleCurlMsg(CURLMsg* msg) >+{ >+ switch (msg->msg) { >+ case CURLMSG_DONE: { >+ if (msg->data.result == CURLE_OK) { >+ callOnMainThread([this] { >+ didFinish(); >+ deref(); // This matches the ref() in CurlDownload::start(). >+ }); >+ } else { >+ callOnMainThread([this] { >+ didFail(); >+ deref(); // This matches the ref() in CurlDownload::start(). >+ }); >+ } >+ return CurlJobAction::Finished; >+ } >+ default: { >+ return CurlJobAction::None; >+ } >+ } >+} >+ > } > > #endif >Index: Source/WebCore/platform/network/curl/CurlDownload.h >=================================================================== >--- Source/WebCore/platform/network/curl/CurlDownload.h (revision 218635) >+++ Source/WebCore/platform/network/curl/CurlDownload.h (working copy) >@@ -36,47 +36,10 @@ > #include <winsock2.h> > #endif > >-#include <curl/curl.h> >+#include "CurlManager.h" > > namespace WebCore { > >-class CurlDownloadManager { >-public: >- CurlDownloadManager(); >- ~CurlDownloadManager(); >- >- bool add(CURL* curlHandle); >- bool remove(CURL* curlHandle); >- >- int getActiveDownloadCount() const; >- int getPendingDownloadCount() const; >- >-private: >- void startThreadIfNeeded(); >- void stopThread(); >- void stopThreadIfIdle(); >- >- void updateHandleList(); >- >- CURLM* getMultiHandle() const { return m_curlMultiHandle; } >- >- bool runThread() const { LockHolder locker(m_mutex); return m_runThread; } >- void setRunThread(bool runThread) { LockHolder locker(m_mutex); m_runThread = runThread; } >- >- bool addToCurl(CURL* curlHandle); >- bool removeFromCurl(CURL* curlHandle); >- >- static void downloadThread(void* data); >- >- RefPtr<Thread> m_thread; >- CURLM* m_curlMultiHandle { nullptr }; >- Vector<CURL*> m_pendingHandleList; >- Vector<CURL*> m_activeHandleList; >- Vector<CURL*> m_removedHandleList; >- mutable Lock m_mutex; >- bool m_runThread { false }; >-}; >- > class CurlDownloadListener { > public: > virtual void didReceiveResponse() { } >@@ -85,7 +48,7 @@ public: > virtual void didFail() { } > }; > >-class CurlDownload : public ThreadSafeRefCounted<CurlDownload> { >+class CurlDownload : public ThreadSafeRefCounted<CurlDownload>, public CurlJob { > public: > CurlDownload(); > ~CurlDownload(); >@@ -107,6 +70,8 @@ public: > > void setDestination(const String& destination) { m_destination = destination; } > >+ virtual CurlJobAction handleCurlMsg(CURLMsg*); >+ > private: > void closeFile(); > void moveFileToDestination(); >@@ -142,10 +107,6 @@ private: > bool m_deletesFileUponFailure { false }; > mutable Lock m_mutex; > CurlDownloadListener* m_listener { nullptr }; >- >- static CurlDownloadManager m_downloadManager; >- >- friend class CurlDownloadManager; > }; > > } >Index: Source/WebCore/platform/network/curl/CurlManager.cpp >=================================================================== >--- Source/WebCore/platform/network/curl/CurlManager.cpp (nonexistent) >+++ Source/WebCore/platform/network/curl/CurlManager.cpp (working copy) >@@ -0,0 +1,288 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * Copyright (C) 2017 Sony Interactive Entertainment Inc. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+ >+#if USE(CURL) >+#include "CurlManager.h" >+ >+#include <wtf/MainThread.h> >+#include <wtf/text/CString.h> >+ >+using namespace WebCore; >+ >+namespace WebCore { >+ >+class CurlSharedResources { >+public: >+ static void lock(CURL*, curl_lock_data, curl_lock_access, void*); >+ static void unlock(CURL*, curl_lock_data, void*); >+ >+private: >+ static Lock* mutexFor(curl_lock_data); >+}; >+ >+// CurlDownloadManager ------------------------------------------------------------------- >+ >+CurlManager::CurlManager() >+{ >+ curl_global_init(CURL_GLOBAL_ALL); >+ m_curlMultiHandle = curl_multi_init(); >+ m_curlShareHandle = curl_share_init(); >+ curl_share_setopt(m_curlShareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); >+ curl_share_setopt(m_curlShareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); >+ curl_share_setopt(m_curlShareHandle, CURLSHOPT_LOCKFUNC, CurlSharedResources::lock); >+ curl_share_setopt(m_curlShareHandle, CURLSHOPT_UNLOCKFUNC, CurlSharedResources::unlock); >+} >+ >+CurlManager::~CurlManager() >+{ >+ stopThread(); >+ curl_multi_cleanup(m_curlMultiHandle); >+ curl_share_cleanup(m_curlShareHandle); >+ curl_global_cleanup(); >+} >+ >+bool CurlManager::add(CURL* curlHandle) >+{ >+ ASSERT(isMainThread()); >+ >+ { >+ LockHolder locker(m_mutex); >+ m_pendingHandleList.append(curlHandle); >+ } >+ >+ startThreadIfNeeded(); >+ >+ return true; >+} >+ >+bool CurlManager::remove(CURL* curlHandle) >+{ >+ LockHolder locker(m_mutex); >+ >+ m_removedHandleList.append(curlHandle); >+ >+ return true; >+} >+ >+int CurlManager::getActiveCount() const >+{ >+ LockHolder locker(m_mutex); >+ return m_activeHandleList.size(); >+} >+ >+int CurlManager::getPendingCount() const >+{ >+ LockHolder locker(m_mutex); >+ return m_pendingHandleList.size(); >+} >+ >+void CurlManager::startThreadIfNeeded() >+{ >+ ASSERT(isMainThread()); >+ >+ if (!runThread()) { >+ if (m_thread) >+ m_thread->waitForCompletion(); >+ setRunThread(true); >+ m_thread = Thread::create(workerThread, this, "curlThread"); >+ } >+} >+ >+void CurlManager::stopThread() >+{ >+ ASSERT(isMainThread()); >+ >+ setRunThread(false); >+ >+ if (m_thread) { >+ m_thread->waitForCompletion(); >+ m_thread = nullptr; >+ } >+} >+ >+void CurlManager::stopThreadIfIdle() >+{ >+ if (!getActiveCount() && !getPendingCount()) >+ setRunThread(false); >+} >+ >+void CurlManager::updateHandleList() >+{ >+ LockHolder locker(m_mutex); >+ >+ // Remove curl easy handles from multi list >+ int size = m_removedHandleList.size(); >+ for (int i = 0; i < size; i++) { >+ removeFromCurl(m_removedHandleList[0]); >+ m_removedHandleList.remove(0); >+ } >+ >+ // Add pending curl easy handles to multi list >+ size = m_pendingHandleList.size(); >+ for (int i = 0; i < size; i++) { >+ addToCurl(m_pendingHandleList[0]); >+ m_pendingHandleList.remove(0); >+ } >+} >+ >+bool CurlManager::addToCurl(CURL* curlHandle) >+{ >+ CURLMcode retval = curl_multi_add_handle(m_curlMultiHandle, curlHandle); >+ if (retval == CURLM_OK) { >+ m_activeHandleList.append(curlHandle); >+ return true; >+ } >+ return false; >+} >+ >+bool CurlManager::removeFromCurl(CURL* curlHandle) >+{ >+ int handlePos = m_activeHandleList.find(curlHandle); >+ >+ if (handlePos < 0) >+ return true; >+ >+ CURLMcode retval = curl_multi_remove_handle(m_curlMultiHandle, curlHandle); >+ if (retval == CURLM_OK) { >+ m_activeHandleList.remove(handlePos); >+ curl_easy_cleanup(curlHandle); >+ return true; >+ } >+ return false; >+} >+ >+void CurlManager::workerThread(void* data) >+{ >+ ASSERT(!isMainThread()); >+ >+ CurlManager* manager = reinterpret_cast<CurlManager*>(data); >+ >+ while (manager->runThread()) { >+ >+ manager->updateHandleList(); >+ >+ // Retry 'select' if it was interrupted by a process signal. >+ int rc = 0; >+ do { >+ fd_set fdread; >+ fd_set fdwrite; >+ fd_set fdexcep; >+ >+ int maxfd = 0; >+ >+ const int selectTimeoutMS = 5; >+ >+ struct timeval timeout; >+ timeout.tv_sec = 0; >+ timeout.tv_usec = selectTimeoutMS * 1000; // select waits microseconds >+ >+ FD_ZERO(&fdread); >+ FD_ZERO(&fdwrite); >+ FD_ZERO(&fdexcep); >+ curl_multi_fdset(manager->getMultiHandle(), &fdread, &fdwrite, &fdexcep, &maxfd); >+ // When the 3 file descriptors are empty, winsock will return -1 >+ // and bail out, stopping the file download. So make sure we >+ // have valid file descriptors before calling select. >+ if (maxfd >= 0) >+ rc = ::select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); >+ } while (rc == -1 && errno == EINTR); >+ >+ int activeCount = 0; >+ while (curl_multi_perform(manager->getMultiHandle(), &activeCount) == CURLM_CALL_MULTI_PERFORM) { } >+ >+ int messagesInQueue = 0; >+ CURLMsg* msg = curl_multi_info_read(manager->getMultiHandle(), &messagesInQueue); >+ >+ if (!msg) >+ continue; >+ >+ >+ CurlJob* job = nullptr; >+ CURLcode err = curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &job); >+ UNUSED_PARAM(err); >+ ASSERT(job); >+ >+ CurlJobAction action = job->handleCurlMsg(msg); >+ >+ if (action == CurlJobAction::Finished) >+ manager->removeFromCurl(msg->easy_handle); >+ >+ manager->stopThreadIfIdle(); >+ } >+} >+ >+// CURL Utilities >+ >+URL CurlUtils::getEffectiveURL(CURL* handle) >+{ >+ const char* url; >+ CURLcode err = curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &url); >+ if (CURLE_OK != err) >+ return URL(); >+ return URL(URL(), url); >+} >+ >+// Shared Resource management ======================= >+ >+Lock* CurlSharedResources::mutexFor(curl_lock_data data) >+{ >+ DEPRECATED_DEFINE_STATIC_LOCAL(Lock, cookieMutex, ()); >+ DEPRECATED_DEFINE_STATIC_LOCAL(Lock, dnsMutex, ()); >+ DEPRECATED_DEFINE_STATIC_LOCAL(Lock, shareMutex, ()); >+ >+ switch (data) { >+ case CURL_LOCK_DATA_COOKIE: >+ return &cookieMutex; >+ case CURL_LOCK_DATA_DNS: >+ return &dnsMutex; >+ case CURL_LOCK_DATA_SHARE: >+ return &shareMutex; >+ default: >+ ASSERT_NOT_REACHED(); >+ return nullptr; >+ } >+} >+ >+// libcurl does not implement its own thread synchronization primitives. >+// these two functions provide mutexes for cookies, and for the global DNS >+// cache. >+void CurlSharedResources::lock(CURL* /* handle */, curl_lock_data data, curl_lock_access /* access */, void* /* userPtr */) >+{ >+ if (Lock* mutex = CurlSharedResources::mutexFor(data)) >+ mutex->lock(); >+} >+ >+void CurlSharedResources::unlock(CURL* /* handle */, curl_lock_data data, void* /* userPtr */) >+{ >+ if (Lock* mutex = CurlSharedResources::mutexFor(data)) >+ mutex->unlock(); >+} >+ >+} >+ >+#endif >Index: Source/WebCore/platform/network/curl/CurlManager.h >=================================================================== >--- Source/WebCore/platform/network/curl/CurlManager.h (nonexistent) >+++ Source/WebCore/platform/network/curl/CurlManager.h (working copy) >@@ -0,0 +1,107 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * Copyright (C) 2017 Sony Interactive Entertainment Inc. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include <curl/curl.h> >+#include <wtf/Lock.h> >+#include <wtf/Threading.h> >+ >+#if PLATFORM(WIN) >+#include <windows.h> >+#include <winsock2.h> >+#endif >+ >+#include "URL.h" >+ >+namespace WebCore { >+ >+enum class CurlJobAction { None, Finished }; >+ >+class CurlJob { >+public: >+ virtual CurlJobAction handleCurlMsg(CURLMsg*) = 0; >+}; >+ >+class CurlManager { >+public: >+ static CurlManager& singleton() >+ { >+ // Since it's a static variable, if the class has already been created, >+ // It won't be created again. >+ // And it **is** thread-safe in C++11. >+ >+ static CurlManager shared; >+ return shared; >+ } >+ >+ CurlManager(); >+ virtual ~CurlManager(); >+ >+ bool add(CURL* curlHandle); >+ bool remove(CURL* curlHandle); >+ >+ int getActiveCount() const; >+ int getPendingCount() const; >+ >+ CURLSH* getCurlShareHandle() const { return m_curlShareHandle; } >+ >+private: >+ void startThreadIfNeeded(); >+ void stopThread(); >+ void stopThreadIfIdle(); >+ >+ void updateHandleList(); >+ >+ CURLM* getMultiHandle() const { return m_curlMultiHandle; } >+ >+ bool runThread() const { LockHolder locker(m_mutex); return m_runThread; } >+ void setRunThread(bool runThread) { LockHolder locker(m_mutex); m_runThread = runThread; } >+ >+ bool addToCurl(CURL* curlHandle); >+ bool removeFromCurl(CURL* curlHandle); >+ >+ static void workerThread(void* data); >+ >+ RefPtr<Thread> m_thread; >+ CURLM* m_curlMultiHandle { nullptr }; >+ Vector<CURL*> m_pendingHandleList; >+ Vector<CURL*> m_activeHandleList; >+ Vector<CURL*> m_removedHandleList; >+ mutable Lock m_mutex; >+ bool m_runThread { false }; >+ >+ CURLSH* m_curlShareHandle { nullptr }; >+ >+ friend class CurlJob; >+}; >+ >+class CurlUtils { >+public: >+ static URL getEffectiveURL(CURL* handle); >+}; >+ >+} >Index: Source/WebCore/platform/network/curl/ResourceHandleManager.cpp >=================================================================== >--- Source/WebCore/platform/network/curl/ResourceHandleManager.cpp (revision 218635) >+++ Source/WebCore/platform/network/curl/ResourceHandleManager.cpp (working copy) >@@ -42,6 +42,7 @@ > > #include "CredentialStorage.h" > #include "CurlCacheManager.h" >+#include "CurlManager.h" > #include "HTTPHeaderNames.h" > #include "HTTPParsers.h" > #include "MIMETypeRegistry.h" >@@ -87,15 +88,6 @@ static const Seconds pollTime { 50_ms }; > const int maxRunningJobs = 128; > const char* const errorDomainCurl = "CurlErrorDomain"; > >-URL getCurlEffectiveURL(CURL* handle) >-{ >- const char* url; >- CURLcode err = curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &url); >- if (CURLE_OK != err) >- return URL(); >- return URL(URL(), url); >-} >- > static const bool ignoreSSLErrors = getenv("WEBKIT_IGNORE_SSL_ERRORS"); > > static CString certificatePath() >@@ -151,25 +143,6 @@ static char* cookieJarPath() > #endif > } > >-static Lock* sharedResourceMutex(curl_lock_data data) >-{ >- DEPRECATED_DEFINE_STATIC_LOCAL(Lock, cookieMutex, ()); >- DEPRECATED_DEFINE_STATIC_LOCAL(Lock, dnsMutex, ()); >- DEPRECATED_DEFINE_STATIC_LOCAL(Lock, shareMutex, ()); >- >- switch (data) { >- case CURL_LOCK_DATA_COOKIE: >- return &cookieMutex; >- case CURL_LOCK_DATA_DNS: >- return &dnsMutex; >- case CURL_LOCK_DATA_SHARE: >- return &shareMutex; >- default: >- ASSERT_NOT_REACHED(); >- return NULL; >- } >-} >- > #if ENABLE(WEB_TIMING) > static void calculateWebTimingInformations(ResourceHandleInternal* d) > { >@@ -197,21 +170,6 @@ static void calculateWebTimingInformatio > } > #endif > >-// libcurl does not implement its own thread synchronization primitives. >-// these two functions provide mutexes for cookies, and for the global DNS >-// cache. >-static void curl_lock_callback(CURL* /* handle */, curl_lock_data data, curl_lock_access /* access */, void* /* userPtr */) >-{ >- if (Lock* mutex = sharedResourceMutex(data)) >- mutex->lock(); >-} >- >-static void curl_unlock_callback(CURL* /* handle */, curl_lock_data data, void* /* userPtr */) >-{ >- if (Lock* mutex = sharedResourceMutex(data)) >- mutex->unlock(); >-} >- > inline static bool isHttpInfo(int statusCode) > { > return 100 <= statusCode && statusCode < 200; >@@ -235,19 +193,16 @@ inline static bool isHttpNotModified(int > ResourceHandleManager::ResourceHandleManager() > : m_downloadTimer(*this, &ResourceHandleManager::downloadTimerCallback) > , m_cookieJarFileName(cookieJarPath()) >- , m_certificatePath (certificatePath()) >+ , m_certificatePath(certificatePath()) > , m_runningJobs(0) > #ifndef NDEBUG > , m_logFile(nullptr) > #endif > { >- curl_global_init(CURL_GLOBAL_ALL); >+ CURLSH* h = CurlManager::singleton().getCurlShareHandle(); >+ m_curlShareHandle = h; > m_curlMultiHandle = curl_multi_init(); >- m_curlShareHandle = curl_share_init(); >- curl_share_setopt(m_curlShareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); >- curl_share_setopt(m_curlShareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); >- curl_share_setopt(m_curlShareHandle, CURLSHOPT_LOCKFUNC, curl_lock_callback); >- curl_share_setopt(m_curlShareHandle, CURLSHOPT_UNLOCKFUNC, curl_unlock_callback); >+ > > initCookieSession(); > >@@ -261,10 +216,8 @@ ResourceHandleManager::ResourceHandleMan > ResourceHandleManager::~ResourceHandleManager() > { > curl_multi_cleanup(m_curlMultiHandle); >- curl_share_cleanup(m_curlShareHandle); > if (m_cookieJarFileName) > fastFree(m_cookieJarFileName); >- curl_global_cleanup(); > > #ifndef NDEBUG > if (m_logFile) >@@ -272,11 +225,6 @@ ResourceHandleManager::~ResourceHandleMa > #endif > } > >-CURLSH* ResourceHandleManager::getCurlShareHandle() const >-{ >- return m_curlShareHandle; >-} >- > void ResourceHandleManager::setCookieJarFileName(const char* cookieJarFileName) > { > m_cookieJarFileName = fastStrDup(cookieJarFileName); >@@ -302,7 +250,7 @@ static void handleLocalReceiveResponse ( > // which means the ResourceLoader's response does not contain the URL. > // Run the code here for local files to resolve the issue. > // TODO: See if there is a better approach for handling this. >- URL url = getCurlEffectiveURL(handle); >+ URL url = CurlUtils::getEffectiveURL(handle); > ASSERT(url.isValid()); > d->m_response.setURL(url); > if (d->client()) >@@ -413,7 +361,7 @@ static bool getProtectionSpace(CURL* h, > if (err != CURLE_OK) > return false; > >- URL url = getCurlEffectiveURL(h); >+ URL url = CurlUtils::getEffectiveURL(h); > if (!url.isValid()) > return false; > >@@ -502,7 +450,7 @@ static size_t headerCallback(char* ptr, > curl_easy_getinfo(h, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength); > d->m_response.setExpectedContentLength(static_cast<long long int>(contentLength)); > >- d->m_response.setURL(getCurlEffectiveURL(h)); >+ d->m_response.setURL(CurlUtils::getEffectiveURL(h)); > > d->m_response.setHTTPStatusCode(httpCode); > d->m_response.setMimeType(extractMIMETypeFromMediaType(d->m_response.httpHeaderField(HTTPHeaderName::ContentType)).convertToASCIILowercase()); >@@ -709,7 +657,7 @@ void ResourceHandleManager::downloadTime > CurlCacheManager::getInstance().didFinishLoading(*job); > } > } else { >- URL url = getCurlEffectiveURL(d->m_handle); >+ URL url = CurlUtils::getEffectiveURL(d->m_handle); > #ifndef NDEBUG > fprintf(stderr, "Curl ERROR for url='%s', error: '%s'\n", url.string().utf8().data(), curl_easy_strerror(msg->data.result)); > #endif >Index: Source/WebCore/platform/network/curl/ResourceHandleManager.h >=================================================================== >--- Source/WebCore/platform/network/curl/ResourceHandleManager.h (revision 218635) >+++ Source/WebCore/platform/network/curl/ResourceHandleManager.h (working copy) >@@ -57,8 +57,6 @@ public: > void add(ResourceHandle*); > void cancel(ResourceHandle*); > >- CURLSH* getCurlShareHandle() const; >- > void setCookieJarFileName(const char* cookieJarFileName); > const char* getCookieJarFileName() const; > >@@ -100,8 +98,6 @@ private: > #endif > }; > >-URL getCurlEffectiveURL(CURL*); >- > } > > #endif
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 173557
:
313335
|
313408
| 313524 |
313653