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 {
|
||||
|
||||
//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
|
||||
void initCurl(void)
|
||||
{
|
||||
@@ -417,6 +431,39 @@ void setCAPath(std::string const& 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
|
||||
//==================================================================================
|
||||
|
||||
@@ -426,31 +473,13 @@ void setCAPath(std::string const& path)
|
||||
|
||||
namespace AICurlPrivate {
|
||||
|
||||
using AICurlInterface::Stats;
|
||||
|
||||
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
|
||||
// CURLOPT_DEBUGFUNCTION function.
|
||||
extern int debug_callback(CURL*, curl_infotype infotype, char* buf, size_t size, void* user_ptr);
|
||||
#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
|
||||
void handle_multi_error(CURLMcode code)
|
||||
{
|
||||
@@ -1175,6 +1204,7 @@ LLChannelDescriptors const BufferedCurlEasyRequest::sChannels;
|
||||
|
||||
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)
|
||||
@@ -1202,6 +1232,7 @@ BufferedCurlEasyRequest::~BufferedCurlEasyRequest()
|
||||
timed_out();
|
||||
}
|
||||
}
|
||||
--AICurlInterface::Stats::BufferedCurlEasyRequest_count;
|
||||
}
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
@@ -221,11 +238,14 @@ class AICurlEasyRequest {
|
||||
// 'new' never returned however and neither the constructor nor destructor of mBufferedCurlEasyRequest is called in this case.
|
||||
// This might throw AICurlNoEasyHandle.
|
||||
AICurlEasyRequest(void) :
|
||||
mBufferedCurlEasyRequest(new AICurlPrivate::ThreadSafeBufferedCurlEasyRequest) { }
|
||||
mBufferedCurlEasyRequest(new AICurlPrivate::ThreadSafeBufferedCurlEasyRequest) { AICurlInterface::Stats::AICurlEasyRequest_count++; }
|
||||
|
||||
public:
|
||||
// Update stats.
|
||||
~AICurlEasyRequest() { --AICurlInterface::Stats::AICurlEasyRequest_count; }
|
||||
|
||||
// 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.
|
||||
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.
|
||||
// Note that the external AICurlPrivate::BufferedCurlEasyRequestPtr needs its own locking, because
|
||||
// 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.
|
||||
// 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
|
||||
|
||||
@@ -249,6 +249,7 @@ AICurlEasyRequestStateMachine::AICurlEasyRequestStateMachine(void) :
|
||||
mTimer(NULL), mTotalDelayTimeout(AIHTTPTimeoutPolicy::getDebugSettingsCurlTimeout().getTotalDelay())
|
||||
{
|
||||
Dout(dc::statemachine, "Calling AICurlEasyRequestStateMachine(void) [" << (void*)this << "] [" << (void*)mCurlEasyRequest.get() << "]");
|
||||
AICurlInterface::Stats::AICurlEasyRequestStateMachine_count++;
|
||||
}
|
||||
|
||||
void AICurlEasyRequestStateMachine::setTotalDelayTimeout(F32 totalDelayTimeout)
|
||||
@@ -259,5 +260,6 @@ void AICurlEasyRequestStateMachine::setTotalDelayTimeout(F32 totalDelayTimeout)
|
||||
AICurlEasyRequestStateMachine::~AICurlEasyRequestStateMachine()
|
||||
{
|
||||
Dout(dc::statemachine, "Calling ~AICurlEasyRequestStateMachine() [" << (void*)this << "] [" << (void*)mCurlEasyRequest.get() << "]");
|
||||
--AICurlInterface::Stats::AICurlEasyRequestStateMachine_count;
|
||||
}
|
||||
|
||||
|
||||
@@ -111,20 +111,8 @@ class HTTPTimeout : public LLRefCount {
|
||||
|
||||
} // 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);
|
||||
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);
|
||||
void wakeUpCurlThread(void);
|
||||
@@ -248,7 +236,7 @@ class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEven
|
||||
// Always first call setErrorBuffer()!
|
||||
static inline CURLcode check_easy_code(CURLcode code)
|
||||
{
|
||||
Stats::easy_calls++;
|
||||
AICurlInterface::Stats::easy_calls++;
|
||||
if (code != CURLE_OK)
|
||||
handle_easy_error(code);
|
||||
return code;
|
||||
@@ -511,9 +499,11 @@ class ThreadSafeBufferedCurlEasyRequest : public AIThreadSafeSimple<BufferedCurl
|
||||
// Throws AICurlNoEasyHandle.
|
||||
ThreadSafeBufferedCurlEasyRequest(void) : mReferenceCount(0)
|
||||
{ new (ptr()) BufferedCurlEasyRequest;
|
||||
Dout(dc::curl, "Creating ThreadSafeBufferedCurlEasyRequest with this = " << (void*)this); }
|
||||
virtual ~ThreadSafeBufferedCurlEasyRequest()
|
||||
{ Dout(dc::curl, "Destructing ThreadSafeBufferedCurlEasyRequest with this = " << (void*)this); }
|
||||
Dout(dc::curl, "Creating ThreadSafeBufferedCurlEasyRequest with this = " << (void*)this);
|
||||
AICurlInterface::Stats::ThreadSafeBufferedCurlEasyRequest_count++; }
|
||||
~ThreadSafeBufferedCurlEasyRequest()
|
||||
{ Dout(dc::curl, "Destructing ThreadSafeBufferedCurlEasyRequest with this = " << (void*)this);
|
||||
--AICurlInterface::Stats::ThreadSafeBufferedCurlEasyRequest_count; }
|
||||
|
||||
private:
|
||||
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
|
||||
// when it certainly wasn't an error...
|
||||
if (ret)
|
||||
Stats::multi_calls++;
|
||||
AICurlInterface::Stats::multi_calls++;
|
||||
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)
|
||||
{
|
||||
DoutEntering(dc::curl, "AICurlInterface::Responder() with this = " << (void*)this);
|
||||
AICurlInterface::Stats::ResponderBase_count++;
|
||||
}
|
||||
|
||||
LLHTTPClient::ResponderBase::~ResponderBase()
|
||||
{
|
||||
DoutEntering(dc::curl, "AICurlInterface::ResponderBase::~ResponderBase() with this = " << (void*)this << "; mReferenceCount = " << mReferenceCount);
|
||||
llassert(mReferenceCount == 0);
|
||||
--AICurlInterface::Stats::ResponderBase_count;
|
||||
}
|
||||
|
||||
void LLHTTPClient::ResponderBase::setURL(std::string const& url)
|
||||
|
||||
Reference in New Issue
Block a user