Merge pull request #3377

0b238b2 Use thread-local storage for LogPrint(category...) (Gavin Andresen)
962b1cf Fix infinite loop with LogPrint on Windows (Gavin Andresen)
This commit is contained in:
Wladimir J. van der Laan 2013-12-14 13:28:15 +01:00
commit 8a7606f35b
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
1 changed files with 30 additions and 27 deletions

View File

@ -242,17 +242,23 @@ int LogPrint(const char* category, const char* pszFormat, ...)
if (!fDebug) if (!fDebug)
return 0; return 0;
const vector<string>& categories = mapMultiArgs["-debug"]; // Give each thread quick access to -debug settings.
bool allCategories = count(categories.begin(), categories.end(), string("")); // This helps prevent issues debugging global destructors,
// where mapMultiArgs might be deleted before another
// Only look for categories, if not -debug/-debug=1 was passed, // global destructor calls LogPrint()
// as that implies every category should be logged. static boost::thread_specific_ptr<set<string> > ptrCategory;
if (!allCategories) if (ptrCategory.get() == NULL)
{ {
// Category was not found (not supplied via -debug=<category>) const vector<string>& categories = mapMultiArgs["-debug"];
if (find(categories.begin(), categories.end(), string(category)) == categories.end()) ptrCategory.reset(new set<string>(categories.begin(), categories.end()));
return 0; // thread_specific_ptr automatically deletes the set when the thread ends.
} }
const set<string>& setCategories = *ptrCategory.get();
// if not debugging everything and not debugging specific category, LogPrint does nothing.
if (setCategories.count(string("")) == 0 &&
setCategories.count(string(category)) == 0)
return 0;
} }
int ret = 0; // Returns total number of characters written int ret = 0; // Returns total number of characters written
@ -299,27 +305,24 @@ int LogPrint(const char* category, const char* pszFormat, ...)
#ifdef WIN32 #ifdef WIN32
if (fPrintToDebugger) if (fPrintToDebugger)
{ {
static CCriticalSection cs_OutputDebugStringF;
// accumulate and output a line at a time // accumulate and output a line at a time
static std::string buffer;
boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
buffer += vstrprintf(pszFormat, arg_ptr);
va_end(arg_ptr);
int line_start = 0, line_end;
while((line_end = buffer.find('\n', line_start)) != -1)
{ {
LOCK(cs_OutputDebugStringF); OutputDebugStringA(buffer.substr(line_start, line_end - line_start).c_str());
static std::string buffer; line_start = line_end + 1;
ret += line_end-line_start;
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
buffer += vstrprintf(pszFormat, arg_ptr);
va_end(arg_ptr);
int line_start = 0, line_end;
while((line_end = buffer.find('\n', line_start)) != -1)
{
OutputDebugStringA(buffer.substr(line_start, line_end - line_start).c_str());
line_start = line_end + 1;
ret += line_end-line_start;
}
buffer.erase(0, line_start);
} }
buffer.erase(0, line_start);
} }
#endif #endif
return ret; return ret;