object_pool.hpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. //
  2. // detail/object_pool.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_DETAIL_OBJECT_POOL_HPP
  11. #define BOOST_ASIO_DETAIL_OBJECT_POOL_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/config.hpp>
  16. #include <boost/asio/detail/memory.hpp>
  17. #include <boost/asio/detail/push_options.hpp>
  18. namespace boost {
  19. namespace asio {
  20. namespace detail {
  21. template <typename Object, typename Allocator>
  22. class object_pool
  23. {
  24. public:
  25. // Constructor.
  26. template <typename... Args>
  27. object_pool(const Allocator& allocator,
  28. unsigned int preallocated, Args... args)
  29. : allocator_(allocator),
  30. live_list_(0),
  31. free_list_(0)
  32. {
  33. while (preallocated > 0)
  34. {
  35. Object* o = allocate_object<Object>(allocator_, args...);
  36. o->next_ = free_list_;
  37. o->prev_ = 0;
  38. free_list_ = o;
  39. --preallocated;
  40. }
  41. }
  42. // Destructor destroys all objects.
  43. ~object_pool()
  44. {
  45. destroy_list(live_list_);
  46. destroy_list(free_list_);
  47. }
  48. // Get the object at the start of the live list.
  49. Object* first()
  50. {
  51. return live_list_;
  52. }
  53. // Allocate a new object with an argument.
  54. template <typename... Args>
  55. Object* alloc(Args... args)
  56. {
  57. Object* o = free_list_;
  58. if (o)
  59. free_list_ = free_list_->next_;
  60. else
  61. o = allocate_object<Object>(allocator_, args...);
  62. o->next_ = live_list_;
  63. o->prev_ = 0;
  64. if (live_list_)
  65. live_list_->prev_ = o;
  66. live_list_ = o;
  67. return o;
  68. }
  69. // Free an object. Moves it to the free list. No destructors are run.
  70. void free(Object* o)
  71. {
  72. if (live_list_ == o)
  73. live_list_ = o->next_;
  74. if (o->prev_)
  75. o->prev_->next_ = o->next_;
  76. if (o->next_)
  77. o->next_->prev_ = o->prev_;
  78. o->next_ = free_list_;
  79. o->prev_ = 0;
  80. free_list_ = o;
  81. }
  82. private:
  83. object_pool(const object_pool&) = delete;
  84. object_pool& operator=(const object_pool&) = delete;
  85. // Helper function to destroy all elements in a list.
  86. void destroy_list(Object* list)
  87. {
  88. while (list)
  89. {
  90. Object* o = list;
  91. list = o->next_;
  92. deallocate_object(allocator_, o);
  93. }
  94. }
  95. // The execution_context allocator used to manage pooled object memory.
  96. Allocator allocator_;
  97. // The list of live objects.
  98. Object* live_list_;
  99. // The free list.
  100. Object* free_list_;
  101. };
  102. } // namespace detail
  103. } // namespace asio
  104. } // namespace boost
  105. #include <boost/asio/detail/pop_options.hpp>
  106. #endif // BOOST_ASIO_DETAIL_OBJECT_POOL_HPP