Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: src/plugin/PluginDebug.h

Issue 29323611: Issue #1234, #2058 - Rewrite log facility, improving thread implementation
Patch Set: rebase to current tip Created Jan. 5, 2016, 2:52 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/plugin/PluginDebug.h
===================================================================
--- a/src/plugin/PluginDebug.h
+++ b/src/plugin/PluginDebug.h
@@ -18,17 +18,65 @@
#ifndef _PLUGIN_DEBUG_H_
#define _PLUGIN_DEBUG_H_
+#include <memory>
+#include <mutex>
+
+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)
@@ -51,4 +99,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_

Powered by Google App Engine
This is Rietveld