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 23 namespace asio { 24 namespace detail { 25 26 template <typename T> 27 class typeid_wrapper {}; 28 29 class service_registry 30 : private noncopyable 31 { 32 public: 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 64 private: 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_; ~auto_service_ptrasio::detail::service_registry::auto_service_ptr101 ~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