SH-2031 Don't do network I/O from the main thread in llcurl.

Reviewed by Kelly
meow-7.2.2
Dave Parks 2011-07-21 17:35:04 -05:00
parent 65d82fe192
commit 764a13a196
10 changed files with 137 additions and 18 deletions

View File

@ -579,11 +579,18 @@ void LLCurl::Easy::prepRequest(const std::string& url,
////////////////////////////////////////////////////////////////////////////
class LLCurl::Multi
class LLCurl::Multi : public LLThread
{
LOG_CLASS(Multi);
public:
typedef enum
{
PERFORM_STATE_READY=0,
PERFORM_STATE_PERFORMING=1,
PERFORM_STATE_COMPLETED=2
} ePerformState;
Multi();
~Multi();
@ -593,13 +600,17 @@ public:
void removeEasy(Easy* easy);
S32 process();
S32 perform();
void perform();
virtual void run();
CURLMsg* info_read(S32* msgs_in_queue);
S32 mQueued;
S32 mErrorCount;
S32 mPerformState;
private:
void easyFree(Easy*);
@ -614,8 +625,10 @@ private:
};
LLCurl::Multi::Multi()
: mQueued(0),
mErrorCount(0)
: LLThread("Curl Multi"),
mQueued(0),
mErrorCount(0),
mPerformState(PERFORM_STATE_READY)
{
mCurlMultiHandle = curl_multi_init();
if (!mCurlMultiHandle)
@ -630,6 +643,7 @@ LLCurl::Multi::Multi()
LLCurl::Multi::~Multi()
{
llassert(isStopped());
// Clean up active
for(easy_active_list_t::iterator iter = mEasyActiveList.begin();
iter != mEasyActiveList.end(); ++iter)
@ -655,8 +669,16 @@ CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue)
return curlmsg;
}
void LLCurl::Multi::perform()
{
if (mPerformState == PERFORM_STATE_READY)
{
mPerformState = PERFORM_STATE_PERFORMING;
start();
}
}
S32 LLCurl::Multi::perform()
void LLCurl::Multi::run()
{
S32 q = 0;
for (S32 call_count = 0;
@ -672,13 +694,18 @@ S32 LLCurl::Multi::perform()
}
mQueued = q;
return q;
mPerformState = PERFORM_STATE_COMPLETED;
}
S32 LLCurl::Multi::process()
{
perform();
if (mPerformState != PERFORM_STATE_COMPLETED)
{
return 0;
}
CURLMsg* msg;
int msgs_in_queue;
@ -709,6 +736,8 @@ S32 LLCurl::Multi::process()
}
}
}
mPerformState = PERFORM_STATE_READY;
return processed;
}
@ -923,6 +952,12 @@ S32 LLCurlRequest::process()
if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0)
{
mMultiSet.erase(curiter);
while (!multi->isStopped())
{
apr_sleep(1000);
}
delete multi;
}
}
@ -963,6 +998,10 @@ LLCurlEasyRequest::LLCurlEasyRequest()
LLCurlEasyRequest::~LLCurlEasyRequest()
{
while (!mMulti->isStopped())
{
apr_sleep(1000);
}
delete mMulti;
}
@ -1059,14 +1098,20 @@ void LLCurlEasyRequest::requestComplete()
}
}
S32 LLCurlEasyRequest::perform()
void LLCurlEasyRequest::perform()
{
return mMulti->perform();
mMulti->perform();
}
// Usage: Call getRestult until it returns false (no more messages)
bool LLCurlEasyRequest::getResult(CURLcode* result, LLCurl::TransferInfo* info)
{
if (mMulti->mPerformState != LLCurl::Multi::PERFORM_STATE_COMPLETED)
{ //we're busy, try again later
return false;
}
mMulti->mPerformState = LLCurl::Multi::PERFORM_STATE_READY;
if (!mEasy)
{
// Special case - we failed to initialize a curl_easy (can happen if too many open files)

View File

@ -236,7 +236,7 @@ public:
void slist_append(const char* str);
void sendRequest(const std::string& url);
void requestComplete();
S32 perform();
void perform();
bool getResult(CURLcode* result, LLCurl::TransferInfo* info = NULL);
std::string getErrorString();

View File

@ -308,6 +308,7 @@ LLFilterSD2XMLRPCResponse::~LLFilterSD2XMLRPCResponse()
}
static LLFastTimer::DeclareTimer FTM_PROCESS_SD2XMLRPC_RESPONSE("SD2XMLRPC Response");
// virtual
LLIOPipe::EStatus LLFilterSD2XMLRPCResponse::process_impl(
const LLChannelDescriptors& channels,
@ -316,6 +317,8 @@ LLIOPipe::EStatus LLFilterSD2XMLRPCResponse::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_SD2XMLRPC_RESPONSE);
PUMP_DEBUG;
// This pipe does not work if it does not have everyting. This
// could be addressed by making a stream parser for llsd which
@ -382,6 +385,8 @@ LLFilterSD2XMLRPCRequest::~LLFilterSD2XMLRPCRequest()
{
}
static LLFastTimer::DeclareTimer FTM_PROCESS_SD2XMLRPC_REQUEST("S22XMLRPC Request");
// virtual
LLIOPipe::EStatus LLFilterSD2XMLRPCRequest::process_impl(
const LLChannelDescriptors& channels,
@ -390,6 +395,7 @@ LLIOPipe::EStatus LLFilterSD2XMLRPCRequest::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_SD2XMLRPC_REQUEST);
// This pipe does not work if it does not have everyting. This
// could be addressed by making a stream parser for llsd which
// handled partial information.
@ -586,6 +592,8 @@ LLFilterXMLRPCResponse2LLSD::~LLFilterXMLRPCResponse2LLSD()
{
}
static LLFastTimer::DeclareTimer FTM_PROCESS_XMLRPC2LLSD_RESPONSE("XMLRPC2LLSD Response");
LLIOPipe::EStatus LLFilterXMLRPCResponse2LLSD::process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
@ -593,6 +601,8 @@ LLIOPipe::EStatus LLFilterXMLRPCResponse2LLSD::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_XMLRPC2LLSD_RESPONSE);
PUMP_DEBUG;
if(!eos) return STATUS_BREAK;
if(!buffer) return STATUS_ERROR;
@ -668,6 +678,7 @@ LLFilterXMLRPCRequest2LLSD::~LLFilterXMLRPCRequest2LLSD()
{
}
static LLFastTimer::DeclareTimer FTM_PROCESS_XMLRPC2LLSD_REQUEST("XMLRPC2LLSD Request");
LLIOPipe::EStatus LLFilterXMLRPCRequest2LLSD::process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
@ -675,6 +686,7 @@ LLIOPipe::EStatus LLFilterXMLRPCRequest2LLSD::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_XMLRPC2LLSD_REQUEST);
PUMP_DEBUG;
if(!eos) return STATUS_BREAK;
if(!buffer) return STATUS_ERROR;

View File

@ -140,6 +140,7 @@ private:
LLSD mHeaders;
};
static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_PIPE("HTTP Pipe");
LLIOPipe::EStatus LLHTTPPipe::process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
@ -147,6 +148,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_HTTP_PIPE);
PUMP_DEBUG;
lldebugs << "LLSDHTTPServer::process_impl" << llendl;
@ -428,6 +430,9 @@ protected:
/**
* LLHTTPResponseHeader
*/
static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_HEADER("HTTP Header");
// virtual
LLIOPipe::EStatus LLHTTPResponseHeader::process_impl(
const LLChannelDescriptors& channels,
@ -436,6 +441,7 @@ LLIOPipe::EStatus LLHTTPResponseHeader::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_HTTP_HEADER);
PUMP_DEBUG;
LLMemType m1(LLMemType::MTYPE_IO_HTTP_SERVER);
if(eos)
@ -630,6 +636,8 @@ void LLHTTPResponder::markBad(
<< "</body>\n</html>\n";
}
static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_RESPONDER("HTTP Responder");
// virtual
LLIOPipe::EStatus LLHTTPResponder::process_impl(
const LLChannelDescriptors& channels,
@ -638,6 +646,7 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_HTTP_RESPONDER);
PUMP_DEBUG;
LLMemType m1(LLMemType::MTYPE_IO_HTTP_SERVER);
LLIOPipe::EStatus status = STATUS_OK;

View File

@ -301,6 +301,8 @@ LLIOSocketReader::~LLIOSocketReader()
//lldebugs << "Destroying LLIOSocketReader" << llendl;
}
static LLFastTimer::DeclareTimer FTM_PROCESS_SOCKET_READER("Socket Reader");
// virtual
LLIOPipe::EStatus LLIOSocketReader::process_impl(
const LLChannelDescriptors& channels,
@ -309,6 +311,7 @@ LLIOPipe::EStatus LLIOSocketReader::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_SOCKET_READER);
PUMP_DEBUG;
LLMemType m1(LLMemType::MTYPE_IO_TCP);
if(!mSource) return STATUS_PRECONDITION_NOT_MET;
@ -401,6 +404,7 @@ LLIOSocketWriter::~LLIOSocketWriter()
//lldebugs << "Destroying LLIOSocketWriter" << llendl;
}
static LLFastTimer::DeclareTimer FTM_PROCESS_SOCKET_WRITER("Socket Writer");
// virtual
LLIOPipe::EStatus LLIOSocketWriter::process_impl(
const LLChannelDescriptors& channels,
@ -409,6 +413,7 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_SOCKET_WRITER);
PUMP_DEBUG;
LLMemType m1(LLMemType::MTYPE_IO_TCP);
if(!mDestination) return STATUS_PRECONDITION_NOT_MET;
@ -555,6 +560,7 @@ void LLIOServerSocket::setResponseTimeout(F32 timeout_secs)
mResponseTimeout = timeout_secs;
}
static LLFastTimer::DeclareTimer FTM_PROCESS_SERVER_SOCKET("Server Socket");
// virtual
LLIOPipe::EStatus LLIOServerSocket::process_impl(
const LLChannelDescriptors& channels,
@ -563,6 +569,7 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_SERVER_SOCKET);
PUMP_DEBUG;
LLMemType m1(LLMemType::MTYPE_IO_TCP);
if(!pump)

View File

@ -43,6 +43,8 @@ LLIOPipe::EStatus LLIOFlush::process_impl(
return STATUS_OK;
}
static LLFastTimer::DeclareTimer FTM_PROCESS_SLEEP("IO Sleep");
/**
* @class LLIOSleep
*/
@ -53,6 +55,7 @@ LLIOPipe::EStatus LLIOSleep::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_SLEEP);
if(mSeconds > 0.0)
{
if(pump) pump->sleepChain(mSeconds);
@ -62,6 +65,7 @@ LLIOPipe::EStatus LLIOSleep::process_impl(
return STATUS_DONE;
}
static LLFastTimer::DeclareTimer FTM_PROCESS_ADD_CHAIN("Add Chain");
/**
* @class LLIOAddChain
*/
@ -72,6 +76,7 @@ LLIOPipe::EStatus LLIOAddChain::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_ADD_CHAIN);
pump->addChain(mChain, mTimeout);
return STATUS_DONE;
}

View File

@ -82,6 +82,8 @@ bool LLSDRPCResponse::extractResponse(const LLSD& sd)
return rv;
}
static LLFastTimer::DeclareTimer FTM_SDRPC_RESPONSE("SDRPC Response");
// virtual
LLIOPipe::EStatus LLSDRPCResponse::process_impl(
const LLChannelDescriptors& channels,
@ -90,6 +92,7 @@ LLIOPipe::EStatus LLSDRPCResponse::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_SDRPC_RESPONSE);
PUMP_DEBUG;
LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
if(mIsError)
@ -178,6 +181,8 @@ bool LLSDRPCClient::call(
return true;
}
static LLFastTimer::DeclareTimer FTM_PROCESS_SDRPC_CLIENT("SDRPC Client");
// virtual
LLIOPipe::EStatus LLSDRPCClient::process_impl(
const LLChannelDescriptors& channels,
@ -186,6 +191,7 @@ LLIOPipe::EStatus LLSDRPCClient::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_SDRPC_CLIENT);
PUMP_DEBUG;
LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
if((STATE_NONE == mState) || (!pump))

View File

@ -97,6 +97,8 @@ void LLSDRPCServer::clearLock()
}
}
static LLFastTimer::DeclareTimer FTM_PROCESS_SDRPC_SERVER("SDRPC Server");
// virtual
LLIOPipe::EStatus LLSDRPCServer::process_impl(
const LLChannelDescriptors& channels,
@ -105,6 +107,7 @@ LLIOPipe::EStatus LLSDRPCServer::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_SDRPC_SERVER);
PUMP_DEBUG;
LLMemType m1(LLMemType::MTYPE_IO_SD_SERVER);
// lldebugs << "LLSDRPCServer::process_impl" << llendl;

View File

@ -270,6 +270,8 @@ LLIOPipe::EStatus LLURLRequest::handleError(
return status;
}
static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST("URL Request");
// virtual
LLIOPipe::EStatus LLURLRequest::process_impl(
const LLChannelDescriptors& channels,
@ -278,6 +280,7 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_URL_REQUEST);
PUMP_DEBUG;
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
//llinfos << "LLURLRequest::process_impl()" << llendl;
@ -288,6 +291,8 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
const S32 MIN_ACCUMULATION = 100000;
if(pump && (mDetail->mByteAccumulator > MIN_ACCUMULATION))
{
static LLFastTimer::DeclareTimer FTM_URL_ADJUST_TIMEOUT("Adjust Timeout");
LLFastTimer t(FTM_URL_ADJUST_TIMEOUT);
// This is a pretty sloppy calculation, but this
// tries to make the gross assumption that if data
// is coming in at 56kb/s, then this transfer will
@ -335,16 +340,30 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
{
PUMP_DEBUG;
LLIOPipe::EStatus status = STATUS_BREAK;
mDetail->mCurlRequest->perform();
static LLFastTimer::DeclareTimer FTM_URL_PERFORM("Perform");
{
LLFastTimer t(FTM_URL_PERFORM);
mDetail->mCurlRequest->perform();
}
while(1)
{
CURLcode result;
bool newmsg = mDetail->mCurlRequest->getResult(&result);
static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST_GET_RESULT("Get Result");
bool newmsg = false;
{
LLFastTimer t(FTM_PROCESS_URL_REQUEST_GET_RESULT);
newmsg = mDetail->mCurlRequest->getResult(&result);
}
if(!newmsg)
{
// keep processing
break;
}
mState = STATE_HAVE_RESPONSE;
context[CONTEXT_REQUEST][CONTEXT_TRANSFERED_BYTES] = mRequestTransferedBytes;
@ -370,7 +389,11 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
link.mChannels = LLBufferArray::makeChannelConsumer(
channels);
chain.push_back(link);
pump->respond(chain, buffer, context);
static LLFastTimer::DeclareTimer FTM_PROCESS_URL_PUMP_RESPOND("Pump Respond");
{
LLFastTimer t(FTM_PROCESS_URL_PUMP_RESPOND);
pump->respond(chain, buffer, context);
}
mCompletionCallback = NULL;
}
break;
@ -422,8 +445,11 @@ void LLURLRequest::initialize()
mResponseTransferedBytes = 0;
}
static LLFastTimer::DeclareTimer FTM_URL_REQUEST_CONFIGURE("URL Configure");
bool LLURLRequest::configure()
{
LLFastTimer t(FTM_URL_REQUEST_CONFIGURE);
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
bool rv = false;
S32 bytes = mDetail->mResponseBuffer->countAfter(
@ -624,6 +650,7 @@ static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user)
return header_len;
}
static LLFastTimer::DeclareTimer FTM_PROCESS_URL_EXTRACTOR("URL Extractor");
/**
* LLContextURLExtractor
*/
@ -635,6 +662,7 @@ LLIOPipe::EStatus LLContextURLExtractor::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_URL_EXTRACTOR);
PUMP_DEBUG;
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
// The destination host is in the context.
@ -713,6 +741,7 @@ void LLURLRequestComplete::responseStatus(LLIOPipe::EStatus status)
mRequestStatus = status;
}
static LLFastTimer::DeclareTimer FTM_PROCESS_URL_COMPLETE("URL Complete");
// virtual
LLIOPipe::EStatus LLURLRequestComplete::process_impl(
const LLChannelDescriptors& channels,
@ -721,6 +750,7 @@ LLIOPipe::EStatus LLURLRequestComplete::process_impl(
LLSD& context,
LLPumpIO* pump)
{
LLFastTimer t(FTM_PROCESS_URL_COMPLETE);
PUMP_DEBUG;
complete(channels, buffer);
return STATUS_OK;

View File

@ -394,16 +394,18 @@ bool LLXMLRPCTransaction::Impl::process()
}
}
const F32 MAX_PROCESSING_TIME = 0.05f;
LLTimer timer;
//const F32 MAX_PROCESSING_TIME = 0.05f;
//LLTimer timer;
while (mCurlRequest->perform() > 0)
mCurlRequest->perform();
/*while (mCurlRequest->perform() > 0)
{
if (timer.getElapsedTimeF32() >= MAX_PROCESSING_TIME)
{
return false;
}
}
}*/
while(1)
{