summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeslie Linden <leslie@lindenlab.com>2011-11-21 15:15:26 -0800
committerLeslie Linden <leslie@lindenlab.com>2011-11-21 15:15:26 -0800
commitabf39f788609f65d1b2b3ac1548f7146aa5c8584 (patch)
treedcaf1d6c1fdfffb4362b4aebb6eaa5f069345747
parent0071e6576f694f9f8ed1bc6537a6201c08dc79dd (diff)
Greatly reduced the number of memcpy operations done on the media plug-in message output pipe
by removing 's = s.substr()' type operations. The output string is now cleared via 's.clear()' when its entire contents have been pumped and the beginning of the data is stored as an index when necessary, rather than modifying the initial string. Reviewed by davep.
-rw-r--r--indra/llplugin/llpluginmessagepipe.cpp51
-rw-r--r--indra/llplugin/llpluginmessagepipe.h1
2 files changed, 35 insertions, 17 deletions
diff --git a/indra/llplugin/llpluginmessagepipe.cpp b/indra/llplugin/llpluginmessagepipe.cpp
index 8d13e38ad5..091e93ea4b 100644
--- a/indra/llplugin/llpluginmessagepipe.cpp
+++ b/indra/llplugin/llpluginmessagepipe.cpp
@@ -94,10 +94,10 @@ void LLPluginMessagePipeOwner::killMessagePipe(void)
LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket):
mInputMutex(gAPRPoolp),
mOutputMutex(gAPRPoolp),
+ mOutputStartIndex(0),
mOwner(owner),
mSocket(socket)
{
-
mOwner->setMessagePipe(this);
}
@@ -113,6 +113,14 @@ bool LLPluginMessagePipe::addMessage(const std::string &message)
{
// queue the message for later output
LLMutexLock lock(&mOutputMutex);
+
+ // If we're starting to use up too much memory, clear
+ if (mOutputStartIndex > 1024 * 1024)
+ {
+ mOutput = mOutput.substr(mOutputStartIndex);
+ mOutputStartIndex = 0;
+ }
+
mOutput += message;
mOutput += MESSAGE_DELIMITER; // message separator
@@ -165,35 +173,44 @@ bool LLPluginMessagePipe::pumpOutput()
if(mSocket)
{
apr_status_t status;
- apr_size_t size;
+ apr_size_t in_size, out_size;
LLMutexLock lock(&mOutputMutex);
- if(!mOutput.empty())
+
+ const char * output_data = &(mOutput.data()[mOutputStartIndex]);
+ if(*output_data != '\0')
{
// write any outgoing messages
- size = (apr_size_t)mOutput.size();
+ in_size = (apr_size_t) (mOutput.size() - mOutputStartIndex);
+ out_size = in_size;
setSocketTimeout(0);
// LL_INFOS("Plugin") << "before apr_socket_send, size = " << size << LL_ENDL;
- status = apr_socket_send(
- mSocket->getSocket(),
- (const char*)mOutput.data(),
- &size);
+ status = apr_socket_send(mSocket->getSocket(),
+ output_data,
+ &out_size);
// LL_INFOS("Plugin") << "after apr_socket_send, size = " << size << LL_ENDL;
- if(status == APR_SUCCESS)
+ if((status == APR_SUCCESS) || APR_STATUS_IS_EAGAIN(status))
{
- // success
- mOutput = mOutput.substr(size);
- }
- else if(APR_STATUS_IS_EAGAIN(status))
- {
- // Socket buffer is full...
- // remove the written part from the buffer and try again later.
- mOutput = mOutput.substr(size);
+ // Success or Socket buffer is full...
+
+ // If we've pumped the entire string, clear it
+ if (out_size == in_size)
+ {
+ mOutputStartIndex = 0;
+ mOutput.clear();
+ }
+ else
+ {
+ llassert(in_size > out_size);
+
+ // Remove the written part from the buffer and try again later.
+ mOutputStartIndex += out_size;
+ }
}
else if(APR_STATUS_IS_EOF(status))
{
diff --git a/indra/llplugin/llpluginmessagepipe.h b/indra/llplugin/llpluginmessagepipe.h
index beb942c0fe..059943cc90 100644
--- a/indra/llplugin/llpluginmessagepipe.h
+++ b/indra/llplugin/llpluginmessagepipe.h
@@ -86,6 +86,7 @@ protected:
std::string mInput;
LLMutex mOutputMutex;
std::string mOutput;
+ std::string::size_type mOutputStartIndex;
LLPluginMessagePipeOwner *mOwner;
LLSocket::ptr_t mSocket;