Skip to content

Commit 8a7606f

Browse files
committed
Merge pull request #3377
0b238b2 Use thread-local storage for LogPrint(category...) (Gavin Andresen) 962b1cf Fix infinite loop with LogPrint on Windows (Gavin Andresen)
2 parents 6bfaf2a + 0b238b2 commit 8a7606f

File tree

1 file changed

+29
-26
lines changed

1 file changed

+29
-26
lines changed

src/util.cpp

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -242,17 +242,23 @@ int LogPrint(const char* category, const char* pszFormat, ...)
242242
if (!fDebug)
243243
return 0;
244244

245-
const vector<string>& categories = mapMultiArgs["-debug"];
246-
bool allCategories = count(categories.begin(), categories.end(), string(""));
247-
248-
// Only look for categories, if not -debug/-debug=1 was passed,
249-
// as that implies every category should be logged.
250-
if (!allCategories)
245+
// Give each thread quick access to -debug settings.
246+
// This helps prevent issues debugging global destructors,
247+
// where mapMultiArgs might be deleted before another
248+
// global destructor calls LogPrint()
249+
static boost::thread_specific_ptr<set<string> > ptrCategory;
250+
if (ptrCategory.get() == NULL)
251251
{
252-
// Category was not found (not supplied via -debug=<category>)
253-
if (find(categories.begin(), categories.end(), string(category)) == categories.end())
254-
return 0;
252+
const vector<string>& categories = mapMultiArgs["-debug"];
253+
ptrCategory.reset(new set<string>(categories.begin(), categories.end()));
254+
// thread_specific_ptr automatically deletes the set when the thread ends.
255255
}
256+
const set<string>& setCategories = *ptrCategory.get();
257+
258+
// if not debugging everything and not debugging specific category, LogPrint does nothing.
259+
if (setCategories.count(string("")) == 0 &&
260+
setCategories.count(string(category)) == 0)
261+
return 0;
256262
}
257263

258264
int ret = 0; // Returns total number of characters written
@@ -299,27 +305,24 @@ int LogPrint(const char* category, const char* pszFormat, ...)
299305
#ifdef WIN32
300306
if (fPrintToDebugger)
301307
{
302-
static CCriticalSection cs_OutputDebugStringF;
303-
304308
// accumulate and output a line at a time
305-
{
306-
LOCK(cs_OutputDebugStringF);
307-
static std::string buffer;
309+
static std::string buffer;
308310

309-
va_list arg_ptr;
310-
va_start(arg_ptr, pszFormat);
311-
buffer += vstrprintf(pszFormat, arg_ptr);
312-
va_end(arg_ptr);
311+
boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
313312

314-
int line_start = 0, line_end;
315-
while((line_end = buffer.find('\n', line_start)) != -1)
316-
{
317-
OutputDebugStringA(buffer.substr(line_start, line_end - line_start).c_str());
318-
line_start = line_end + 1;
319-
ret += line_end-line_start;
320-
}
321-
buffer.erase(0, line_start);
313+
va_list arg_ptr;
314+
va_start(arg_ptr, pszFormat);
315+
buffer += vstrprintf(pszFormat, arg_ptr);
316+
va_end(arg_ptr);
317+
318+
int line_start = 0, line_end;
319+
while((line_end = buffer.find('\n', line_start)) != -1)
320+
{
321+
OutputDebugStringA(buffer.substr(line_start, line_end - line_start).c_str());
322+
line_start = line_end + 1;
323+
ret += line_end-line_start;
322324
}
325+
buffer.erase(0, line_start);
323326
}
324327
#endif
325328
return ret;

0 commit comments

Comments
 (0)