mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-06 00:31:10 +01:00
4557 ndc thread local (#4682)
* fix(NestedDiagnosticContext): NDC crashed in multi-thread environment * fix(NestedDiagnosticContext): TestCase output redirect * enh(NestedDiagnosticContext): replace Poco::ThreadLocal to C++ standard thread_local so that objects can dtor when thread exit * enh(NestedDiagnosticContext): remove unused header files * chore(NDCTest): verify dump content * chore(NDCTest): use __FILE__ macro * fix(NDCTest): fix codeql warning * fix(NDCTest): remove temp code * enh(NestedDiagnosticContext): add nameOnly for dump --------- Co-authored-by: Alex Fabijanic <alex@pocoproject.org>
This commit is contained in:
parent
b85b49643e
commit
71a9bdafbd
@ -89,9 +89,11 @@ public:
|
|||||||
/// to the given stream. The entries are delimited by
|
/// to the given stream. The entries are delimited by
|
||||||
/// a newline.
|
/// a newline.
|
||||||
|
|
||||||
void dump(std::ostream& ostr, const std::string& delimiter) const;
|
void dump(std::ostream& ostr, const std::string& delimiter, bool nameOnly = false) const;
|
||||||
/// Dumps the stack (including line number and filenames)
|
/// Dumps the stack (including line number and filenames)
|
||||||
/// to the given stream.
|
/// to the given stream.
|
||||||
|
/// If nameOnly is false (default), the whole path to file is printed,
|
||||||
|
/// otherwise only the file name.
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
/// Clears the NDC stack.
|
/// Clears the NDC stack.
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "Poco/NestedDiagnosticContext.h"
|
#include "Poco/NestedDiagnosticContext.h"
|
||||||
#include "Poco/ThreadLocal.h"
|
#include "Poco/Path.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
@ -95,14 +95,26 @@ void NestedDiagnosticContext::dump(std::ostream& ostr) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NestedDiagnosticContext::dump(std::ostream& ostr, const std::string& delimiter) const
|
void NestedDiagnosticContext::dump(std::ostream& ostr, const std::string& delimiter, bool nameOnly) const
|
||||||
{
|
{
|
||||||
for (const auto& i: _stack)
|
for (auto it = _stack.begin(); it != _stack.end(); ++it)
|
||||||
{
|
{
|
||||||
ostr << i.info;
|
if (it != _stack.begin())
|
||||||
if (i.file)
|
{
|
||||||
ostr << " (in \"" << i.file << "\", line " << i.line << ")";
|
ostr << delimiter;
|
||||||
ostr << delimiter;
|
}
|
||||||
|
|
||||||
|
std::string file = it->file ? it->file : "";
|
||||||
|
if (nameOnly && !file.empty())
|
||||||
|
{
|
||||||
|
file = Path(file).getFileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
ostr << it->info;
|
||||||
|
if (!file.empty())
|
||||||
|
{
|
||||||
|
ostr << " (in \"" << file << "\", line " << it->line << ")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +127,7 @@ void NestedDiagnosticContext::clear()
|
|||||||
|
|
||||||
NestedDiagnosticContext& NestedDiagnosticContext::current()
|
NestedDiagnosticContext& NestedDiagnosticContext::current()
|
||||||
{
|
{
|
||||||
static NestedDiagnosticContext ndc;
|
static thread_local NestedDiagnosticContext ndc;
|
||||||
return ndc;
|
return ndc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,10 +12,18 @@
|
|||||||
#include "CppUnit/TestCaller.h"
|
#include "CppUnit/TestCaller.h"
|
||||||
#include "CppUnit/TestSuite.h"
|
#include "CppUnit/TestSuite.h"
|
||||||
#include "Poco/NestedDiagnosticContext.h"
|
#include "Poco/NestedDiagnosticContext.h"
|
||||||
|
#include "Poco/ActiveThreadPool.h"
|
||||||
|
#include "Poco/RunnableAdapter.h"
|
||||||
|
#include "Poco/Format.h"
|
||||||
|
#include "Poco/Path.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
using Poco::NDC;
|
using Poco::NDC;
|
||||||
|
using Poco::ActiveThreadPool;
|
||||||
|
using Poco::RunnableAdapter;
|
||||||
|
using Poco::Path;
|
||||||
|
|
||||||
|
|
||||||
NDCTest::NDCTest(const std::string& name): CppUnit::TestCase(name)
|
NDCTest::NDCTest(const std::string& name): CppUnit::TestCase(name)
|
||||||
@ -49,14 +57,39 @@ void NDCTest::testNDC()
|
|||||||
void NDCTest::testNDCScope()
|
void NDCTest::testNDCScope()
|
||||||
{
|
{
|
||||||
poco_ndc("item1");
|
poco_ndc("item1");
|
||||||
|
auto line1 = __LINE__ - 1;
|
||||||
assertTrue (NDC::current().depth() == 1);
|
assertTrue (NDC::current().depth() == 1);
|
||||||
|
|
||||||
{
|
{
|
||||||
poco_ndc("item2");
|
poco_ndc("item2");
|
||||||
|
auto line2 = __LINE__ - 1;
|
||||||
assertTrue (NDC::current().depth() == 2);
|
assertTrue (NDC::current().depth() == 2);
|
||||||
|
|
||||||
{
|
{
|
||||||
poco_ndc("item3");
|
poco_ndc("item3");
|
||||||
|
auto line3 = __LINE__ - 1;
|
||||||
assertTrue (NDC::current().depth() == 3);
|
assertTrue (NDC::current().depth() == 3);
|
||||||
NDC::current().dump(std::cout);
|
|
||||||
|
std::ostringstream ostr1;
|
||||||
|
NDC::current().dump(ostr1);
|
||||||
|
assertEqual (ostr1.str(), Poco::format(
|
||||||
|
"\"item1\" (in \"%s\", line %d)\n"
|
||||||
|
"\"item2\" (in \"%s\", line %d)\n"
|
||||||
|
"\"item3\" (in \"%s\", line %d)",
|
||||||
|
std::string(__FILE__), line1,
|
||||||
|
std::string(__FILE__), line2,
|
||||||
|
std::string(__FILE__), line3));
|
||||||
|
|
||||||
|
std::ostringstream ostr2;
|
||||||
|
NDC::current().dump(ostr2, "\n", true);
|
||||||
|
std::string fileName = Path(__FILE__).getFileName();
|
||||||
|
assertEqual(ostr2.str(), Poco::format(
|
||||||
|
"\"item1\" (in \"%s\", line %d)\n"
|
||||||
|
"\"item2\" (in \"%s\", line %d)\n"
|
||||||
|
"\"item3\" (in \"%s\", line %d)",
|
||||||
|
fileName, line1,
|
||||||
|
fileName, line2,
|
||||||
|
fileName, line3));
|
||||||
}
|
}
|
||||||
assertTrue (NDC::current().depth() == 2);
|
assertTrue (NDC::current().depth() == 2);
|
||||||
}
|
}
|
||||||
@ -64,6 +97,25 @@ void NDCTest::testNDCScope()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NDCTest::testNDCMultiThread()
|
||||||
|
{
|
||||||
|
ActiveThreadPool pool;
|
||||||
|
RunnableAdapter<NDCTest> ra(*this, &NDCTest::runInThread);
|
||||||
|
for (int i = 0; i < 1000; i++)
|
||||||
|
{
|
||||||
|
pool.start(ra);
|
||||||
|
}
|
||||||
|
pool.joinAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NDCTest::runInThread()
|
||||||
|
{
|
||||||
|
testNDC();
|
||||||
|
testNDCScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void NDCTest::setUp()
|
void NDCTest::setUp()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -80,6 +132,7 @@ CppUnit::Test* NDCTest::suite()
|
|||||||
|
|
||||||
CppUnit_addTest(pSuite, NDCTest, testNDC);
|
CppUnit_addTest(pSuite, NDCTest, testNDC);
|
||||||
CppUnit_addTest(pSuite, NDCTest, testNDCScope);
|
CppUnit_addTest(pSuite, NDCTest, testNDCScope);
|
||||||
|
CppUnit_addTest(pSuite, NDCTest, testNDCMultiThread);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ public:
|
|||||||
|
|
||||||
void testNDC();
|
void testNDC();
|
||||||
void testNDCScope();
|
void testNDCScope();
|
||||||
|
void testNDCMultiThread();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
@ -33,6 +34,7 @@ public:
|
|||||||
static CppUnit::Test* suite();
|
static CppUnit::Test* suite();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void runInThread();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user