Implement curl connection throttling (CurlConcurrentConnections)
This commit is contained in:
@@ -99,7 +99,7 @@ struct TransferInfo {
|
|||||||
void initCurl(void (*)(void) = NULL);
|
void initCurl(void (*)(void) = NULL);
|
||||||
|
|
||||||
// Called once at start of application (from LLAppViewer::initThreads), starts AICurlThread.
|
// Called once at start of application (from LLAppViewer::initThreads), starts AICurlThread.
|
||||||
void startCurlThread(void);
|
void startCurlThread(U32 CurlConcurrentConnections);
|
||||||
|
|
||||||
// Called once at end of application (from newview/llappviewer.cpp by main thread),
|
// Called once at end of application (from newview/llappviewer.cpp by main thread),
|
||||||
// with purpose to stop curl threads, free curl resources and deinitialize curl.
|
// with purpose to stop curl threads, free curl resources and deinitialize curl.
|
||||||
|
|||||||
@@ -1440,18 +1440,27 @@ CURLMsg const* MultiHandle::info_read(int* msgs_in_queue) const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLMcode MultiHandle::add_easy_request(AICurlEasyRequest const& easy_request)
|
static U32 curl_concurrent_connections = 8; // Initialized on start up by startCurlThread().
|
||||||
|
|
||||||
|
void MultiHandle::add_easy_request(AICurlEasyRequest const& easy_request)
|
||||||
{
|
{
|
||||||
std::pair<addedEasyRequests_type::iterator, bool> res = mAddedEasyRequests.insert(easy_request);
|
if (mAddedEasyRequests.size() < curl_concurrent_connections) // Not throttled?
|
||||||
llassert(res.second); // May not have been added before.
|
|
||||||
CURLMcode ret;
|
|
||||||
{
|
{
|
||||||
AICurlEasyRequest_wat curl_easy_request_w(*easy_request);
|
CURLMcode ret;
|
||||||
ret = curl_easy_request_w->add_handle_to_multi(curl_easy_request_w, mMultiHandle);
|
{
|
||||||
|
AICurlEasyRequest_wat curl_easy_request_w(*easy_request);
|
||||||
|
ret = curl_easy_request_w->add_handle_to_multi(curl_easy_request_w, mMultiHandle);
|
||||||
|
}
|
||||||
|
if (ret == CURLM_OK)
|
||||||
|
{
|
||||||
|
mHandleAddedOrRemoved = true;
|
||||||
|
std::pair<addedEasyRequests_type::iterator, bool> res = mAddedEasyRequests.insert(easy_request);
|
||||||
|
llassert(res.second); // May not have been added before.
|
||||||
|
Dout(dc::curl, "MultiHandle::add_easy_request: Added AICurlEasyRequest " << (void*)easy_request.get() << "; now processing " << mAddedEasyRequests.size() << " easy handles.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mHandleAddedOrRemoved = true;
|
mQueuedRequests.push_back(easy_request);
|
||||||
Dout(dc::curl, "MultiHandle::add_easy_request: Added AICurlEasyRequest " << (void*)easy_request.get() << "; now processing " << mAddedEasyRequests.size() << " easy handles.");
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLMcode MultiHandle::remove_easy_request(AICurlEasyRequest const& easy_request, bool as_per_command)
|
CURLMcode MultiHandle::remove_easy_request(AICurlEasyRequest const& easy_request, bool as_per_command)
|
||||||
@@ -1470,6 +1479,14 @@ CURLMcode MultiHandle::remove_easy_request(AICurlEasyRequest const& easy_request
|
|||||||
mAddedEasyRequests.erase(iter);
|
mAddedEasyRequests.erase(iter);
|
||||||
mHandleAddedOrRemoved = true;
|
mHandleAddedOrRemoved = true;
|
||||||
Dout(dc::curl, "MultiHandle::remove_easy_request: Removed AICurlEasyRequest " << (void*)easy_request.get() << "; now processing " << mAddedEasyRequests.size() << " easy handles.");
|
Dout(dc::curl, "MultiHandle::remove_easy_request: Removed AICurlEasyRequest " << (void*)easy_request.get() << "; now processing " << mAddedEasyRequests.size() << " easy handles.");
|
||||||
|
|
||||||
|
// Attempt to add a queued request, if any.
|
||||||
|
if (!mQueuedRequests.empty())
|
||||||
|
{
|
||||||
|
add_easy_request(mQueuedRequests.front());
|
||||||
|
mQueuedRequests.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1697,11 +1714,12 @@ void AICurlEasyRequest::removeRequest(void)
|
|||||||
|
|
||||||
namespace AICurlInterface {
|
namespace AICurlInterface {
|
||||||
|
|
||||||
void startCurlThread(void)
|
void startCurlThread(U32 CurlConcurrentConnections)
|
||||||
{
|
{
|
||||||
using namespace AICurlPrivate::curlthread;
|
using namespace AICurlPrivate::curlthread;
|
||||||
|
|
||||||
llassert(is_main_thread());
|
llassert(is_main_thread());
|
||||||
|
curl_concurrent_connections = CurlConcurrentConnections; // Debug Setting.
|
||||||
AICurlThread::sInstance = new AICurlThread;
|
AICurlThread::sInstance = new AICurlThread;
|
||||||
AICurlThread::sInstance->start();
|
AICurlThread::sInstance->start();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "aicurl.h"
|
#include "aicurl.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
#undef AICurlPrivate
|
#undef AICurlPrivate
|
||||||
|
|
||||||
@@ -59,7 +60,7 @@ class MultiHandle : public CurlMultiHandle
|
|||||||
~MultiHandle();
|
~MultiHandle();
|
||||||
|
|
||||||
// Add/remove an easy handle to/from a multi session.
|
// Add/remove an easy handle to/from a multi session.
|
||||||
CURLMcode add_easy_request(AICurlEasyRequest const& easy_request);
|
void add_easy_request(AICurlEasyRequest const& easy_request);
|
||||||
CURLMcode remove_easy_request(AICurlEasyRequest const& easy_request, bool as_per_command = false);
|
CURLMcode remove_easy_request(AICurlEasyRequest const& easy_request, bool as_per_command = false);
|
||||||
|
|
||||||
// Reads/writes available data from a particular socket (non-blocking).
|
// Reads/writes available data from a particular socket (non-blocking).
|
||||||
@@ -100,6 +101,10 @@ class MultiHandle : public CurlMultiHandle
|
|||||||
|
|
||||||
PollSet* mReadPollSet;
|
PollSet* mReadPollSet;
|
||||||
PollSet* mWritePollSet;
|
PollSet* mWritePollSet;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Temporary throttling hack.
|
||||||
|
std::deque<AICurlEasyRequest> mQueuedRequests; // Waiting (throttled) requests.
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace curlthread
|
} // namespace curlthread
|
||||||
|
|||||||
@@ -4205,6 +4205,17 @@
|
|||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
</map>
|
</map>
|
||||||
|
<key>CurlConcurrentConnections</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Maximum number of simultaneous curl connections (requires restart)</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>U32</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>16</integer>
|
||||||
|
</map>
|
||||||
<key>CurlMaximumNumberOfHandles</key>
|
<key>CurlMaximumNumberOfHandles</key>
|
||||||
<map>
|
<map>
|
||||||
<key>Comment</key>
|
<key>Comment</key>
|
||||||
|
|||||||
@@ -1817,7 +1817,7 @@ bool LLAppViewer::initThreads()
|
|||||||
LLWatchdog::getInstance()->init(watchdog_killer_callback);
|
LLWatchdog::getInstance()->init(watchdog_killer_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
AICurlInterface::startCurlThread();
|
AICurlInterface::startCurlThread(gSavedSettings.getU32("CurlConcurrentConnections"));
|
||||||
|
|
||||||
LLImage::initClass();
|
LLImage::initClass();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user