Index: src/plugin/PluginDebug.h |
=================================================================== |
--- a/src/plugin/PluginDebug.h |
+++ b/src/plugin/PluginDebug.h |
@@ -18,19 +18,66 @@ |
#ifndef _PLUGIN_DEBUG_H_ |
#define _PLUGIN_DEBUG_H_ |
+#include <memory> |
+#include <mutex> |
#include <string> |
+namespace Trace |
+{ |
+ /** |
+ */ |
+ struct Location |
+ { |
+ std::string prefixText; |
+ std::string postfixText; |
+ |
+ Location() // = default |
+ : prefixText(), postfixText() |
+ {}; |
+ |
+ Location(int id, int subId); |
+ |
+ Location(std::string postfixText) |
+ : prefixText(), postfixText(postfixText) |
+ {} |
+ |
+ Location(std::string prefixText, std::string postfixText) |
+ : prefixText(prefixText), postfixText(postfixText) |
+ {} |
+ }; |
+ |
+ void TextFixed(const std::string& description, Trace::Location location); |
+ void ErrorCode(DWORD errorCode, const std::string& description, Trace::Location location); |
+ void SystemException(const std::system_error& ex, const std::string& description, Trace::Location location); |
+} |
+ |
+// Cope with insufficient support on old toolsets |
+#if !defined(__func__) && defined(_MSC_VER) |
+#define __func__ __FUNCTION__ |
+#endif |
+ |
+// __LINE__ expands to an integer literal, not a string literal |
+// The stringify operator "#" applies only to arguments, not macro definitions |
+#define STRING_EXPAND(x) STRINGIFY(x) |
+#define STRINGIFY(x) #x |
+#define __LINE_STRING__ STRING_EXPAND(__LINE__) |
+#define HERE Trace::Location(__FILE__ ":" __LINE_STRING__) |
+#define HERE_F Trace::Location(__func__, __FILE__ ":" __LINE_STRING__) |
+ |
+#ifdef _DEBUG |
+#define TRACE(description, location) Trace::TextFixed(description, location) |
+#else |
+#define TRACE(a,b) |
+#endif |
+ |
class CPluginDebug |
{ |
- |
public: |
- static void DebugSystemException(const std::system_error& ex, int errorId, int errorSubid, const std::string& description); |
- |
#if (defined ENABLE_DEBUG_INFO) |
static void Debug(const std::string& text); |
static void Debug(const std::wstring& text); |
- static void DebugException(const std::exception& ex); |
- static void DebugErrorCode(DWORD errorCode, const std::string& error, DWORD processId=0, DWORD threadId=0); |
+ static void DebugException(const std::exception& ex, Trace::Location location); |
+ static void DebugErrorCode(DWORD errorCode, const std::string& error, Trace::Location location); |
#endif |
#if (defined ENABLE_DEBUG_RESULT) |
@@ -53,4 +100,59 @@ |
*/ |
std::wstring ToHexLiteral(const void*); |
+/* |
+ * Forward declaration. |
+ */ |
+class LogQueue; |
+ |
+/** |
+ * This class maintains a singleton LogQueue in existence. |
+ * |
+ * This class exists because it's not possible to use a static declaration for |
+ * 'std::thread' or any class that contains one, such as 'ActiveQueue'. |
+ * To appreciate of the origin of restriction, see |
+ * http://stackoverflow.com/questions/28746016/thread-join-does-not-return-when-called-in-global-var-destructor |
+ * In addition, we have no main() function to use for initialization, |
+ * since we're packaged as a COM class provider. |
+ * |
+ * As a substitute, we maintain a reference to the queue in each instance of |
+ * 'CPluginClass', the sole visible COM class, the one that implements the |
+ * BHO interface. |
+ * This class has the responsibility for managing the life cycle of the queue, |
+ * ensuring it exists whenever there's a reference to it. |
+ * The lifespan of instances of 'CPluginClass' encompasses the lifespans of any |
+ * other objects that the BHO uses, so it's sufficient to maintain a LogQueue |
+ * in existence with a reference in that class. |
+ * |
+ * The queue itself is accessible only to the logging functions; |
+ * it need not be visible externally. |
+ * Hence all this class requires is an opaque, forward declaration. |
+ * Mere instantiation of this class is sufficient to ensure we have a log queue. |
+ */ |
+class LogQueueReference |
+{ |
+ friend LogQueue; |
+ |
+ typedef std::shared_ptr<LogQueue> pointer; |
+ |
+ /** |
+ * The class-wide reference to the debug queue. |
+ */ |
+ static pointer queueMasterReference; |
+ |
+ /** |
+ * The instance reference to the debug queue. |
+ */ |
+ pointer queueReference; |
+ |
+ /** |
+ * Mutex to allow joint serialization of constructor/destructor calls. |
+ */ |
+ static std::mutex mutex; |
+ |
+public: |
+ LogQueueReference(); |
+ ~LogQueueReference(); |
+}; |
+ |
#endif // _PLUGIN_DEBUG_H_ |