。宏定义如下:
[cpp]
#define poco_ndc(func) \
Poco::NDCScope _theNdcScope(#func, __LINE__, __FILE__)
#if defined(_DEBUG)
#define poco_ndc_dbg(func) \
Poco::NDCScope _theNdcScope(#func, __LINE__, __FILE__)
#else
#define poco_ndc_dbg(func)
#endif
#define poco_ndc(func) \
Poco::NDCScope _theNdcScope(#func, __LINE__, __FILE__)
#if defined(_DEBUG)
#define poco_ndc_dbg(func) \
Poco::NDCScope _theNdcScope(#func, __LINE__, __FILE__)
#else
#define poco_ndc_dbg(func)
#endif
NDCScope实现了诊断信息上下文的入栈出栈工作,它通过调用NestedDiagnosticContext类的静态函数current实现了此功能。其定义如下:
[cpp]
inline NDCScope::NDCScope(const std::string& info)
{
NestedDiagnosticContext::current().push(info);
}
inline NDCScope::NDCScope(const std::string& info, int line, const char* filename)
{
NestedDiagnosticContext::current().push(info, line, filename);
}
inline NDCScope::~NDCScope()
{
NestedDiagnosticContext::current().pop();
}
inline NDCScope::NDCScope(const std::string& info)
{
NestedDiagnosticContext::current().push(info);
}
inline NDCScope::NDCScope(const std::string& info, int line, const char* filename)
{
NestedDiagnosticContext::current().push(info, line, filename);
}
inline NDCScope::~NDCScope()
{
NestedDiagnosticContext::current().pop();
}
NestedDiagnosticContext类的current()是个静态函数,其定义如下:
[cpp]
namespace
{
static ThreadLocal ndc;
}
NestedDiagnosticContext& NestedDiagnosticContext::current()
{
return ndc.get();
}
namespace
{
static ThreadLocal ndc;
}
NestedDiagnosticContext& NestedDiagnosticContext::current()
{
return ndc.get();
}
而ThreadLocal是一个辅助类,用于获取线程对象的本地存储信息或者是主线程的本地存储信息。
[cpp]
template
class ThreadLocal
/// This template is used to declare type safe thread
/// local variables. It can basically be used like
/// a smart pointer class with the special feature
/// that it references a different object
/// in every thread. The underlying object will
/// be created when it is referenced for the first
/// time.
/// See the NestedDiagnosticContext class for an
/// example how to use this template.
/// Every thread only has access to its own
/// thread local data. There is no way for a thread
/// to access another thread's local data.
{
typedef TLSSlot Slot;
public:
ThreadLocal()
{
}
~ThreadLocal()
{
}
C* operator -> ()
{
return &get();
}
C& operator * ()
/// "Dereferences" the smart pointer and returns a reference
/// to the underlying data object. The reference can be used
/// to modify the object.
{
return get();
}
C& get()
/// Returns a reference to the underlying data object.
/// The reference can be used to modify the object.
{
TLSAbstractSlot*& p = ThreadLocalStorage::current().get(this);
if (!p) p = new Slot;
return static_cast(p)->value();
}
private:
ThreadLocal(const ThreadLocal&);
ThreadLocal& operator = (const ThreadLocal&);
};
template
class ThreadLocal
/// This template is used to declare type safe thread
/// local variables. It can basically be used like
/// a smart pointer class with the special feature
/// that it references a different object
/// in every thread. The underlying object will