From 6c7793d47be9776f532fb86bb51011a7bf6afb83 Mon Sep 17 00:00:00 2001 From: gabi Date: Fri, 10 Oct 2014 02:45:23 +0300 Subject: [PATCH] Modified sinks to be templates with Mutex param to support single threaded sinks --- include/c11log/sinks/async_sink.h | 38 +++++++++++++--------- include/c11log/sinks/base_sink.h | 12 +++++-- include/c11log/sinks/file_sinks.h | 53 +++++++++++++++++-------------- include/c11log/sinks/null_sink.h | 6 ++-- 4 files changed, 64 insertions(+), 45 deletions(-) diff --git a/include/c11log/sinks/async_sink.h b/include/c11log/sinks/async_sink.h index 49640995..cedb31ee 100644 --- a/include/c11log/sinks/async_sink.h +++ b/include/c11log/sinks/async_sink.h @@ -17,8 +17,8 @@ namespace c11log namespace sinks { - -class async_sink : public base_sink +template +class async_sink : public base_sink { public: using q_type = details::blocking_queue; @@ -54,28 +54,30 @@ private: /////////////////////////////////////////////////////////////////////////////// // async_sink class implementation /////////////////////////////////////////////////////////////////////////////// - -inline c11log::sinks::async_sink::async_sink(const q_type::size_type max_queue_size) +template +inline c11log::sinks::async_sink::async_sink(const q_type::size_type max_queue_size) :_sinks(), _active(true), _q(max_queue_size), _back_thread(&async_sink::_thread_loop, this) {} -inline c11log::sinks::async_sink::~async_sink() +template +inline c11log::sinks::async_sink::~async_sink() { _shutdown(); } - -inline void c11log::sinks::async_sink::_sink_it(const details::log_msg& msg) +template +inline void c11log::sinks::async_sink::_sink_it(const details::log_msg& msg) { if(!_active || msg.formatted.empty()) return; _q.push(msg); } -inline void c11log::sinks::async_sink::_thread_loop() +template +inline void c11log::sinks::async_sink::_thread_loop() { static std::chrono::seconds pop_timeout { 1 }; while (_active) @@ -93,23 +95,27 @@ inline void c11log::sinks::async_sink::_thread_loop() } } -inline void c11log::sinks::async_sink::add_sink(logger::sink_ptr sink) +template +inline void c11log::sinks::async_sink::add_sink(logger::sink_ptr sink) { _sinks.push_back(sink); } -inline void c11log::sinks::async_sink::remove_sink(logger::sink_ptr sink) +template +inline void c11log::sinks::async_sink::remove_sink(logger::sink_ptr sink) { _sinks.erase(std::remove(_sinks.begin(), _sinks.end(), sink), _sinks.end()); } - -inline c11log::sinks::async_sink::q_type& c11log::sinks::async_sink::q() +/* +template +inline c11log::sinks::async_sink::q_type& c11log::sinks::async_sink::q() { return _q; -} +}*/ -inline void c11log::sinks::async_sink::shutdown(const std::chrono::milliseconds& timeout) +template +inline void c11log::sinks::async_sink::shutdown(const std::chrono::milliseconds& timeout) { if(timeout > std::chrono::milliseconds::zero()) { @@ -122,7 +128,9 @@ inline void c11log::sinks::async_sink::shutdown(const std::chrono::milliseconds& _shutdown(); } -inline void c11log::sinks::async_sink::_shutdown() + +template +inline void c11log::sinks::async_sink::_shutdown() { std::lock_guard guard(_shutdown_mutex); if(_active) diff --git a/include/c11log/sinks/base_sink.h b/include/c11log/sinks/base_sink.h index 593cb9b7..f880bc23 100644 --- a/include/c11log/sinks/base_sink.h +++ b/include/c11log/sinks/base_sink.h @@ -1,20 +1,23 @@ #pragma once #include +#include #include - +#include "isink.h" #include "../formatter.h" #include "../common_types.h" #include "../details/log_msg.h" + namespace c11log { namespace sinks { -class base_sink +template +class base_sink:public isink { public: - base_sink(): _enabled(true) {} + base_sink():_mutex(), _enabled(true) {} virtual ~base_sink() = default; base_sink(const base_sink&) = delete; @@ -24,6 +27,7 @@ public: { if (_enabled) { + std::lock_guard lock(_mutex); _sink_it(msg); } }; @@ -40,7 +44,9 @@ public: protected: virtual void _sink_it(const details::log_msg& msg) = 0; + Mutex _mutex; std::atomic _enabled; + }; diff --git a/include/c11log/sinks/file_sinks.h b/include/c11log/sinks/file_sinks.h index 60791b73..bcbb55bc 100644 --- a/include/c11log/sinks/file_sinks.h +++ b/include/c11log/sinks/file_sinks.h @@ -3,48 +3,50 @@ #include #include #include -#include #include "base_sink.h" +#include +#include "../details/null_mutex.h" #include "../details/flush_helper.h" #include "../details/blocking_queue.h" + namespace c11log { namespace sinks { /* -* Thread safe, trivial file sink with single file as target +* Trivial file sink with single file as target */ -class simple_file_sink : public base_sink +template +class simple_file_sink : public base_sink { public: explicit simple_file_sink(const std::string &filename, - const std::string& extension, - const std::size_t flush_every=0) - : _mutex(), - _ofstream(filename + "." + extension, std::ofstream::binary|std::ofstream::app), - _flush_helper(flush_every) + const std::size_t flush_every=0): + _ofstream(filename, std::ofstream::binary|std::ofstream::app), + _flush_helper(flush_every) { } protected: void _sink_it(const details::log_msg& msg) override { - std::lock_guard lock(_mutex); _flush_helper.write(msg.formatted, _ofstream); } private: - std::mutex _mutex; std::ofstream _ofstream; details::file_flush_helper _flush_helper; }; +typedef simple_file_sink simple_file_sink_mt; +typedef simple_file_sink simple_file_sink_st; /* - * Thread safe, rotating file sink based on size + * Rotating file sink based on size */ -class rotating_file_sink : public base_sink +template +class rotating_file_sink : public base_sink { public: rotating_file_sink(const std::string &base_filename, const std::string &extension, @@ -55,7 +57,6 @@ public: _max_size(max_size), _max_files(max_files), _current_size(0), - _mutex(), _ofstream(_calc_filename(_base_filename, 0, _extension), std::ofstream::binary), _flush_helper(flush_every) { @@ -64,8 +65,6 @@ public: protected: void _sink_it(const details::log_msg& msg) override { - std::lock_guard lock(_mutex); - _current_size += msg.formatted.size(); if (_current_size > _max_size) { @@ -89,10 +88,13 @@ private: // Rotate old files: - // log.n-1.txt -> log.n.txt - // log n-2.txt -> log.n-1.txt - // ... // log.txt -> log.1.txt + // log.n-1.txt -> log.n.txt + // log.n-2.txt -> log.n-1.txt + // log.n-3.txt ->.. + // log.n.txt -> log.txt + + void _rotate() { _ofstream.close(); @@ -112,15 +114,18 @@ private: std::size_t _max_size; std::size_t _max_files; std::size_t _current_size; - std::mutex _mutex; std::ofstream _ofstream; details::file_flush_helper _flush_helper; }; +typedef rotating_file_sink rotating_file_sink_mt; +typedef rotating_file_sinkrotating_file_sink_st; + /* - * Thread safe, rotating file sink based on date. rotates at midnight + * Rotating file sink based on date. rotates at midnight */ -class daily_file_sink:public base_sink +template +class daily_file_sink:public base_sink { public: explicit daily_file_sink(const std::string& base_filename, @@ -129,7 +134,6 @@ public: _base_filename(base_filename), _extension(extension), _midnight_tp (_calc_midnight_tp() ), - _mutex(), _ofstream(_calc_filename(_base_filename, _extension), std::ofstream::binary|std::ofstream::app), _flush_helper(flush_every) { @@ -138,7 +142,6 @@ public: protected: void _sink_it(const details::log_msg& msg) override { - std::lock_guard lock(_mutex); if (std::chrono::system_clock::now() >= _midnight_tp) { _ofstream.close(); @@ -175,10 +178,12 @@ private: std::string _base_filename; std::string _extension; std::chrono::system_clock::time_point _midnight_tp; - std::mutex _mutex; std::ofstream _ofstream; details::file_flush_helper _flush_helper; }; + +typedef daily_file_sink daily_file_sink_mt; +typedef daily_file_sink daily_file_sink_st; } } diff --git a/include/c11log/sinks/null_sink.h b/include/c11log/sinks/null_sink.h index 9248533b..4526eef6 100644 --- a/include/c11log/sinks/null_sink.h +++ b/include/c11log/sinks/null_sink.h @@ -1,12 +1,12 @@ #pragma once -#include -#include #include "base_sink.h" namespace c11log { namespace sinks { -class null_sink : public base_sink + +template +class null_sink : public base_sink { protected: void _sink_it(const details::log_msg&) override