Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: AlericInglewood/SingularityViewer
...
head fork: AlericInglewood/SingularityViewer
Checking mergeability… Don't worry, you can still create the pull request.
  • 2 commits
  • 3 files changed
  • 0 commit comments
  • 1 contributor
Commits on Mar 15, 2012
@AlericInglewood Allow AIThreadSafe*DC classes to be constructed with zero or one para…
…meter.

Also, allow AIThreadSafeSingleThreadDC objects to auto convert
to it's underlaying type, to assign that type and to write it
directly to an ostream.
8dd89dc
@AlericInglewood WIP: More brute force AIThreadSafe* wrapping d90e091
View
17 indra/llcommon/aithreadsafe.h
@@ -260,6 +260,8 @@ class AIThreadSafeDC : public AIThreadSafe<T>
public:
// Construct a wrapper around a default constructed object.
AIThreadSafeDC(void) { new (AIThreadSafe<T>::ptr()) T; }
+ // Allow an arbitrary parameter to be passed for construction.
+ template<typename T2> AIThreadSafeDC(T2 const& val) { new (AIThreadSafe<T>::ptr()) T(val); }
};
/**
@@ -480,10 +482,12 @@ class AIThreadSafeSimpleDC : public AIThreadSafeSimple<T>
public:
// Construct a wrapper around a default constructed object.
AIThreadSafeSimpleDC(void) { new (AIThreadSafeSimple<T>::ptr()) T; }
+ // Allow an arbitrary parameter to be passed for construction.
+ template<typename T2> AIThreadSafeSimpleDC(T2 const& val) { new (AIThreadSafeSimple<T>::ptr()) T(val); }
protected:
// For use by AIThreadSafeSimpleDCRootPool
- AIThreadSafeSimpleDC(LLAPRPool& parent) : AIThreadSafeSimple<T>(parent) { new (AIThreadSafeSimple<T>::ptr()) T; }
+ AIThreadSafeSimpleDC(LLAPRRootPool& parent) : AIThreadSafeSimple<T>(parent) { new (AIThreadSafeSimple<T>::ptr()) T; }
};
// Helper class for AIThreadSafeSimpleDCRootPool to assure initialization of
@@ -672,6 +676,17 @@ class AIThreadSafeSingleThreadDC : public AIThreadSafeSingleThread<T>
public:
// Construct a wrapper around a default constructed object.
AIThreadSafeSingleThreadDC(void) { new (AIThreadSafeSingleThread<T>::ptr()) T; }
+ // Allow an arbitrary parameter to be passed for construction.
+ template<typename T2> AIThreadSafeSingleThreadDC(T2 const& val) { new (AIThreadSafeSingleThread<T>::ptr()) T(val); }
+
+ // Allow assigning with T.
+ AIThreadSafeSingleThreadDC& operator=(T const& val) { AIThreadSafeSingleThread<T>::accessed(); *AIThreadSafeSingleThread<T>::ptr() = val; return *this; }
+ // Allow writing to an ostream.
+ friend std::ostream& operator<<(std::ostream& os, AIThreadSafeSingleThreadDC const& wrapped_val) { wrapped_val.accessed(); return os << *wrapped_val.ptr(); }
+
+ // Automatic conversion to T.
+ operator T&(void) { AIThreadSafeSingleThread<T>::accessed(); return *AIThreadSafeSingleThread<T>::ptr(); }
+ operator T const&(void) const { AIThreadSafeSingleThread<T>::accessed(); return *AIThreadSafeSingleThread<T>::ptr(); }
};
/**
View
175 indra/llmessage/llcurl.cpp
@@ -90,7 +90,7 @@ bool LLCurl::sNotQuitting = true;
F32 LLCurl::sCurlRequestTimeOut = 120.f; //seconds
S32 LLCurl::sMaxHandles = 256; //max number of handles, (multi handles and easy handles combined).
-void check_curl_code(CURLcode code)
+static void check_curl_code(CURLcode code)
{
if (code != CURLE_OK)
{
@@ -100,7 +100,7 @@ void check_curl_code(CURLcode code)
}
}
-void check_curl_multi_code(CURLMcode code)
+static void check_curl_multi_code(CURLMcode code)
{
if (code != CURLM_OK)
{
@@ -219,9 +219,7 @@ namespace boost
//////////////////////////////////////////////////////////////////////////////
-std::set<CURL*> LLCurl::Easy::sFreeHandles;
-std::set<CURL*> LLCurl::Easy::sActiveHandles;
-LLMutex* LLCurl::Easy::sHandleMutexp = NULL ;
+AIThreadSafeSimpleDC<LLCurl::Easy::Handles> LLCurl::Easy::sHandles;
//static
CURL* LLCurl::Easy::allocEasyHandle()
@@ -231,22 +229,22 @@ CURL* LLCurl::Easy::allocEasyHandle()
CURL* ret = NULL;
//*** Multi-threaded.
- LLMutexLock lock(sHandleMutexp) ;
+ AIAccess<Handles> handles_w(sHandles);
- if (sFreeHandles.empty())
+ if (handles_w->free.empty())
{
ret = LLCurl::newEasyHandle();
}
else
{
- ret = *(sFreeHandles.begin());
- sFreeHandles.erase(ret);
+ ret = *(handles_w->free.begin());
+ handles_w->free.erase(ret);
curl_easy_reset(ret);
}
if (ret)
{
- sActiveHandles.insert(ret);
+ handles_w->active.insert(ret);
}
return ret;
@@ -264,14 +262,15 @@ void LLCurl::Easy::releaseEasyHandle(CURL* handle)
}
//*** Multi-Threaded (logout only?)
- LLMutexLock lock(sHandleMutexp) ;
- if (sActiveHandles.find(handle) != sActiveHandles.end())
+ AIAccess<Handles> handles_w(sHandles);
+
+ if (handles_w->active.find(handle) != handles_w->active.end())
{
- sActiveHandles.erase(handle);
+ handles_w->active.erase(handle);
- if(sFreeHandles.size() < MAX_NUM_FREE_HANDLES)
+ if (handles_w->free.size() < MAX_NUM_FREE_HANDLES)
{
- sFreeHandles.insert(handle);
+ handles_w->free.insert(handle);
}
else
{
@@ -285,8 +284,8 @@ void LLCurl::Easy::releaseEasyHandle(CURL* handle)
}
LLCurl::Easy::Easy()
- : mHeaders(NULL),
- mCurlEasyHandle(NULL)
+ : mHeaders((curl_slist*)NULL),
+ mCurlEasyHandle((CURL*)NULL)
{
mErrorBuffer[0] = 0;
}
@@ -318,15 +317,20 @@ LLCurl::Easy::~Easy()
releaseEasyHandle(mCurlEasyHandle);
--gCurlEasyCount;
curl_slist_free_all(mHeaders);
- for_each(mStrings.begin(), mStrings.end(), DeletePointerArray());
- if (mResponder && LLCurl::getNotQuitting()) //aborted
+ {
+ AISTAccess<std::vector<char*> > strings_w(mStrings);
+ for_each(strings_w->begin(), strings_w->end(), DeletePointerArray());
+ }
+
+ AISTAccess<LLCurl::ResponderPtr> responder_w(mResponder);
+ if (*responder_w && LLCurl::getNotQuitting()) //aborted
{
std::string reason("Request timeout, aborted.") ;
- mResponder->completedRaw(408, //HTTP_REQUEST_TIME_OUT, timeout, abort
+ (*responder_w)->completedRaw(408, //HTTP_REQUEST_TIME_OUT, timeout, abort
reason, mChannels, mOutput);
}
- mResponder = NULL;
+ *responder_w = NULL;
}
void LLCurl::Easy::resetState()
@@ -339,18 +343,24 @@ void LLCurl::Easy::resetState()
mHeaders = NULL;
}
- mRequest.str("");
- mRequest.clear();
+ //mRequest.str("");
+ //mRequest.clear();
- mOutput.reset();
+ AISTAccess<LLIOPipe::buffer_ptr_t>(mOutput)->reset();
- mInput.str("");
- mInput.clear();
+ {
+ AISTAccess<std::stringstream> input_w(mInput);
+ input_w->str("");
+ input_w->clear();
+ }
mErrorBuffer[0] = 0;
- mHeaderOutput.str("");
- mHeaderOutput.clear();
+ {
+ AISTAccess<std::stringstream> header_output_w(mHeaderOutput);
+ header_output_w->str("");
+ header_output_w->clear();
+ }
}
void LLCurl::Easy::setErrorBuffer()
@@ -405,12 +415,16 @@ U32 LLCurl::Easy::report(CURLcode code)
setopt(CURLOPT_FRESH_CONNECT, TRUE);
}
- if (mResponder)
- {
- mResponder->completedRaw(responseCode, responseReason, mChannels, mOutput);
- mResponder = NULL;
+ {
+ AISTAccess<LLCurl::ResponderPtr> responder_w(mResponder);
+ LLCurl::ResponderPtr& responder = *responder_w;
+ if (responder)
+ {
+ responder->completedRaw(responseCode, responseReason, mChannels, mOutput);
+ responder = NULL;
+ }
}
-
+
resetState();
return responseCode;
}
@@ -439,7 +453,7 @@ void LLCurl::Easy::setoptString(CURLoption option, const std::string& value)
{
char* tstring = new char[value.length()+1];
strcpy(tstring, value.c_str());
- mStrings.push_back(tstring);
+ AISTAccess<std::vector<char*> >(mStrings)->push_back(tstring);
CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, tstring);
check_curl_code(result);
}
@@ -449,7 +463,7 @@ void LLCurl::Easy::slist_append(const char* str)
mHeaders = curl_slist_append(mHeaders, str);
}
-size_t curlReadCallback(char* data, size_t size, size_t nmemb, void* user_data)
+static size_t curlReadCallback(char* data, size_t size, size_t nmemb, void* user_data)
{
LLCurl::Easy* easy = (LLCurl::Easy*)user_data;
@@ -465,7 +479,7 @@ size_t curlReadCallback(char* data, size_t size, size_t nmemb, void* user_data)
return n;
}
-size_t curlWriteCallback(char* data, size_t size, size_t nmemb, void* user_data)
+static size_t curlWriteCallback(char* data, size_t size, size_t nmemb, void* user_data)
{
LLCurl::Easy* easy = (LLCurl::Easy*)user_data;
@@ -475,7 +489,7 @@ size_t curlWriteCallback(char* data, size_t size, size_t nmemb, void* user_data)
return n;
}
-size_t curlHeaderCallback(void* data, size_t size, size_t nmemb, void* user_data)
+static size_t curlHeaderCallback(void* data, size_t size, size_t nmemb, void* user_data)
{
LLCurl::Easy* easy = (LLCurl::Easy*)user_data;
@@ -499,8 +513,12 @@ void LLCurl::Easy::prepRequest(const std::string& url,
// Set the CURL options for either Socks or HTTP proxy
LLProxy::getInstance()->applyProxySettings(this);
- mOutput.reset(new LLBufferArray);
- mOutput->setThreaded(true);
+ {
+ AISTAccess<LLIOPipe::buffer_ptr_t> output_w(mOutput);
+ LLIOPipe::buffer_ptr_t& output(*output_w);
+ output.reset(new LLBufferArray);
+ output->setThreaded(true);
+ }
setopt(CURLOPT_WRITEFUNCTION, (void*)&curlWriteCallback);
setopt(CURLOPT_WRITEDATA, (void*)this);
@@ -528,7 +546,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
setoptString(CURLOPT_URL, url);
- mResponder = responder;
+ *AISTAccess<LLCurl::ResponderPtr>(mResponder) = responder;
if (!post)
{
@@ -594,30 +612,34 @@ void LLCurl::Multi::cleanup()
}
// Clean up active
- for(easy_active_list_t::iterator iter = mEasyActiveList.begin();
- iter != mEasyActiveList.end(); ++iter)
+ AISTAccess<easy_active_list_t> easy_active_list_w(mEasyActiveList);
+ for(easy_active_list_t::iterator iter = easy_active_list_w->begin(); iter != easy_active_list_w->end(); ++iter)
{
Easy* easy = *iter;
check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()));
delete easy;
}
- mEasyActiveList.clear();
- mEasyActiveMap.clear();
+ easy_active_list_w->clear();
+
+ AISTAccess<easy_active_map_t> easy_active_map_w(mEasyActiveMap);
+ easy_active_map_w->clear();
// Clean up freed
- for_each(mEasyFreeList.begin(), mEasyFreeList.end(), DeletePointer());
- mEasyFreeList.clear();
+ AISTAccess<easy_free_list_t> easy_free_list_w(mEasyFreeList);
+ for_each(easy_free_list_w->begin(), easy_free_list_w->end(), DeletePointer());
+ easy_free_list_w->clear();
- check_curl_multi_code(LLCurl::deleteMultiHandle(mCurlMultiHandle));
- mCurlMultiHandle = NULL ;
+ AISTAccess<CURLM*> curl_multi_handle_w(mCurlMultiHandle);
+ check_curl_multi_code(LLCurl::deleteMultiHandle(*curl_multi_handle_w));
+ *curl_multi_handle_w = NULL ;
delete mMutexp ;
mMutexp = NULL ;
delete mEasyMutexp ;
mEasyMutexp = NULL ;
- mQueued = 0 ;
- mState = STATE_COMPLETED;
+ *AISTAccess<S32>(mQueued) = 0;
+ *AIAccess<ePerformState>(mState) = STATE_COMPLETED;
--gCurlMultiCount;
@@ -650,11 +672,9 @@ void LLCurl::Multi::markDead()
void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state)
{
- lock() ;
- mState = state ;
- unlock() ;
+ *AIAccess<ePerformState>(mState) = state ;
- if(mState == STATE_READY)
+ if (state == STATE_READY)
{
(*AIAccess<LLCurlThread*>(LLCurl::getCurlThread()))->setPriority(mHandle, LLQueuedThread::PRIORITY_NORMAL);
}
@@ -662,7 +682,7 @@ void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state)
LLCurl::Multi::ePerformState LLCurl::Multi::getState()
{
- return mState;
+ return *AIAccess<ePerformState>(mState);
}
bool LLCurl::Multi::isCompleted()
@@ -683,7 +703,7 @@ bool LLCurl::Multi::waitToComplete()
return true ;
}
- bool completed = (STATE_COMPLETED == mState) ;
+ bool completed = (STATE_COMPLETED == *AIAccess<ePerformState>(mState)) ;
if(!completed)
{
(*AIAccess<LLCurlThread*>(LLCurl::getCurlThread()))->setPriority(mHandle, LLQueuedThread::PRIORITY_HIGH);
@@ -737,9 +757,9 @@ bool LLCurl::Multi::doPerform()
mQueued = q;
setState(STATE_COMPLETED) ;
- mIdleTimer.reset() ;
+ AISTAccess<LLFrameTimer>(mIdleTimer)->reset();
}
- else if(mIdleTimer.getElapsedTimeF32() > mIdleTimeOut) //idle for too long, remove it.
+ else if (AISTAccess<LLFrameTimer>(mIdleTimer)->getElapsedTimeF32() > mIdleTimeOut) //idle for too long, remove it.
{
dead = true ;
}
@@ -776,8 +796,9 @@ S32 LLCurl::Multi::process()
{
LLMutexLock lock(mEasyMutexp) ;
- easy_active_map_t::iterator iter = mEasyActiveMap.find(msg->easy_handle);
- if (iter != mEasyActiveMap.end())
+ AISTAccess<easy_active_map_t> easy_active_map_w(mEasyActiveMap);
+ easy_active_map_t::iterator iter = easy_active_map_w->find(msg->easy_handle);
+ if (iter != easy_active_map_w->end())
{
easy = iter->second;
}
@@ -812,21 +833,21 @@ LLCurl::Easy* LLCurl::Multi::allocEasy()
//*** Multi-threaded.
Easy* easy = 0;
- if (mEasyFreeList.empty())
+ if (AISTAccess<easy_free_list_t>(mEasyFreeList)->empty())
{
easy = Easy::getEasy();
}
else
{
LLMutexLock lock(mEasyMutexp) ;
- easy = *(mEasyFreeList.begin());
- mEasyFreeList.erase(easy);
+ easy = *(AISTAccess<easy_free_list_t>(mEasyFreeList)->begin());
+ AISTAccess<easy_free_list_t>(mEasyFreeList)->erase(easy);
}
if (easy)
{
LLMutexLock lock(mEasyMutexp) ;
- mEasyActiveList.insert(easy);
- mEasyActiveMap[easy->getCurlHandle()] = easy;
+ AISTAccess<easy_active_list_t>(mEasyActiveList)->insert(easy);
+ (*AISTAccess<easy_active_map_t>(mEasyActiveMap))[easy->getCurlHandle()] = easy;
}
return easy;
}
@@ -853,12 +874,12 @@ void LLCurl::Multi::easyFree(Easy* easy)
mEasyMutexp->lock() ;
}
- mEasyActiveList.erase(easy);
- mEasyActiveMap.erase(easy->getCurlHandle());
+ AISTAccess<easy_active_list_t>(mEasyActiveList)->erase(easy);
+ AISTAccess<easy_active_map_t>(mEasyActiveMap)->erase(easy->getCurlHandle());
- if (mEasyFreeList.size() < EASY_HANDLE_POOL_SIZE)
+ if (AISTAccess<easy_free_list_t>(mEasyFreeList)->size() < EASY_HANDLE_POOL_SIZE)
{
- mEasyFreeList.insert(easy);
+ AISTAccess<easy_free_list_t>(mEasyFreeList)->insert(easy);
if(mEasyMutexp)
{
@@ -1471,10 +1492,6 @@ void LLCurl::initClass(F32 curl_reuest_timeout, S32 max_number_handles, bool mul
#endif
*AIAccess<LLCurlThread*>(sCurlThread) = new LLCurlThread(multi_threaded) ;
- if(multi_threaded)
- {
- Easy::sHandleMutexp = new LLMutex;
- }
}
void LLCurl::cleanupClass()
@@ -1500,18 +1517,14 @@ void LLCurl::cleanupClass()
for_each(sSSLMutex.begin(), sSSLMutex.end(), DeletePointer());
#endif
- for (std::set<CURL*>::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter)
+ AIAccess<Easy::Handles> handles_w(Easy::sHandles);
+ for (std::set<CURL*>::iterator iter = handles_w->free.begin(); iter != handles_w->free.end(); ++iter)
{
CURL* curl = *iter;
LLCurl::deleteEasyHandle(curl);
}
-
- Easy::sFreeHandles.clear();
-
- delete Easy::sHandleMutexp ;
- Easy::sHandleMutexp = NULL ;
-
- llassert(Easy::sActiveHandles.empty());
+ handles_w->free.clear();
+ llassert(handles_w->active.empty());
}
//static
View
53 indra/llmessage/llcurl.h
@@ -128,10 +128,10 @@ class LLCurl
}
public: /* but not really -- don't touch this */
- U32 mReferenceCount;
+ AIThreadSafeSingleThreadDC<U32> mReferenceCount;
private:
- std::string mURL;
+ AIThreadSafeSingleThreadDC<std::string> mURL;
};
typedef boost::intrusive_ptr<Responder> ResponderPtr;
@@ -257,24 +257,27 @@ class LLCurl::Easy
friend class LLCurl;
friend class LLCurl::Multi;
- CURL* mCurlEasyHandle;
- struct curl_slist* mHeaders;
+ AIThreadSafeSingleThreadDC<CURL*> mCurlEasyHandle;
+ AIThreadSafeSingleThreadDC<curl_slist*> mHeaders;
- std::stringstream mRequest;
- LLChannelDescriptors mChannels;
- LLIOPipe::buffer_ptr_t mOutput;
- std::stringstream mInput;
- std::stringstream mHeaderOutput;
- char mErrorBuffer[CURL_ERROR_SIZE];
+ //AIThreadSafeSingleThreadDC<std::stringstream> mRequest;
+ AIThreadSafeSingleThreadDC<LLChannelDescriptors> mChannels;
+ AIThreadSafeSingleThreadDC<LLIOPipe::buffer_ptr_t> mOutput;
+ AIThreadSafeSingleThreadDC<std::stringstream> mInput;
+ AIThreadSafeSingleThreadDC<std::stringstream> mHeaderOutput;
+ char mErrorBuffer[CURL_ERROR_SIZE];
// Note: char*'s not strings since we pass pointers to curl
- std::vector<char*> mStrings;
+ AIThreadSafeSingleThreadDC<std::vector<char*> > mStrings;
- LLCurl::ResponderPtr mResponder;
+ AIThreadSafeSingleThreadDC<LLCurl::ResponderPtr> mResponder;
- static std::set<CURL*> sFreeHandles;
- static std::set<CURL*> sActiveHandles;
- static LLMutex* sHandleMutexp ;
+ struct Handles {
+ std::set<CURL*> free;
+ std::set<CURL*> active;
+ };
+
+ static AIThreadSafeSimpleDC<Handles> sHandles;
};
class LLCurl::Multi
@@ -320,30 +323,30 @@ class LLCurl::Multi
CURLMsg* info_read(S32* msgs_in_queue);
- S32 mQueued;
- S32 mErrorCount;
+ AIThreadSafeSingleThreadDC<S32> mQueued;
+ AIThreadSafeSingleThreadDC<S32> mErrorCount;
private:
void easyFree(LLCurl::Easy*);
void cleanup() ;
- CURLM* mCurlMultiHandle;
+ AIThreadSafeSingleThreadDC<CURLM*> mCurlMultiHandle;
typedef std::set<LLCurl::Easy*> easy_active_list_t;
- easy_active_list_t mEasyActiveList;
+ AIThreadSafeSingleThreadDC<easy_active_list_t> mEasyActiveList;
typedef std::map<CURL*, LLCurl::Easy*> easy_active_map_t;
- easy_active_map_t mEasyActiveMap;
+ AIThreadSafeSingleThreadDC<easy_active_map_t> mEasyActiveMap;
typedef std::set<LLCurl::Easy*> easy_free_list_t;
- easy_free_list_t mEasyFreeList;
+ AIThreadSafeSingleThreadDC<easy_free_list_t> mEasyFreeList;
- LLQueuedThread::handle_t mHandle ;
- ePerformState mState;
+ AIThreadSafeSingleThreadDC<LLQueuedThread::handle_t> mHandle ;
+ AIThreadSafeSimpleDC<ePerformState> mState;
AIThreadSafeSimpleDC<bool> mDead;
LLMutex* mMutexp ;
LLMutex* mEasyMutexp ;
- LLFrameTimer mIdleTimer ;
- F32 mIdleTimeOut;
+ AIThreadSafeSingleThreadDC<LLFrameTimer> mIdleTimer ;
+ AIThreadSafeSingleThreadDC<F32> mIdleTimeOut;
};
class LLCurlThread : public LLQueuedThread

No commit comments for this range

Something went wrong with that request. Please try again.