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