WIP: Make curl thread code robust and flexible.

Conflicts:

	indra/llmessage/llcurl.cpp
	indra/llmessage/llcurl.h
	indra/newview/app_settings/settings.xml
	indra/newview/llappviewer.cpp
	indra/newview/llmeshrepository.cpp

Resolved:

	indra/llmessage/llcurl.cpp:

	  Basically removed (not used anyway)

	indra/llmessage/llcurl.h:

	  Basically removed (just includes aiculr.h now)

	indra/newview/app_settings/settings.xml:

	  CurlUseMultipleThreads was remvoved.
	  CurlMaximumNumberOfHandles and CurlRequestTimeOut
	  are still in there, but unused at the moment.

	indra/newview/llappviewer.cpp:

	  CurlMaximumNumberOfHandles and CurlRequestTimeOut
	  are unused at the moment.

	indra/newview/llmeshrepository.cpp:

	  Lock mSignal always (is unlocked inside wait()).
	  Use mSignal lock to see if we are waiting; remove mWaiting.
	  Return false from the MeshFetch functions iff we have to retry
	  a HTTP fetch. Catch the error exception thrown by getByteRange
	  instead of using it's return value (always returns true
	  anyway).
This commit is contained in:
Aleric Inglewood
2012-06-27 12:57:07 +02:00
parent 221e3908b9
commit 69ca6cd5b2
47 changed files with 4173 additions and 2502 deletions

View File

@@ -297,6 +297,20 @@ void LLApp::startErrorThread()
}
}
void LLApp::stopErrorThread()
{
LLApp::setStopped(); // Signal error thread that we stopped.
int count = 0;
while (mThreadErrorp && !mThreadErrorp->isStopped() && ++count < 100)
{
ms_sleep(10);
}
if (mThreadErrorp && !mThreadErrorp->isStopped())
{
llwarns << "Failed to stop Error Thread." << llendl;
}
}
void LLApp::setErrorHandler(LLAppErrorHandler handler)
{
LLApp::sErrorHandler = handler;

View File

@@ -260,6 +260,10 @@ protected:
* @ brief This method is called once as soon as logging is initialized.
*/
void startErrorThread();
/**
* @brief This method is called at the end, just prior to deinitializing curl.
*/
void stopErrorThread();
private:
void setupErrorHandling(); // Do platform-specific error-handling setup (signals, structured exceptions)

View File

@@ -194,17 +194,17 @@ void LLErrorThread::run()
if (LLApp::isError())
{
// The app is in an error state, run the application's error handler.
//llinfos << "thread_error - An error has occurred, running error callback!" << llendl;
Dout(dc::notice, "thread_error - An error has occurred, running error callback!");
// Run the error handling callback
LLApp::runErrorHandler();
}
else
{
// Everything is okay, a clean exit.
//llinfos << "thread_error - Application exited cleanly" << llendl;
Dout(dc::notice, "thread_error - Application exited cleanly");
}
//llinfos << "thread_error - Exiting" << llendl;
Dout(dc::notice, "thread_error - Exiting");
LLApp::sErrorThreadRunning = FALSE;
}

View File

@@ -110,6 +110,8 @@ public:
return mPriority > second.mPriority;
}
virtual void deleteRequest(); // Only method to delete a request
protected:
status_t setStatus(status_t newstatus)
{
@@ -125,7 +127,6 @@ public:
virtual bool processRequest() = 0; // Return true when request has completed
virtual void finishRequest(bool completed); // Always called from thread after request has completed or aborted
virtual void deleteRequest(); // Only method to delete a request
void setPriority(U32 pri)
{

View File

@@ -68,6 +68,7 @@ U32 ll_thread_local local_thread_ID = 0;
U32 LLThread::sIDIter = 0;
LLAtomicS32 LLThread::sCount = 0;
LLAtomicS32 LLThread::sRunning = 0;
LL_COMMON_API void assert_main_thread()
{
@@ -119,6 +120,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
// the critical area of the mSignal lock)].
lldebugs << "LLThread::staticRun() Exiting: " << name << llendl;
--sRunning; // Would be better to do this after joining with the thread, but we don't join :/
return NULL;
}
@@ -194,6 +196,7 @@ void LLThread::start()
// Set thread state to running
mStatus = RUNNING;
sRunning++;
apr_status_t status =
apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, tldata().mRootPool());
@@ -205,6 +208,7 @@ void LLThread::start()
}
else
{
--sRunning;
mStatus = STOPPED;
llwarns << "failed to start thread " << mName << llendl;
ll_apr_warn_status(status);
@@ -315,6 +319,16 @@ LL_COMMON_API bool is_main_thread(void) { return apr_os_thread_equal(main_thread
// The thread private handle to access the LLThreadLocalData instance.
apr_threadkey_t* LLThreadLocalData::sThreadLocalDataKey;
LLThreadLocalData::LLThreadLocalData(char const* name) : mCurlMultiHandle(NULL), mCurlErrorBuffer(NULL), mName(name)
{
}
LLThreadLocalData::~LLThreadLocalData()
{
delete mCurlMultiHandle;
delete [] mCurlErrorBuffer;
}
//static
void LLThreadLocalData::init(void)
{
@@ -348,7 +362,7 @@ void LLThreadLocalData::destroy(void* thread_local_data)
//static
void LLThreadLocalData::create(LLThread* threadp)
{
LLThreadLocalData* new_tld = new LLThreadLocalData;
LLThreadLocalData* new_tld = new LLThreadLocalData(threadp ? threadp->mName.c_str() : "main thread");
if (threadp)
{
threadp->mThreadLocalData = new_tld;

View File

@@ -57,6 +57,12 @@ class LLCondition;
#define ll_thread_local __thread
#endif
class LL_COMMON_API LLThreadLocalDataMember
{
public:
virtual ~LLThreadLocalDataMember() { };
};
class LL_COMMON_API LLThreadLocalData
{
private:
@@ -66,11 +72,18 @@ public:
// Thread-local memory pool.
LLAPRRootPool mRootPool;
LLVolatileAPRPool mVolatileAPRPool;
LLThreadLocalDataMember* mCurlMultiHandle; // Initialized by AICurlMultiHandle::getInstance
char* mCurlErrorBuffer; // NULL, or pointing to a buffer used by libcurl.
std::string mName; // "main thread", or a copy of LLThread::mName.
static void init(void);
static void destroy(void* thread_local_data);
static void create(LLThread* pthread);
static LLThreadLocalData& tldata(void);
private:
LLThreadLocalData(char const* name);
~LLThreadLocalData();
};
class LL_COMMON_API LLThread
@@ -78,6 +91,7 @@ class LL_COMMON_API LLThread
private:
static U32 sIDIter;
static LLAtomicS32 sCount;
static LLAtomicS32 sRunning;
public:
typedef enum e_thread_status
@@ -96,8 +110,9 @@ public:
static U32 currentID(); // Return ID of current thread
static S32 getCount() { return sCount; }
static S32 getRunning() { return sRunning; }
static void yield(); // Static because it can be called by the main thread, which doesn't have an LLThread data structure.
public:
// PAUSE / RESUME functionality. See source code for important usage notes.
// Called from MAIN THREAD.
@@ -204,6 +219,11 @@ protected:
apr_thread_mutex_t* mAPRMutexp;
mutable U32 mCount;
mutable U32 mLockingThread;
private:
// Disallow copy construction and assignment.
LLMutexBase(LLMutexBase const&);
LLMutexBase& operator=(LLMutexBase const&);
};
class LL_COMMON_API LLMutex : public LLMutexBase
@@ -223,10 +243,6 @@ public:
protected:
LLAPRPool mPool;
private:
// Disable copy construction, as si teh bomb!!! -SG
LLMutex(const LLMutex&);
LLMutex& operator=(const LLMutex&);
};
#if APR_HAS_THREADS
@@ -380,6 +396,16 @@ public:
mNoHoldersCondition.signal(); // Tell waiting readers, see [5].
mNoHoldersCondition.unlock(); // Release lock on mHoldersCount.
}
#if LL_DEBUG
// Really only intended for debugging purposes:
bool isLocked(void)
{
mNoHoldersCondition.lock();
bool res = mHoldersCount;
mNoHoldersCondition.unlock();
return res;
}
#endif
};
//============================================================================