File indexing completed on 2026-01-08 10:31:09
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 <functional>
0012 #include <memory>
0013 #include <thread>
0014 #include <vector>
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 { log, flush, terminate };
0024
0025
0026
0027 struct async_msg : log_msg_buffer {
0028 async_msg_type msg_type{async_msg_type::log};
0029 async_logger_ptr worker_ptr;
0030
0031 async_msg() = default;
0032 ~async_msg() = default;
0033
0034
0035 async_msg(const async_msg &) = delete;
0036
0037
0038 #if defined(_MSC_VER) && _MSC_VER <= 1800
0039 async_msg(async_msg &&other)
0040 : log_msg_buffer(std::move(other)),
0041 msg_type(other.msg_type),
0042 worker_ptr(std::move(other.worker_ptr)) {}
0043
0044 async_msg &operator=(async_msg &&other) {
0045 *static_cast<log_msg_buffer *>(this) = std::move(other);
0046 msg_type = other.msg_type;
0047 worker_ptr = std::move(other.worker_ptr);
0048 return *this;
0049 }
0050 #else
0051 async_msg(async_msg &&) = default;
0052 async_msg &operator=(async_msg &&) = default;
0053 #endif
0054
0055
0056 async_msg(async_logger_ptr &&worker, async_msg_type the_type, const details::log_msg &m)
0057 : log_msg_buffer{m},
0058 msg_type{the_type},
0059 worker_ptr{std::move(worker)} {}
0060
0061 async_msg(async_logger_ptr &&worker, async_msg_type the_type)
0062 : log_msg_buffer{},
0063 msg_type{the_type},
0064 worker_ptr{std::move(worker)} {}
0065
0066 explicit async_msg(async_msg_type the_type)
0067 : async_msg{nullptr, the_type} {}
0068 };
0069
0070 class SPDLOG_API thread_pool {
0071 public:
0072 using item_type = async_msg;
0073 using q_type = details::mpmc_blocking_queue<item_type>;
0074
0075 thread_pool(size_t q_max_items,
0076 size_t threads_n,
0077 std::function<void()> on_thread_start,
0078 std::function<void()> on_thread_stop);
0079 thread_pool(size_t q_max_items, size_t threads_n, std::function<void()> on_thread_start);
0080 thread_pool(size_t q_max_items, size_t threads_n);
0081
0082
0083 ~thread_pool();
0084
0085 thread_pool(const thread_pool &) = delete;
0086 thread_pool &operator=(thread_pool &&) = delete;
0087
0088 void post_log(async_logger_ptr &&worker_ptr,
0089 const details::log_msg &msg,
0090 async_overflow_policy overflow_policy);
0091 void post_flush(async_logger_ptr &&worker_ptr, async_overflow_policy overflow_policy);
0092 size_t overrun_counter();
0093 void reset_overrun_counter();
0094 size_t discard_counter();
0095 void reset_discard_counter();
0096 size_t queue_size();
0097
0098 private:
0099 q_type q_;
0100
0101 std::vector<std::thread> threads_;
0102
0103 void post_async_msg_(async_msg &&new_msg, async_overflow_policy overflow_policy);
0104 void worker_loop_();
0105
0106
0107
0108
0109 bool process_next_msg_();
0110 };
0111
0112 }
0113 }
0114
0115 #ifdef SPDLOG_HEADER_ONLY
0116 #include "thread_pool-inl.h"
0117 #endif