Blame view

3rdparty/spdlog-1.9.2/release/include/spdlog/details/thread_pool.h 3.15 KB
3d2ab595   Hu Chunming   支持gb28181
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
  // Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
  // Distributed under the MIT License (http://opensource.org/licenses/MIT)
  
  #pragma once
  
  #include <spdlog/details/log_msg_buffer.h>
  #include <spdlog/details/mpmc_blocking_q.h>
  #include <spdlog/details/os.h>
  
  #include <chrono>
  #include <memory>
  #include <thread>
  #include <vector>
  #include <functional>
  
  namespace spdlog {
  class async_logger;
  
  namespace details {
  
  using async_logger_ptr = std::shared_ptr<spdlog::async_logger>;
  
  enum class async_msg_type
  {
      log,
      flush,
      terminate
  };
  
  // Async msg to move to/from the queue
  // Movable only. should never be copied
  struct async_msg : log_msg_buffer
  {
      async_msg_type msg_type{async_msg_type::log};
      async_logger_ptr worker_ptr;
  
      async_msg() = default;
      ~async_msg() = default;
  
      // should only be moved in or out of the queue..
      async_msg(const async_msg &) = delete;
  
  // support for vs2013 move
  #if defined(_MSC_VER) && _MSC_VER <= 1800
      async_msg(async_msg &&other)
          : log_msg_buffer(std::move(other))
          , msg_type(other.msg_type)
          , worker_ptr(std::move(other.worker_ptr))
      {}
  
      async_msg &operator=(async_msg &&other)
      {
          *static_cast<log_msg_buffer *>(this) = std::move(other);
          msg_type = other.msg_type;
          worker_ptr = std::move(other.worker_ptr);
          return *this;
      }
  #else // (_MSC_VER) && _MSC_VER <= 1800
      async_msg(async_msg &&) = default;
      async_msg &operator=(async_msg &&) = default;
  #endif
  
      // construct from log_msg with given type
      async_msg(async_logger_ptr &&worker, async_msg_type the_type, const details::log_msg &m)
          : log_msg_buffer{m}
          , msg_type{the_type}
          , worker_ptr{std::move(worker)}
      {}
  
      async_msg(async_logger_ptr &&worker, async_msg_type the_type)
          : log_msg_buffer{}
          , msg_type{the_type}
          , worker_ptr{std::move(worker)}
      {}
  
      explicit async_msg(async_msg_type the_type)
          : async_msg{nullptr, the_type}
      {}
  };
  
  class SPDLOG_API thread_pool
  {
  public:
      using item_type = async_msg;
      using q_type = details::mpmc_blocking_queue<item_type>;
  
      thread_pool(size_t q_max_items, size_t threads_n, std::function<void()> on_thread_start);
      thread_pool(size_t q_max_items, size_t threads_n);
  
      // message all threads to terminate gracefully join them
      ~thread_pool();
  
      thread_pool(const thread_pool &) = delete;
      thread_pool &operator=(thread_pool &&) = delete;
  
      void post_log(async_logger_ptr &&worker_ptr, const details::log_msg &msg, async_overflow_policy overflow_policy);
      void post_flush(async_logger_ptr &&worker_ptr, async_overflow_policy overflow_policy);
      size_t overrun_counter();
      size_t queue_size();
  
  private:
      q_type q_;
  
      std::vector<std::thread> threads_;
  
      void post_async_msg_(async_msg &&new_msg, async_overflow_policy overflow_policy);
      void worker_loop_();
  
      // process next message in the queue
      // return true if this thread should still be active (while no terminate msg
      // was received)
      bool process_next_msg_();
  };
  
  } // namespace details
  } // namespace spdlog
  
  #ifdef SPDLOG_HEADER_ONLY
  #    include "thread_pool-inl.h"
  #endif