From 82a3db85138c91df397fd820a3b5d1a0b5c21ef9 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Thu, 16 Nov 2017 16:27:47 +0000 Subject: Asynchronous logging added --- CMakeLists.txt | 1 + tests/activetest.cpp | 38 ++++++++++++++++++++++++++++++++++++++ tests/logtest.cpp | 6 +++--- tests/syncqueuetest.cpp | 3 +-- yage/CMakeLists.txt | 2 ++ yage/core/.#logmessage.h | 1 + yage/core/logger.cpp | 15 ++++++++++----- yage/core/logger.h | 4 ++++ yage/core/logsink.cpp | 2 +- yage/core/logsink.h | 8 ++++---- yage/util/active.cpp | 37 +++++++++++++++++++++++++++++++++++++ yage/util/active.h | 29 ++++++++++++++++++++++++++++- 12 files changed, 130 insertions(+), 16 deletions(-) create mode 100644 tests/activetest.cpp create mode 120000 yage/core/.#logmessage.h create mode 100644 yage/util/active.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b6826631..12711e71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,4 +49,5 @@ if($ENV{UNIT_TESTS}) make_test(logtest 1) make_test(threadtest 1) make_test(syncqueuetest 1) + make_test(activetest 1) endif() diff --git a/tests/activetest.cpp b/tests/activetest.cpp new file mode 100644 index 00000000..74e72f54 --- /dev/null +++ b/tests/activetest.cpp @@ -0,0 +1,38 @@ +#include + +#include + +using namespace yage; + +void print_random() +{ + std::cout << "hello world" + << "\n"; +} + +void print_h() +{ + std::cout << "Helllllllo" + << "\n"; +} + +void flush() +{ + std::cout << "flush" << std::endl; +} + +int main() +{ + auto a = Active::create(); + + a->send(print_random); + a->send(print_h); + a->send(flush); + + std::cout << std::endl; + + for (int i = 0; i < 1000000; i++) { + } + + std::cout << std::endl; +} diff --git a/tests/logtest.cpp b/tests/logtest.cpp index 359311ec..9536f00a 100644 --- a/tests/logtest.cpp +++ b/tests/logtest.cpp @@ -12,8 +12,8 @@ int main() { - gLog << "Hello World"; + gLog << "First message"; - gLog << "This is Yann"; - std::cout << "Hello\n"; + gLog << "Second Message"; + std::cout << "COUT\n"; } diff --git a/tests/syncqueuetest.cpp b/tests/syncqueuetest.cpp index cb9a920e..07167dc6 100644 --- a/tests/syncqueuetest.cpp +++ b/tests/syncqueuetest.cpp @@ -6,7 +6,7 @@ using namespace yage; SyncQueue queue; -std::atomic_int j; +std::atomic_int j(0); void push_to_queue1(int elements) { @@ -28,7 +28,6 @@ void push_to_queue2(int elements) int main() { - j.store(0); std::thread first(push_to_queue1, 100000); std::thread second(push_to_queue2, 100000); diff --git a/yage/CMakeLists.txt b/yage/CMakeLists.txt index 5a5674ec..83a6e054 100644 --- a/yage/CMakeLists.txt +++ b/yage/CMakeLists.txt @@ -3,12 +3,14 @@ cmake_policy(SET CMP0048 NEW) file(GLOB YAGE_CORE_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} core/*.cpp) file(GLOB YAGE_MATH_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} math/*.cpp) file(GLOB YAGE_PHYSICS_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} physics/*.cpp) +file(GLOB YAGE_UTIL_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} util/*.cpp) file(GLOB YAGE_CURRENT_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) set(YAGE_SOURCES ${YAGE_CORE_SOURCES} ${YAGE_PHYSICS_SOURCES} ${YAGE_MATH_SOURCES} + ${YAGE_UTIL_SOURCES} ${YAGE_CURRENT_SOURCES}) set(${PROJECT_NAME}_DIR diff --git a/yage/core/.#logmessage.h b/yage/core/.#logmessage.h new file mode 120000 index 00000000..c4ccefcf --- /dev/null +++ b/yage/core/.#logmessage.h @@ -0,0 +1 @@ +yannherklotz@yann-arch.2036:1510699559 \ No newline at end of file diff --git a/yage/core/logger.cpp b/yage/core/logger.cpp index 9fba2239..12a23dfc 100644 --- a/yage/core/logger.cpp +++ b/yage/core/logger.cpp @@ -17,7 +17,7 @@ namespace yage { -Logger::Logger() +Logger::Logger() : active_(Active::create()) { add(makeConsoleSink()); } @@ -31,9 +31,14 @@ void Logger::flush(const LogMessage *msg) { std::string asString(msg->buffer_.str()); - for (auto &&sink : sinks_) { - sink.write(msg->meta_, asString); - } + auto &&sinks = sinks_; + auto &&meta = msg->meta_; + + active_->send([=] { + for (auto &&sink : sinks) { + sink.write(meta, asString); + } + }); } void Logger::add(const LogSink &sink) @@ -45,7 +50,7 @@ void Logger::remove(const LogSink &sink) { auto it = std::find(std::begin(sinks_), std::end(sinks_), sink); - if(it != std::end(sinks_)) { + if (it != std::end(sinks_)) { sinks_.erase(it); } } diff --git a/yage/core/logger.h b/yage/core/logger.h index 2c70fd04..30b06b98 100644 --- a/yage/core/logger.h +++ b/yage/core/logger.h @@ -9,6 +9,9 @@ #ifndef YAGE_CORE_LOGGER_H #define YAGE_CORE_LOGGER_H +#include + +#include #include #include @@ -34,6 +37,7 @@ public: private: std::vector sinks_; + std::unique_ptr active_; }; } // namespace yage diff --git a/yage/core/logsink.cpp b/yage/core/logsink.cpp index 987a260d..a8f4d7b4 100644 --- a/yage/core/logsink.cpp +++ b/yage/core/logsink.cpp @@ -34,7 +34,7 @@ bool LogSink::operator==(const LogSink &sink) return (wrapper_.get() == sink.wrapper_.get()); } -void LogSink::write(const LogMessage::Meta &meta, const std::string &msg) +void LogSink::write(const LogMessage::Meta &meta, const std::string &msg) const { wrapper_->write(meta, msg); } diff --git a/yage/core/logsink.h b/yage/core/logsink.h index f18a6d37..526c862e 100644 --- a/yage/core/logsink.h +++ b/yage/core/logsink.h @@ -30,7 +30,7 @@ public: LogSink &operator=(LogSink &&sink); bool operator==(const LogSink &sink); - void write(const LogMessage::Meta &meta, const std::string &msg); + void write(const LogMessage::Meta &meta, const std::string &msg) const; private: struct Concept { @@ -38,7 +38,7 @@ private: virtual Concept *clone() const = 0; virtual void write(const LogMessage::Meta &meta, - const std::string &msg) = 0; + const std::string &msg) const = 0; }; template @@ -46,7 +46,7 @@ private: Model(T impl_i); virtual Concept *clone() const override; virtual void write(const LogMessage::Meta &meta, - const std::string &msg) override; + const std::string &msg) const override; T impl; }; @@ -79,7 +79,7 @@ LogSink::Concept *LogSink::Model::clone() const template void LogSink::Model::write(const LogMessage::Meta &meta, - const std::string &msg) + const std::string &msg) const { impl(meta, msg); } diff --git a/yage/util/active.cpp b/yage/util/active.cpp new file mode 100644 index 00000000..13e7fc38 --- /dev/null +++ b/yage/util/active.cpp @@ -0,0 +1,37 @@ +#include "active.h" + +namespace yage +{ + +Active::Active() : running_(true) {} + +Active::~Active() +{ + send([this] { running_ = false; }); + thread_.join(); +} + +std::unique_ptr Active::create() +{ + std::unique_ptr result(new Active); + + result->thread_ = std::thread(&Active::run, result.get()); + + return result; +} + +void Active::send(Callback message) +{ + queue_.push(message); +} + +void Active::run() +{ + Callback fn; + while (running_) { + queue_.pop(fn); + fn(); + } +} + +} // namespace yage diff --git a/yage/util/active.h b/yage/util/active.h index 877ab75e..ca8d30ad 100644 --- a/yage/util/active.h +++ b/yage/util/active.h @@ -1,11 +1,38 @@ #ifndef YAGE_UTIL_ACTIVE_H #define YAGE_UTIL_ACTIVE_H +#include "syncqueue.h" + +#include +#include +#include + +namespace yage +{ + class Active { public: + typedef std::function Callback; + + Active(const Active &) = delete; + Active &operator=(const Active &) = delete; + + ~Active(); + + static std::unique_ptr create(); + + void send(Callback message); + +private: Active(); - virtual ~Active(); + void run(); + + bool running_; + SyncQueue queue_; + std::thread thread_; }; +} // namespace yage + #endif -- cgit