Browse Source

Merge pull request #201 from paullouisageneau/fix-rtcinitlogger

Fix rtcInitLogger to prevent logging multiple times
Paul-Louis Ageneau 4 years ago
parent
commit
df62d6d51c
3 changed files with 29 additions and 13 deletions
  1. 2 1
      include/rtc/rtc.h
  2. 23 12
      src/capi.cpp
  3. 4 0
      src/log.cpp

+ 2 - 1
include/rtc/rtc.h

@@ -102,7 +102,8 @@ typedef void (RTC_API *rtcBufferedAmountLowCallbackFunc)(void *ptr);
 typedef void (RTC_API *rtcAvailableCallbackFunc)(void *ptr);
 typedef void (RTC_API *rtcAvailableCallbackFunc)(void *ptr);
 
 
 // Log
 // Log
-RTC_EXPORT void rtcInitLogger(rtcLogLevel level, rtcLogCallbackFunc cb); // NULL cb to log to stdout
+// NULL cb on the first call will log to stdout
+RTC_EXPORT void rtcInitLogger(rtcLogLevel level, rtcLogCallbackFunc cb);
 
 
 // User pointer
 // User pointer
 RTC_EXPORT void rtcSetUserPointer(int id, void *ptr);
 RTC_EXPORT void rtcSetUserPointer(int id, void *ptr);

+ 23 - 12
src/capi.cpp

@@ -195,12 +195,17 @@ template <typename F> int wrap(F func) {
 		return RTC_ERR_SUCCESS;                                                                    \
 		return RTC_ERR_SUCCESS;                                                                    \
 	})
 	})
 
 
-class plog_appender : public plog::IAppender {
+class plogAppender : public plog::IAppender {
 public:
 public:
-	plog_appender(rtcLogCallbackFunc cb = nullptr) { set_callback(cb); }
+	plogAppender(rtcLogCallbackFunc cb = nullptr) { setCallback(cb); }
 
 
-	void set_callback(rtcLogCallbackFunc cb) {
-		std::lock_guard lock(mutex);
+	plogAppender(plogAppender &&appender) : callback(nullptr) {
+		std::lock_guard lock(appender.callbackMutex);
+		std::swap(appender.callback, callback);
+	}
+
+	void setCallback(rtcLogCallbackFunc cb) {
+		std::lock_guard lock(callbackMutex);
 		callback = cb;
 		callback = cb;
 	}
 	}
 
 
@@ -215,7 +220,7 @@ public:
 #else
 #else
 		std::string str = formatted;
 		std::string str = formatted;
 #endif
 #endif
-		std::lock_guard lock(mutex);
+		std::lock_guard lock(callbackMutex);
 		if (callback)
 		if (callback)
 			callback(static_cast<rtcLogLevel>(record.getSeverity()), str.c_str());
 			callback(static_cast<rtcLogLevel>(record.getSeverity()), str.c_str());
 		else
 		else
@@ -224,18 +229,24 @@ public:
 
 
 private:
 private:
 	rtcLogCallbackFunc callback;
 	rtcLogCallbackFunc callback;
+	std::mutex callbackMutex;
 };
 };
 
 
 } // namespace
 } // namespace
 
 
 void rtcInitLogger(rtcLogLevel level, rtcLogCallbackFunc cb) {
 void rtcInitLogger(rtcLogLevel level, rtcLogCallbackFunc cb) {
-	static std::optional<plog_appender> appender;
-	if (appender)
-		appender->set_callback(cb);
-	else if (cb)
-		appender.emplace(plog_appender(cb));
-
-	InitLogger(static_cast<plog::Severity>(level), appender ? &appender.value() : nullptr);
+	static std::optional<plogAppender> appender;
+	const auto severity = static_cast<plog::Severity>(level);
+	std::lock_guard lock(mutex);
+	if (appender) {
+		appender->setCallback(cb);
+		InitLogger(severity, nullptr); // change the severity
+	} else if (cb) {
+		appender.emplace(plogAppender(cb));
+		InitLogger(severity, &appender.value());
+	} else {
+		InitLogger(severity, nullptr); // log to stdout
+	}
 }
 }
 
 
 void rtcSetUserPointer(int i, void *ptr) { setUserPointer(i, ptr); }
 void rtcSetUserPointer(int i, void *ptr) { setUserPointer(i, ptr); }

+ 4 - 0
src/log.cpp

@@ -24,6 +24,8 @@
 #include "plog/Log.h"
 #include "plog/Log.h"
 #include "plog/Logger.h"
 #include "plog/Logger.h"
 
 
+#include <mutex>
+
 namespace rtc {
 namespace rtc {
 
 
 void InitLogger(LogLevel level) { InitLogger(static_cast<plog::Severity>(level)); }
 void InitLogger(LogLevel level) { InitLogger(static_cast<plog::Severity>(level)); }
@@ -31,6 +33,8 @@ void InitLogger(LogLevel level) { InitLogger(static_cast<plog::Severity>(level))
 void InitLogger(plog::Severity severity, plog::IAppender *appender) {
 void InitLogger(plog::Severity severity, plog::IAppender *appender) {
 	static plog::ColorConsoleAppender<plog::TxtFormatter> consoleAppender;
 	static plog::ColorConsoleAppender<plog::TxtFormatter> consoleAppender;
 	static plog::Logger<0> *logger = nullptr;
 	static plog::Logger<0> *logger = nullptr;
+	static std::mutex mutex;
+	std::lock_guard lock(mutex);
 	if (!logger) {
 	if (!logger) {
 		logger = &plog::init(severity, appender ? appender : &consoleAppender);
 		logger = &plog::init(severity, appender ? appender : &consoleAppender);
 		PLOG_DEBUG << "Logger initialized";
 		PLOG_DEBUG << "Logger initialized";