1//
2// detail/service_registry.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2015 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
11#ifndef ASIO_DETAIL_SERVICE_REGISTRY_HPP
12#define ASIO_DETAIL_SERVICE_REGISTRY_HPP
13
14
15#include "asio/detail/config.hpp"
16#include <typeinfo>
17#include "asio/detail/mutex.hpp"
18#include "asio/detail/noncopyable.hpp"
19#include "asio/io_service.hpp"
20
21#include "asio/detail/push_options.hpp"
22
23namespace asio {
24namespace detail {
25
26template <typename T>
27class typeid_wrapper {};
28
29class service_registry
30  : private noncopyable
31{
32public:
33  // Constructor. Adds the initial service.
34  template <typename Service, typename Arg>
35  service_registry(asio::io_service& o,
36      Service* initial_service, Arg arg);
37
38  // Destructor.
39  ASIO_DECL ~service_registry();
40
41  // Notify all services of a fork event.
42  ASIO_DECL void notify_fork(asio::io_service::fork_event fork_ev);
43
44  // Get the first service object cast to the specified type. Called during
45  // io_service construction and so performs no locking or type checking.
46  template <typename Service>
47  Service& first_service();
48
49  // Get the service object corresponding to the specified service type. Will
50  // create a new service object automatically if no such object already
51  // exists. Ownership of the service object is not transferred to the caller.
52  template <typename Service>
53  Service& use_service();
54
55  // Add a service object. Throws on error, in which case ownership of the
56  // object is retained by the caller.
57  template <typename Service>
58  void add_service(Service* new_service);
59
60  // Check whether a service object of the specified type already exists.
61  template <typename Service>
62  bool has_service() const;
63
64private:
65  // Initialise a service's key based on its id.
66  ASIO_DECL static void init_key(
67      asio::io_service::service::key& key,
68      const asio::io_service::id& id);
69
70#if !defined(ASIO_NO_TYPEID)
71  // Initialise a service's key based on its id.
72  template <typename Service>
73  static void init_key(asio::io_service::service::key& key,
74      const asio::detail::service_id<Service>& /*id*/);
75#endif // !defined(ASIO_NO_TYPEID)
76
77  // Check if a service matches the given id.
78  ASIO_DECL static bool keys_match(
79      const asio::io_service::service::key& key1,
80      const asio::io_service::service::key& key2);
81
82  // The type of a factory function used for creating a service instance.
83  typedef asio::io_service::service*
84    (*factory_type)(asio::io_service&);
85
86  // Factory function for creating a service instance.
87  template <typename Service>
88  static asio::io_service::service* create(
89      asio::io_service& owner);
90
91  // Destroy a service instance.
92  ASIO_DECL static void destroy(
93      asio::io_service::service* service);
94
95  // Helper class to manage service pointers.
96  struct auto_service_ptr;
97  friend struct auto_service_ptr;
98  struct auto_service_ptr
99  {
100    asio::io_service::service* ptr_;
101    ~auto_service_ptr() { destroy(ptr_); }
102  };
103
104  // Get the service object corresponding to the specified service key. Will
105  // create a new service object automatically if no such object already
106  // exists. Ownership of the service object is not transferred to the caller.
107  ASIO_DECL asio::io_service::service* do_use_service(
108      const asio::io_service::service::key& key,
109      factory_type factory);
110
111  // Add a service object. Throws on error, in which case ownership of the
112  // object is retained by the caller.
113  ASIO_DECL void do_add_service(
114      const asio::io_service::service::key& key,
115      asio::io_service::service* new_service);
116
117  // Check whether a service object with the specified key already exists.
118  ASIO_DECL bool do_has_service(
119      const asio::io_service::service::key& key) const;
120
121  // Mutex to protect access to internal data.
122  mutable asio::detail::mutex mutex_;
123
124  // The owner of this service registry and the services it contains.
125  asio::io_service& owner_;
126
127  // The first service in the list of contained services.
128  asio::io_service::service* first_service_;
129};
130
131} // namespace detail
132} // namespace asio
133
134#include "asio/detail/pop_options.hpp"
135
136#include "asio/detail/impl/service_registry.hpp"
137# include "asio/detail/impl/service_registry.ipp"
138
139#endif // ASIO_DETAIL_SERVICE_REGISTRY_HPP
140