Moved and extended AICurlInterface::Stats
Moved AICurlPrivate::Stats to AICurlInterface::Stats and added several counters to keep track of the number of existing instances of respectively AICurlEasyRequest, AICurlEasyRequestStateMachine, BufferedCurlEasyRequest, ResponderBase and ThreadSafeBufferedCurlEasyRequest.
This commit is contained in:
@@ -289,6 +289,20 @@ static unsigned int encoded_version(int major, int minor, int patch)
|
|||||||
|
|
||||||
namespace AICurlInterface {
|
namespace AICurlInterface {
|
||||||
|
|
||||||
|
//static
|
||||||
|
LLAtomicU32 Stats::easy_calls;
|
||||||
|
LLAtomicU32 Stats::easy_errors;
|
||||||
|
LLAtomicU32 Stats::easy_init_calls;
|
||||||
|
LLAtomicU32 Stats::easy_init_errors;
|
||||||
|
LLAtomicU32 Stats::easy_cleanup_calls;
|
||||||
|
LLAtomicU32 Stats::multi_calls;
|
||||||
|
LLAtomicU32 Stats::multi_errors;
|
||||||
|
LLAtomicU32 Stats::AICurlEasyRequest_count;
|
||||||
|
LLAtomicU32 Stats::AICurlEasyRequestStateMachine_count;
|
||||||
|
LLAtomicU32 Stats::BufferedCurlEasyRequest_count;
|
||||||
|
LLAtomicU32 Stats::ResponderBase_count;
|
||||||
|
LLAtomicU32 Stats::ThreadSafeBufferedCurlEasyRequest_count;
|
||||||
|
|
||||||
// MAIN-THREAD
|
// MAIN-THREAD
|
||||||
void initCurl(void)
|
void initCurl(void)
|
||||||
{
|
{
|
||||||
@@ -417,6 +431,39 @@ void setCAPath(std::string const& path)
|
|||||||
CertificateAuthority_w->path = path;
|
CertificateAuthority_w->path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
void Stats::print(void)
|
||||||
|
{
|
||||||
|
int const easy_handles = easy_init_calls - easy_init_errors - easy_cleanup_calls;
|
||||||
|
llinfos_nf << "============ CURL STATS ============" << llendl;
|
||||||
|
llinfos_nf << " Curl multi errors/calls : " << std::dec << multi_errors << "/" << multi_calls << llendl;
|
||||||
|
llinfos_nf << " Curl easy errors/calls : " << std::dec << easy_errors << "/" << easy_calls << llendl;
|
||||||
|
llinfos_nf << " curl_easy_init() errors/calls : " << std::dec << easy_init_errors << "/" << easy_init_calls << llendl;
|
||||||
|
llinfos_nf << " Current number of curl easy handles: " << std::dec << easy_handles << llendl;
|
||||||
|
#ifdef DEBUG_CURLIO
|
||||||
|
llinfos_nf << " Current number of BufferedCurlEasyRequest objects: " << BufferedCurlEasyRequest_count << llendl;
|
||||||
|
llinfos_nf << " Current number of ThreadSafeBufferedCurlEasyRequest objects: " << ThreadSafeBufferedCurlEasyRequest_count << llendl;
|
||||||
|
llinfos_nf << " Current number of AICurlEasyRequest objects: " << AICurlEasyRequest_count << llendl;
|
||||||
|
llinfos_nf << " Current number of AICurlEasyRequestStateMachine objects: " << AICurlEasyRequestStateMachine_count << llendl;
|
||||||
|
#endif
|
||||||
|
llinfos_nf << " Current number of Responders: " << ResponderBase_count << llendl;
|
||||||
|
llinfos_nf << "========= END OF CURL STATS =========" << llendl;
|
||||||
|
// Leak tests.
|
||||||
|
// There is one easy handle per CurlEasyHandle, and BufferedCurlEasyRequest is derived from that.
|
||||||
|
// It is not allowed to create CurlEasyHandle (or CurlEasyRequest) directly, only by creating a BufferedCurlEasyRequest,
|
||||||
|
// therefore the number of existing easy handles must equal the number of BufferedCurlEasyRequest objects.
|
||||||
|
llassert(easy_handles == BufferedCurlEasyRequest_count);
|
||||||
|
// Even more strict, BufferedCurlEasyRequest may not be created directly either, only as
|
||||||
|
// base class of ThreadSafeBufferedCurlEasyRequest.
|
||||||
|
llassert(BufferedCurlEasyRequest_count == ThreadSafeBufferedCurlEasyRequest_count);
|
||||||
|
// Each AICurlEasyRequestStateMachine is responsible for exactly one easy handle.
|
||||||
|
llassert(easy_handles >= AICurlEasyRequest_count);
|
||||||
|
// Each AICurlEasyRequestStateMachine has one AICurlEasyRequest member.
|
||||||
|
llassert(AICurlEasyRequest_count >= AICurlEasyRequestStateMachine_count);
|
||||||
|
// AIFIXME: is this really always the case? And why?
|
||||||
|
llassert(easy_handles <= ResponderBase_count);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace AICurlInterface
|
} // namespace AICurlInterface
|
||||||
//==================================================================================
|
//==================================================================================
|
||||||
|
|
||||||
@@ -426,31 +473,13 @@ void setCAPath(std::string const& path)
|
|||||||
|
|
||||||
namespace AICurlPrivate {
|
namespace AICurlPrivate {
|
||||||
|
|
||||||
|
using AICurlInterface::Stats;
|
||||||
|
|
||||||
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
|
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
|
||||||
// CURLOPT_DEBUGFUNCTION function.
|
// CURLOPT_DEBUGFUNCTION function.
|
||||||
extern int debug_callback(CURL*, curl_infotype infotype, char* buf, size_t size, void* user_ptr);
|
extern int debug_callback(CURL*, curl_infotype infotype, char* buf, size_t size, void* user_ptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//static
|
|
||||||
LLAtomicU32 Stats::easy_calls;
|
|
||||||
LLAtomicU32 Stats::easy_errors;
|
|
||||||
LLAtomicU32 Stats::easy_init_calls;
|
|
||||||
LLAtomicU32 Stats::easy_init_errors;
|
|
||||||
LLAtomicU32 Stats::easy_cleanup_calls;
|
|
||||||
LLAtomicU32 Stats::multi_calls;
|
|
||||||
LLAtomicU32 Stats::multi_errors;
|
|
||||||
|
|
||||||
//static
|
|
||||||
void Stats::print(void)
|
|
||||||
{
|
|
||||||
llinfos_nf << "============ CURL STATS ============" << llendl;
|
|
||||||
llinfos_nf << " Curl multi errors/calls : " << std::dec << multi_errors << "/" << multi_calls << llendl;
|
|
||||||
llinfos_nf << " Curl easy errors/calls : " << std::dec << easy_errors << "/" << easy_calls << llendl;
|
|
||||||
llinfos_nf << " curl_easy_init() errors/calls : " << std::dec << easy_init_errors << "/" << easy_init_calls << llendl;
|
|
||||||
llinfos_nf << " Current number of curl easy handles: " << std::dec << (easy_init_calls - easy_init_errors - easy_cleanup_calls) << llendl;
|
|
||||||
llinfos_nf << "========= END OF CURL STATS =========" << llendl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// THREAD-SAFE
|
// THREAD-SAFE
|
||||||
void handle_multi_error(CURLMcode code)
|
void handle_multi_error(CURLMcode code)
|
||||||
{
|
{
|
||||||
@@ -1175,6 +1204,7 @@ LLChannelDescriptors const BufferedCurlEasyRequest::sChannels;
|
|||||||
|
|
||||||
BufferedCurlEasyRequest::BufferedCurlEasyRequest() : mRequestTransferedBytes(0), mResponseTransferedBytes(0), mBufferEventsTarget(NULL)
|
BufferedCurlEasyRequest::BufferedCurlEasyRequest() : mRequestTransferedBytes(0), mResponseTransferedBytes(0), mBufferEventsTarget(NULL)
|
||||||
{
|
{
|
||||||
|
AICurlInterface::Stats::BufferedCurlEasyRequest_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define llmaybeerrs lllog(LLApp::isRunning() ? LLError::LEVEL_ERROR : LLError::LEVEL_WARN, NULL, NULL, false, true)
|
#define llmaybeerrs lllog(LLApp::isRunning() ? LLError::LEVEL_ERROR : LLError::LEVEL_WARN, NULL, NULL, false, true)
|
||||||
@@ -1202,6 +1232,7 @@ BufferedCurlEasyRequest::~BufferedCurlEasyRequest()
|
|||||||
timed_out();
|
timed_out();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
--AICurlInterface::Stats::BufferedCurlEasyRequest_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferedCurlEasyRequest::timed_out(void)
|
void BufferedCurlEasyRequest::timed_out(void)
|
||||||
|
|||||||
@@ -127,6 +127,23 @@ class AICurlNoBody : public AICurlError {
|
|||||||
// Things defined in this namespace are called from elsewhere in the viewer code.
|
// Things defined in this namespace are called from elsewhere in the viewer code.
|
||||||
namespace AICurlInterface {
|
namespace AICurlInterface {
|
||||||
|
|
||||||
|
struct Stats {
|
||||||
|
static LLAtomicU32 easy_calls;
|
||||||
|
static LLAtomicU32 easy_errors;
|
||||||
|
static LLAtomicU32 easy_init_calls;
|
||||||
|
static LLAtomicU32 easy_init_errors;
|
||||||
|
static LLAtomicU32 easy_cleanup_calls;
|
||||||
|
static LLAtomicU32 multi_calls;
|
||||||
|
static LLAtomicU32 multi_errors;
|
||||||
|
static LLAtomicU32 AICurlEasyRequest_count;
|
||||||
|
static LLAtomicU32 AICurlEasyRequestStateMachine_count;
|
||||||
|
static LLAtomicU32 BufferedCurlEasyRequest_count;
|
||||||
|
static LLAtomicU32 ResponderBase_count;
|
||||||
|
static LLAtomicU32 ThreadSafeBufferedCurlEasyRequest_count;
|
||||||
|
|
||||||
|
static void print(void);
|
||||||
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Global functions.
|
// Global functions.
|
||||||
|
|
||||||
@@ -221,11 +238,14 @@ class AICurlEasyRequest {
|
|||||||
// 'new' never returned however and neither the constructor nor destructor of mBufferedCurlEasyRequest is called in this case.
|
// 'new' never returned however and neither the constructor nor destructor of mBufferedCurlEasyRequest is called in this case.
|
||||||
// This might throw AICurlNoEasyHandle.
|
// This might throw AICurlNoEasyHandle.
|
||||||
AICurlEasyRequest(void) :
|
AICurlEasyRequest(void) :
|
||||||
mBufferedCurlEasyRequest(new AICurlPrivate::ThreadSafeBufferedCurlEasyRequest) { }
|
mBufferedCurlEasyRequest(new AICurlPrivate::ThreadSafeBufferedCurlEasyRequest) { AICurlInterface::Stats::AICurlEasyRequest_count++; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// Update stats.
|
||||||
|
~AICurlEasyRequest() { --AICurlInterface::Stats::AICurlEasyRequest_count; }
|
||||||
|
|
||||||
// Used for storing this object in a standard container (see MultiHandle::add_easy_request).
|
// Used for storing this object in a standard container (see MultiHandle::add_easy_request).
|
||||||
AICurlEasyRequest(AICurlEasyRequest const& orig) : mBufferedCurlEasyRequest(orig.mBufferedCurlEasyRequest) { }
|
AICurlEasyRequest(AICurlEasyRequest const& orig) : mBufferedCurlEasyRequest(orig.mBufferedCurlEasyRequest) { AICurlInterface::Stats::AICurlEasyRequest_count++; }
|
||||||
|
|
||||||
// For the rest, only allow read operations.
|
// For the rest, only allow read operations.
|
||||||
AIThreadSafeSimple<AICurlPrivate::BufferedCurlEasyRequest>& operator*(void) const { llassert(mBufferedCurlEasyRequest.get()); return *mBufferedCurlEasyRequest; }
|
AIThreadSafeSimple<AICurlPrivate::BufferedCurlEasyRequest>& operator*(void) const { llassert(mBufferedCurlEasyRequest.get()); return *mBufferedCurlEasyRequest; }
|
||||||
@@ -271,11 +291,11 @@ class AICurlEasyRequest {
|
|||||||
// then it's OK to construct a AICurlEasyRequest from it.
|
// then it's OK to construct a AICurlEasyRequest from it.
|
||||||
// Note that the external AICurlPrivate::BufferedCurlEasyRequestPtr needs its own locking, because
|
// Note that the external AICurlPrivate::BufferedCurlEasyRequestPtr needs its own locking, because
|
||||||
// it's not thread-safe in itself.
|
// it's not thread-safe in itself.
|
||||||
AICurlEasyRequest(AICurlPrivate::BufferedCurlEasyRequestPtr const& ptr) : mBufferedCurlEasyRequest(ptr) { }
|
AICurlEasyRequest(AICurlPrivate::BufferedCurlEasyRequestPtr const& ptr) : mBufferedCurlEasyRequest(ptr) { AICurlInterface::Stats::AICurlEasyRequest_count++; }
|
||||||
|
|
||||||
// This one is obviously dangerous. It's for use only in MultiHandle::check_msg_queue.
|
// This one is obviously dangerous. It's for use only in MultiHandle::check_msg_queue.
|
||||||
// See also the long comment in BufferedCurlEasyRequest::finalizeRequest with regard to CURLOPT_PRIVATE.
|
// See also the long comment in BufferedCurlEasyRequest::finalizeRequest with regard to CURLOPT_PRIVATE.
|
||||||
explicit AICurlEasyRequest(AICurlPrivate::ThreadSafeBufferedCurlEasyRequest* ptr) : mBufferedCurlEasyRequest(ptr) { }
|
explicit AICurlEasyRequest(AICurlPrivate::ThreadSafeBufferedCurlEasyRequest* ptr) : mBufferedCurlEasyRequest(ptr) { AICurlInterface::Stats::AICurlEasyRequest_count++; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AICurlPrivate DONTUSE_AICurlPrivate
|
#define AICurlPrivate DONTUSE_AICurlPrivate
|
||||||
|
|||||||
@@ -249,6 +249,7 @@ AICurlEasyRequestStateMachine::AICurlEasyRequestStateMachine(void) :
|
|||||||
mTimer(NULL), mTotalDelayTimeout(AIHTTPTimeoutPolicy::getDebugSettingsCurlTimeout().getTotalDelay())
|
mTimer(NULL), mTotalDelayTimeout(AIHTTPTimeoutPolicy::getDebugSettingsCurlTimeout().getTotalDelay())
|
||||||
{
|
{
|
||||||
Dout(dc::statemachine, "Calling AICurlEasyRequestStateMachine(void) [" << (void*)this << "] [" << (void*)mCurlEasyRequest.get() << "]");
|
Dout(dc::statemachine, "Calling AICurlEasyRequestStateMachine(void) [" << (void*)this << "] [" << (void*)mCurlEasyRequest.get() << "]");
|
||||||
|
AICurlInterface::Stats::AICurlEasyRequestStateMachine_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AICurlEasyRequestStateMachine::setTotalDelayTimeout(F32 totalDelayTimeout)
|
void AICurlEasyRequestStateMachine::setTotalDelayTimeout(F32 totalDelayTimeout)
|
||||||
@@ -259,5 +260,6 @@ void AICurlEasyRequestStateMachine::setTotalDelayTimeout(F32 totalDelayTimeout)
|
|||||||
AICurlEasyRequestStateMachine::~AICurlEasyRequestStateMachine()
|
AICurlEasyRequestStateMachine::~AICurlEasyRequestStateMachine()
|
||||||
{
|
{
|
||||||
Dout(dc::statemachine, "Calling ~AICurlEasyRequestStateMachine() [" << (void*)this << "] [" << (void*)mCurlEasyRequest.get() << "]");
|
Dout(dc::statemachine, "Calling ~AICurlEasyRequestStateMachine() [" << (void*)this << "] [" << (void*)mCurlEasyRequest.get() << "]");
|
||||||
|
--AICurlInterface::Stats::AICurlEasyRequestStateMachine_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,20 +111,8 @@ class HTTPTimeout : public LLRefCount {
|
|||||||
|
|
||||||
} // namespace curlthread
|
} // namespace curlthread
|
||||||
|
|
||||||
struct Stats {
|
|
||||||
static LLAtomicU32 easy_calls;
|
|
||||||
static LLAtomicU32 easy_errors;
|
|
||||||
static LLAtomicU32 easy_init_calls;
|
|
||||||
static LLAtomicU32 easy_init_errors;
|
|
||||||
static LLAtomicU32 easy_cleanup_calls;
|
|
||||||
static LLAtomicU32 multi_calls;
|
|
||||||
static LLAtomicU32 multi_errors;
|
|
||||||
|
|
||||||
static void print(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
void handle_multi_error(CURLMcode code);
|
void handle_multi_error(CURLMcode code);
|
||||||
inline CURLMcode check_multi_code(CURLMcode code) { Stats::multi_calls++; if (code != CURLM_OK) handle_multi_error(code); return code; }
|
inline CURLMcode check_multi_code(CURLMcode code) { AICurlInterface::Stats::multi_calls++; if (code != CURLM_OK) handle_multi_error(code); return code; }
|
||||||
|
|
||||||
bool curlThreadIsRunning(void);
|
bool curlThreadIsRunning(void);
|
||||||
void wakeUpCurlThread(void);
|
void wakeUpCurlThread(void);
|
||||||
@@ -248,7 +236,7 @@ class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEven
|
|||||||
// Always first call setErrorBuffer()!
|
// Always first call setErrorBuffer()!
|
||||||
static inline CURLcode check_easy_code(CURLcode code)
|
static inline CURLcode check_easy_code(CURLcode code)
|
||||||
{
|
{
|
||||||
Stats::easy_calls++;
|
AICurlInterface::Stats::easy_calls++;
|
||||||
if (code != CURLE_OK)
|
if (code != CURLE_OK)
|
||||||
handle_easy_error(code);
|
handle_easy_error(code);
|
||||||
return code;
|
return code;
|
||||||
@@ -511,9 +499,11 @@ class ThreadSafeBufferedCurlEasyRequest : public AIThreadSafeSimple<BufferedCurl
|
|||||||
// Throws AICurlNoEasyHandle.
|
// Throws AICurlNoEasyHandle.
|
||||||
ThreadSafeBufferedCurlEasyRequest(void) : mReferenceCount(0)
|
ThreadSafeBufferedCurlEasyRequest(void) : mReferenceCount(0)
|
||||||
{ new (ptr()) BufferedCurlEasyRequest;
|
{ new (ptr()) BufferedCurlEasyRequest;
|
||||||
Dout(dc::curl, "Creating ThreadSafeBufferedCurlEasyRequest with this = " << (void*)this); }
|
Dout(dc::curl, "Creating ThreadSafeBufferedCurlEasyRequest with this = " << (void*)this);
|
||||||
virtual ~ThreadSafeBufferedCurlEasyRequest()
|
AICurlInterface::Stats::ThreadSafeBufferedCurlEasyRequest_count++; }
|
||||||
{ Dout(dc::curl, "Destructing ThreadSafeBufferedCurlEasyRequest with this = " << (void*)this); }
|
~ThreadSafeBufferedCurlEasyRequest()
|
||||||
|
{ Dout(dc::curl, "Destructing ThreadSafeBufferedCurlEasyRequest with this = " << (void*)this);
|
||||||
|
--AICurlInterface::Stats::ThreadSafeBufferedCurlEasyRequest_count; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LLAtomicU32 mReferenceCount;
|
LLAtomicU32 mReferenceCount;
|
||||||
|
|||||||
@@ -1527,7 +1527,7 @@ CURLMsg const* MultiHandle::info_read(int* msgs_in_queue) const
|
|||||||
// never increment Stats::multi_errors. However, lets just increment multi_calls
|
// never increment Stats::multi_errors. However, lets just increment multi_calls
|
||||||
// when it certainly wasn't an error...
|
// when it certainly wasn't an error...
|
||||||
if (ret)
|
if (ret)
|
||||||
Stats::multi_calls++;
|
AICurlInterface::Stats::multi_calls++;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -265,12 +265,14 @@ void LLHTTPClient::get(std::string const& url, LLSD const& query, ResponderPtr r
|
|||||||
LLHTTPClient::ResponderBase::ResponderBase(void) : mReferenceCount(0), mCode(CURLE_FAILED_INIT), mFinished(false)
|
LLHTTPClient::ResponderBase::ResponderBase(void) : mReferenceCount(0), mCode(CURLE_FAILED_INIT), mFinished(false)
|
||||||
{
|
{
|
||||||
DoutEntering(dc::curl, "AICurlInterface::Responder() with this = " << (void*)this);
|
DoutEntering(dc::curl, "AICurlInterface::Responder() with this = " << (void*)this);
|
||||||
|
AICurlInterface::Stats::ResponderBase_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLHTTPClient::ResponderBase::~ResponderBase()
|
LLHTTPClient::ResponderBase::~ResponderBase()
|
||||||
{
|
{
|
||||||
DoutEntering(dc::curl, "AICurlInterface::ResponderBase::~ResponderBase() with this = " << (void*)this << "; mReferenceCount = " << mReferenceCount);
|
DoutEntering(dc::curl, "AICurlInterface::ResponderBase::~ResponderBase() with this = " << (void*)this << "; mReferenceCount = " << mReferenceCount);
|
||||||
llassert(mReferenceCount == 0);
|
llassert(mReferenceCount == 0);
|
||||||
|
--AICurlInterface::Stats::ResponderBase_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLHTTPClient::ResponderBase::setURL(std::string const& url)
|
void LLHTTPClient::ResponderBase::setURL(std::string const& url)
|
||||||
|
|||||||
Reference in New Issue
Block a user