File indexing completed on 2025-01-18 10:12:41
0001
0002
0003
0004 #pragma once
0005
0006 #include <spdlog/details/log_msg_buffer.h>
0007 #include <spdlog/details/mpmc_blocking_q.h>
0008 #include <spdlog/details/os.h>
0009
0010 #include <chrono>
0011 #include <memory>
0012 #include <thread>
0013 #include <vector>
0014 #include <functional>
0015
0016 namespace spdlog {
0017 class async_logger;
0018
0019 namespace details {
0020
0021 using async_logger_ptr = std::shared_ptr<spdlog::async_logger>;
0022
0023 enum class async_msg_type
0024 {
0025 log,
0026 flush,
0027 terminate
0028 };
0029
0030
0031
0032 struct async_msg : log_msg_buffer
0033 {
0034 async_msg_type msg_type{async_msg_type::log};
0035 async_logger_ptr worker_ptr;
0036
0037 async_msg() = default;
0038 ~async_msg() = default;
0039
0040
0041 async_msg(const async_msg &) = delete;
0042
0043
0044 #if defined(_MSC_VER) && _MSC_VER <= 1800
0045 async_msg(async_msg &&other)
0046 : log_msg_buffer(std::move(other))
0047 , msg_type(other.msg_type)
0048 , worker_ptr(std::move(other.worker_ptr))
0049 {}
0050
0051 async_msg &operator=(async_msg &&other)
0052 {
0053 *static_cast<log_msg_buffer *>(this) = std::move(other);
0054 msg_type = other.msg_type;
0055 worker_ptr = std::move(other.worker_ptr);
0056 return *this;
0057 }
0058 #else
0059 async_msg(async_msg &&) = default;
0060 async_msg &operator=(async_msg &&) = default;
0061 #endif
0062
0063
0064 async_msg(async_logger_ptr &&worker, async_msg_type the_type, const details::log_msg &m)
0065 : log_msg_buffer{m}
0066 , msg_type{the_type}
0067 , worker_ptr{std::move(worker)}
0068 {}
0069
0070 async_msg(async_logger_ptr &&worker, async_msg_type the_type)
0071 : log_msg_buffer{}
0072 , msg_type{the_type}
0073 , worker_ptr{std::move(worker)}
0074 {}
0075
0076 explicit async_msg(async_msg_type the_type)
0077 : async_msg{nullptr, the_type}
0078 {}
0079 };
0080
0081 class SPDLOG_API thread_pool
0082 {
0083 public:
0084 using item_type = async_msg;
0085 using q_type = details::mpmc_blocking_queue<item_type>;
0086
0087 thread_pool(size_t q_max_items, size_t threads_n, std::function<void()> on_thread_start, std::function<void()> on_thread_stop);
0088 thread_pool(size_t q_max_items, size_t threads_n, std::function<void()> on_thread_start);
0089 thread_pool(size_t q_max_items, size_t threads_n);
0090
0091
0092 ~thread_pool();
0093
0094 thread_pool(const thread_pool &) = delete;
0095 thread_pool &operator=(thread_pool &&) = delete;
0096
0097 void post_log(async_logger_ptr &&worker_ptr, const details::log_msg &msg, async_overflow_policy overflow_policy);
0098 void post_flush(async_logger_ptr &&worker_ptr, async_overflow_policy overflow_policy);
0099 size_t overrun_counter();
0100 void reset_overrun_counter();
0101 size_t queue_size();
0102
0103 private:
0104 q_type q_;
0105
0106 std::vector<std::thread> threads_;
0107
0108 void post_async_msg_(async_msg &&new_msg, async_overflow_policy overflow_policy);
0109 void worker_loop_();
0110
0111
0112
0113
0114 bool process_next_msg_();
0115 };
0116
0117 }
0118 }
0119
0120 #ifdef SPDLOG_HEADER_ONLY
0121 # include "thread_pool-inl.h"
0122 #endif