Merge remote-tracking branch 'aleric/master'
This commit is contained in:
@@ -408,6 +408,16 @@ void initCurl(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MAIN-THREAD
|
||||||
|
void shutdownCurl(void)
|
||||||
|
{
|
||||||
|
using namespace AICurlPrivate;
|
||||||
|
|
||||||
|
DoutEntering(dc::curl, "AICurlInterface::shutdownCurl()");
|
||||||
|
|
||||||
|
BufferedCurlEasyRequest::shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
// MAIN-THREAD
|
// MAIN-THREAD
|
||||||
void cleanupCurl(void)
|
void cleanupCurl(void)
|
||||||
{
|
{
|
||||||
@@ -1293,6 +1303,8 @@ bool CurlEasyRequest::removeFromPerHostQueue(AICurlEasyRequest const& easy_reque
|
|||||||
static int const HTTP_REDIRECTS_DEFAULT = 10;
|
static int const HTTP_REDIRECTS_DEFAULT = 10;
|
||||||
|
|
||||||
LLChannelDescriptors const BufferedCurlEasyRequest::sChannels;
|
LLChannelDescriptors const BufferedCurlEasyRequest::sChannels;
|
||||||
|
LLMutex BufferedCurlEasyRequest::sResponderCallbackMutex;
|
||||||
|
bool BufferedCurlEasyRequest::sShuttingDown = false;
|
||||||
|
|
||||||
BufferedCurlEasyRequest::BufferedCurlEasyRequest() : mRequestTransferedBytes(0), mResponseTransferedBytes(0), mBufferEventsTarget(NULL), mStatus(HTTP_INTERNAL_ERROR_OTHER)
|
BufferedCurlEasyRequest::BufferedCurlEasyRequest() : mRequestTransferedBytes(0), mResponseTransferedBytes(0), mBufferEventsTarget(NULL), mStatus(HTTP_INTERNAL_ERROR_OTHER)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -163,8 +163,13 @@ void initCurl(void);
|
|||||||
// Called once at start of application (from LLAppViewer::initThreads), starts AICurlThread.
|
// Called once at start of application (from LLAppViewer::initThreads), starts AICurlThread.
|
||||||
void startCurlThread(U32 CurlMaxTotalConcurrentConnections, U32 CurlConcurrentConnectionsPerHost, bool NoVerifySSLCert);
|
void startCurlThread(U32 CurlMaxTotalConcurrentConnections, U32 CurlConcurrentConnectionsPerHost, bool NoVerifySSLCert);
|
||||||
|
|
||||||
// Called once at end of application (from newview/llappviewer.cpp by main thread),
|
// Called once at the end of application before terminating other threads (most notably the texture thread workers)
|
||||||
// with purpose to stop curl threads, free curl resources and deinitialize curl.
|
// with the purpose to stop the curl thread from doing any call backs to running responders: the responders sometimes
|
||||||
|
// access objects that will be shot down when bringing down other threads.
|
||||||
|
void shutdownCurl(void);
|
||||||
|
|
||||||
|
// Called once at end of application (from newview/llappviewer.cpp by main thread) after all other threads have been terminated
|
||||||
|
// with the purpose to stop the curl thread, free curl resources and deinitialize curl.
|
||||||
void cleanupCurl(void);
|
void cleanupCurl(void);
|
||||||
|
|
||||||
// Called from indra/newview/llfloaterabout.cpp for the About floater, and
|
// Called from indra/newview/llfloaterabout.cpp for the About floater, and
|
||||||
|
|||||||
@@ -386,6 +386,9 @@ class BufferedCurlEasyRequest : public CurlEasyRequest {
|
|||||||
// Called after removed_from_multi_handle was called.
|
// Called after removed_from_multi_handle was called.
|
||||||
void processOutput(void);
|
void processOutput(void);
|
||||||
|
|
||||||
|
// Called just before shutting down the texture thread, to prevent responder call backs.
|
||||||
|
static void shutdown(void);
|
||||||
|
|
||||||
// Do not write more than this amount.
|
// Do not write more than this amount.
|
||||||
//void setBodyLimit(U32 size) { mBodyLimit = size; }
|
//void setBodyLimit(U32 size) { mBodyLimit = size; }
|
||||||
|
|
||||||
@@ -412,6 +415,8 @@ class BufferedCurlEasyRequest : public CurlEasyRequest {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static LLChannelDescriptors const sChannels; // Channel object for mInput (channel out()) and mOutput (channel in()).
|
static LLChannelDescriptors const sChannels; // Channel object for mInput (channel out()) and mOutput (channel in()).
|
||||||
|
static LLMutex sResponderCallbackMutex; // Locked while calling back any overridden ResponderBase::finished and/or accessing sShuttingDown.
|
||||||
|
static bool sShuttingDown; // If true, no additional calls to ResponderBase::finished will be made anymore.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// This class may only be created by constructing a ThreadSafeBufferedCurlEasyRequest.
|
// This class may only be created by constructing a ThreadSafeBufferedCurlEasyRequest.
|
||||||
|
|||||||
@@ -1992,20 +1992,33 @@ void BufferedCurlEasyRequest::processOutput(void)
|
|||||||
{
|
{
|
||||||
print_diagnostics(code);
|
print_diagnostics(code);
|
||||||
}
|
}
|
||||||
if (mBufferEventsTarget)
|
sResponderCallbackMutex.lock();
|
||||||
|
if (!sShuttingDown)
|
||||||
{
|
{
|
||||||
// Only the responder registers for these events.
|
if (mBufferEventsTarget)
|
||||||
llassert(mBufferEventsTarget == mResponder.get());
|
{
|
||||||
// Allow clients to parse result codes and headers before we attempt to parse
|
// Only the responder registers for these events.
|
||||||
// the body and provide completed/result/error calls.
|
llassert(mBufferEventsTarget == mResponder.get());
|
||||||
mBufferEventsTarget->completed_headers(responseCode, responseReason, (code == CURLE_FAILED_INIT) ? NULL : &info);
|
// Allow clients to parse result codes and headers before we attempt to parse
|
||||||
|
// the body and provide completed/result/error calls.
|
||||||
|
mBufferEventsTarget->completed_headers(responseCode, responseReason, (code == CURLE_FAILED_INIT) ? NULL : &info);
|
||||||
|
}
|
||||||
|
mResponder->finished(code, responseCode, responseReason, sChannels, mOutput);
|
||||||
}
|
}
|
||||||
mResponder->finished(code, responseCode, responseReason, sChannels, mOutput);
|
sResponderCallbackMutex.unlock();
|
||||||
mResponder = NULL;
|
mResponder = NULL;
|
||||||
|
|
||||||
resetState();
|
resetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
void BufferedCurlEasyRequest::shutdown(void)
|
||||||
|
{
|
||||||
|
sResponderCallbackMutex.lock();
|
||||||
|
sShuttingDown = true;
|
||||||
|
sResponderCallbackMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
void BufferedCurlEasyRequest::received_HTTP_header(void)
|
void BufferedCurlEasyRequest::received_HTTP_header(void)
|
||||||
{
|
{
|
||||||
if (mBufferEventsTarget)
|
if (mBufferEventsTarget)
|
||||||
|
|||||||
@@ -347,6 +347,12 @@ void LLHTTPClient::ResponderBase::decode_llsd_body(U32 status, std::string const
|
|||||||
{
|
{
|
||||||
llwarns << "The server sent us a response with http status " << status << " and LLSD(!) body: \"" << ss.str() << "\"!" << llendl;
|
llwarns << "The server sent us a response with http status " << status << " and LLSD(!) body: \"" << ss.str() << "\"!" << llendl;
|
||||||
}
|
}
|
||||||
|
// This is not really an error, and it has been known to happen before. It just normally never happens (at the moment)
|
||||||
|
// and therefore warrants an investigation. Linden Lab (or other grids) might start to send error messages
|
||||||
|
// as LLSD in the body in future, but until that happens frequently we might want to leave this assert in.
|
||||||
|
// Note that an HTTP error code means an error at the transport level in most cases-- so I'm highly suspicious
|
||||||
|
// when there is any additional information in the body in LLSD format: it is not unlikely to be a server
|
||||||
|
// bug, where the returned HTTP status code should have been 200 instead.
|
||||||
llassert(!server_sent_llsd_with_http_error);
|
llassert(!server_sent_llsd_with_http_error);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1741,6 +1741,8 @@ bool LLAppViewer::cleanup()
|
|||||||
LLViewerMedia::saveCookieFile();
|
LLViewerMedia::saveCookieFile();
|
||||||
// Stop the plugin read thread if it's running.
|
// Stop the plugin read thread if it's running.
|
||||||
LLPluginProcessParent::setUseReadThread(false);
|
LLPluginProcessParent::setUseReadThread(false);
|
||||||
|
// Stop curl responder call backs.
|
||||||
|
AICurlInterface::shutdownCurl();
|
||||||
|
|
||||||
llinfos << "Shutting down Threads" << llendflush;
|
llinfos << "Shutting down Threads" << llendflush;
|
||||||
|
|
||||||
|
|||||||
@@ -618,18 +618,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
|
|||||||
if (fetch_info.mIsCategory)
|
if (fetch_info.mIsCategory)
|
||||||
{
|
{
|
||||||
const LLUUID &cat_id = fetch_info.mUUID;
|
const LLUUID &cat_id = fetch_info.mUUID;
|
||||||
if (cat_id.isNull()) //DEV-17797
|
if (!cat_id.isNull())
|
||||||
{
|
|
||||||
LLSD folder_sd;
|
|
||||||
folder_sd["folder_id"] = LLUUID::null.asString();
|
|
||||||
folder_sd["owner_id"] = gAgent.getID();
|
|
||||||
folder_sd["sort_order"] = (LLSD::Integer)sort_order;
|
|
||||||
folder_sd["fetch_folders"] = (LLSD::Boolean)FALSE;
|
|
||||||
folder_sd["fetch_items"] = (LLSD::Boolean)TRUE;
|
|
||||||
folder_request_body["folders"].append(folder_sd);
|
|
||||||
folder_count++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
const LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
|
const LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
|
||||||
|
|
||||||
@@ -664,9 +653,9 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (fetch_info.mRecursive)
|
||||||
|
recursive_cats.push_back(cat_id);
|
||||||
}
|
}
|
||||||
if (fetch_info.mRecursive)
|
|
||||||
recursive_cats.push_back(cat_id);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user