From 48702b1ed9772c8a4b16520fdf56904b25c4a7ac Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Mon, 24 Sep 2012 16:55:34 +0200 Subject: [PATCH] Various stuff Comment fixes Added some more debug support, not used yet (linux/libcwd only), I used it, but won't commit the code that did. Pass time_time parameter from post2() to prepRequest; only used by mesh uploading at the moment. --- indra/aistatemachine/aicurl.cpp | 5 ++- indra/cwdebug/debug.cc | 63 +++++++++++++++++++++++++++ indra/cwdebug/debug.h | 72 +++++++++++++++++++++++++++++-- indra/llmessage/llcurlrequest.cpp | 4 +- 4 files changed, 137 insertions(+), 7 deletions(-) diff --git a/indra/aistatemachine/aicurl.cpp b/indra/aistatemachine/aicurl.cpp index 9d6627054..4cc845e68 100644 --- a/indra/aistatemachine/aicurl.cpp +++ b/indra/aistatemachine/aicurl.cpp @@ -1185,7 +1185,7 @@ void CurlEasyRequest::applyDefaultOptions(void) void CurlEasyRequest::finalizeRequest(std::string const& url) { llassert(!mRequestFinalized); - mResult = CURLE_FAILED_INIT; // General error code, the final code is written here in MultiHandle::check_run_count when msg is CURLMSG_DONE. + mResult = CURLE_FAILED_INIT; // General error code; the final result code is stored here by MultiHandle::check_run_count when msg is CURLMSG_DONE. lldebugs << url << llendl; #ifdef SHOW_ASSERT // Do a sanity check on the headers. @@ -1266,7 +1266,8 @@ void CurlEasyRequest::removed_from_multi_handle(AICurlEasyRequest_wat& curl_easy // CurlResponderBuffer static int const HTTP_REDIRECTS_DEFAULT = 10; -static S32 const CURL_REQUEST_TIMEOUT = 30; // Seconds per operation. +static S32 const CURL_REQUEST_TIMEOUT = 30; // The minimum value of the CURLOPT_TIMEOUT option (which is the maximum + // time in seconds that we allow a libcurl transfer operation to take). LLChannelDescriptors const CurlResponderBuffer::sChannels; diff --git a/indra/cwdebug/debug.cc b/indra/cwdebug/debug.cc index 06723f8ae..de14fa99f 100644 --- a/indra/cwdebug/debug.cc +++ b/indra/cwdebug/debug.cc @@ -49,6 +49,8 @@ namespace debug { #if CWDEBUG_LOCATION +ll_thread_local size_t BackTrace::S_number; + void BackTrace::dump_backtrace(void) const { for (int frame = 0; frame < frames(); ++frame) @@ -67,6 +69,67 @@ void BackTrace::dump_backtrace(void) const Dout(dc::finish, mangled_function_name); } } + +void BackTraces::store_trace(size_t trace) +{ + mBackTraces.push_back(trace); +} + +void BackTraces::remove_trace(size_t trace) +{ + trace_container_type::iterator iter = mBackTraces.begin(); + while (iter != mBackTraces.end()) + { + if (*iter == trace) + { + *iter = mBackTraces.back(); + mBackTraces.pop_back(); + return; + } + ++iter; + } + DoutFatal(dc::core, "Trace doesn't exist!"); +} + +void BackTraces::dump(void) const +{ + Dout(dc::backtrace|continued_cf, "Dump for (BackTraces*)" << (void*)this << " (" << mBackTraces.size() << " backtraces): "); + for (trace_container_type::const_iterator iter = mBackTraces.begin(); iter != mBackTraces.end(); ++iter) + { + Dout(dc::continued|nonewline_cf, *iter << ' '); + } + Dout(dc::finish, ""); +} + +BackTraceTracker::BackTraceTracker(BackTraces* back_traces) : mBackTraces(back_traces) +{ + BACKTRACE; + mTrace = BackTrace::S_number; + mBackTraces->store_trace(mTrace); +} + +BackTraceTracker::~BackTraceTracker() +{ + mBackTraces->remove_trace(mTrace); +} + +BackTraceTracker::BackTraceTracker(BackTraceTracker const& orig) : mBackTraces(orig.mBackTraces) +{ + BACKTRACE; + mTrace = BackTrace::S_number; + mBackTraces->store_trace(mTrace); +} + +BackTraceTracker& BackTraceTracker::operator=(BackTraceTracker const& orig) +{ + mBackTraces->remove_trace(mTrace); + mBackTraces = orig.mBackTraces; + BACKTRACE; + mTrace = BackTrace::S_number; + mBackTraces->store_trace(mTrace); + return *this; +} + #endif // CWDEBUG_LOCATION #if CWDEBUG_ALLOC && CWDEBUG_LOCATION diff --git a/indra/cwdebug/debug.h b/indra/cwdebug/debug.h index a52837411..1deed2efb 100644 --- a/indra/cwdebug/debug.h +++ b/indra/cwdebug/debug.h @@ -173,7 +173,9 @@ extern LL_COMMON_API fake_channel const notice; #include #if CWDEBUG_LOCATION #include // Needed for 'backtrace'. +#include "llpreprocessor.h" #endif +#include #define CWD_API __attribute__ ((visibility("default"))) @@ -273,6 +275,8 @@ class BackTrace { private: boost::shared_array M_buffer; int M_frames; + public: + static ll_thread_local size_t S_number; public: BackTrace(void** buffer, int frames) : M_buffer(new void* [frames]), M_frames(frames) { std::memcpy(M_buffer.get(), buffer, sizeof(void*) * frames); } @@ -299,19 +303,81 @@ extern pthread_mutex_t backtrace_mutex; using namespace debug; \ void* buffer[32]; \ int frames = backtrace(buffer, 32); \ - size_t size; \ { \ pthread_mutex_lock(&backtrace_mutex); \ backtraces.push_back(BackTrace(buffer, frames)); \ - size = backtraces.size(); \ + BackTrace::S_number = backtraces.size(); \ pthread_mutex_unlock(&backtrace_mutex); \ } \ - Dout(dc::backtrace, "Stored backtrace #" << size); \ + Dout(dc::backtrace, "Stored backtrace #" << BackTrace::S_number); \ } while(0) + +class LL_COMMON_API BackTraces { + private: + typedef std::vector trace_container_type; + trace_container_type mBackTraces; + + public: + void store_trace(size_t trace); + void remove_trace(size_t trace); + + void dump(void) const; +}; + +class LL_COMMON_API BackTraceTracker { + private: + BackTraces* mBackTraces; + size_t mTrace; + + public: + BackTraceTracker(BackTraces* back_traces); + ~BackTraceTracker(); + + BackTraceTracker(BackTraceTracker const&); + BackTraceTracker& operator=(BackTraceTracker const&); + + void dump(void) const { mBackTraces->dump(); } +}; + #else #define BACKTRACE do { } while(0) #endif // CWDEBUG_LOCATION +template +class LL_COMMON_API InstanceTracker { + private: + T const* mInstance; + static pthread_mutex_t sInstancesMutex; + static std::set sInstances; + static void remember(T const* instance) { pthread_mutex_lock(&sInstancesMutex); sInstances.insert(instance); pthread_mutex_unlock(&sInstancesMutex); } + static void forget(T const* instance) { pthread_mutex_lock(&sInstancesMutex); sInstances.erase(instance); pthread_mutex_unlock(&sInstancesMutex); } + public: + InstanceTracker(T const* instance) : mInstance(instance) { remember(mInstance); } + ~InstanceTracker() { forget(mInstance); } + InstanceTracker& operator=(InstanceTracker const& orig) { forget(mInstance); mInstance = orig.mInstance; remember(mInstance); return *this; } + static void dump(void); + private: + // Non-copyable. Instead of copying, call InstanceTracker(T const*) with the this pointer of the new instance. + InstanceTracker(InstanceTracker const& orig); +}; + +template +pthread_mutex_t InstanceTracker::sInstancesMutex = PTHREAD_MUTEX_INITIALIZER; + +template +std::set InstanceTracker::sInstances; + +template +void InstanceTracker::dump(void) +{ + pthread_mutex_lock(&sInstancesMutex); + for (typename std::set::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) + { + std::cout << *iter << std::endl; + } + pthread_mutex_unlock(&sInstancesMutex); +} + } // namespace debug //! Debugging macro. diff --git a/indra/llmessage/llcurlrequest.cpp b/indra/llmessage/llcurlrequest.cpp index 702904a42..9911335ee 100644 --- a/indra/llmessage/llcurlrequest.cpp +++ b/indra/llmessage/llcurlrequest.cpp @@ -95,7 +95,7 @@ bool Request::post2(std::string const& url, AIHTTPHeaders const& headers, std::s AICurlEasyRequest_wat buffered_easy_request_w(*buffered_easy_request->mCurlEasyRequest); AICurlResponderBuffer_wat buffer_w(*buffered_easy_request->mCurlEasyRequest); - buffer_w->prepRequest(buffered_easy_request_w, headers, responder); + buffer_w->prepRequest(buffered_easy_request_w, headers, responder, time_out); U32 bytes = data.size(); bool success = buffer_w->getInput()->append(buffer_w->sChannels.out(), (U8 const*)data.data(), bytes); @@ -125,7 +125,7 @@ bool Request::post3(std::string const& url, AIHTTPHeaders const& headers, LLSD c AICurlEasyRequest_wat buffered_easy_request_w(*buffered_easy_request->mCurlEasyRequest); AICurlResponderBuffer_wat buffer_w(*buffered_easy_request->mCurlEasyRequest); - buffer_w->prepRequest(buffered_easy_request_w, headers, responder); + buffer_w->prepRequest(buffered_easy_request_w, headers, responder, time_out); LLBufferStream buffer_stream(buffer_w->sChannels, buffer_w->getInput().get()); LLSDSerialize::toXML(data, buffer_stream);