Nexus HTTP/3
A QUIC and HTTP/3 library
service.hpp
1 #pragma once
2 
3 #include <mutex>
4 #include <boost/asio/execution_context.hpp>
5 #include <boost/intrusive/list.hpp>
6 
7 namespace nexus::quic::detail {
8 
9 struct service_tag {};
10 using service_list_base_hook = boost::intrusive::list_base_hook<
11  boost::intrusive::tag<service_tag>>;
12 
23 template <typename IoObject>
24 class service : public boost::asio::execution_context::service {
25  using base_hook = boost::intrusive::base_hook<service_list_base_hook>;
26  boost::intrusive::list<IoObject, base_hook> entries;
27  std::mutex mutex;
28 
30  void shutdown() override {
31  while (!entries.empty()) {
32  auto& entry = entries.front();
33  entries.pop_front();
34  entry.service_shutdown();
35  }
36  }
37  public:
38  using key_type = service;
39  static inline boost::asio::execution_context::id id;
40 
41  explicit service(boost::asio::execution_context& ctx)
42  : boost::asio::execution_context::service(ctx) {}
43 
45  void add(IoObject& entry) {
46  auto lock = std::scoped_lock{mutex};
47  entries.push_back(entry);
48  }
50  void remove(IoObject& entry) {
51  auto lock = std::scoped_lock{mutex};
52  if (entries.empty()) {
53  // already shut down
54  } else {
55  entries.erase(entries.iterator_to(entry));
56  }
57  }
58 };
59 
60 } // namespace nexus::quic::detail