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