10ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 20ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// detail/service_registry.hpp 30ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 40ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 50ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) 60ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 70ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Distributed under the Boost Software License, Version 1.0. (See accompanying 80ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 90ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#ifndef ASIO_DETAIL_SERVICE_REGISTRY_HPP 120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#define ASIO_DETAIL_SERVICE_REGISTRY_HPP 130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/config.hpp" 160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include <typeinfo> 170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/mutex.hpp" 180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/noncopyable.hpp" 190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/io_service.hpp" 200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/push_options.hpp" 220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace asio { 240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace detail { 250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffietemplate <typename T> 270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass typeid_wrapper {}; 280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass service_registry 300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie : private noncopyable 310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic: 330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Constructor. Adds the initial service. 340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename Service, typename Arg> 350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie service_registry(asio::io_service& o, 360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie Service* initial_service, Arg arg); 370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Destructor. 390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_DECL ~service_registry(); 400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Notify all services of a fork event. 420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_DECL void notify_fork(asio::io_service::fork_event fork_ev); 430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Get the first service object cast to the specified type. Called during 450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // io_service construction and so performs no locking or type checking. 460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename Service> 470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie Service& first_service(); 480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Get the service object corresponding to the specified service type. Will 500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // create a new service object automatically if no such object already 510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // exists. Ownership of the service object is not transferred to the caller. 520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename Service> 530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie Service& use_service(); 540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Add a service object. Throws on error, in which case ownership of the 560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // object is retained by the caller. 570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename Service> 580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void add_service(Service* new_service); 590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Check whether a service object of the specified type already exists. 610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename Service> 620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie bool has_service() const; 630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprivate: 650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Initialise a service's key based on its id. 660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_DECL static void init_key( 670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::io_service::service::key& key, 680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const asio::io_service::id& id); 690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#if !defined(ASIO_NO_TYPEID) 710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Initialise a service's key based on its id. 720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename Service> 730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static void init_key(asio::io_service::service::key& key, 740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const asio::detail::service_id<Service>& /*id*/); 750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#endif // !defined(ASIO_NO_TYPEID) 760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Check if a service matches the given id. 780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_DECL static bool keys_match( 790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const asio::io_service::service::key& key1, 800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const asio::io_service::service::key& key2); 810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // The type of a factory function used for creating a service instance. 830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typedef asio::io_service::service* 840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie (*factory_type)(asio::io_service&); 850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Factory function for creating a service instance. 870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename Service> 880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static asio::io_service::service* create( 890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::io_service& owner); 900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Destroy a service instance. 920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_DECL static void destroy( 930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::io_service::service* service); 940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Helper class to manage service pointers. 960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie struct auto_service_ptr; 970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie friend struct auto_service_ptr; 980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie struct auto_service_ptr 990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::io_service::service* ptr_; 1010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ~auto_service_ptr() { destroy(ptr_); } 1020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie }; 1030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Get the service object corresponding to the specified service key. Will 1050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // create a new service object automatically if no such object already 1060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // exists. Ownership of the service object is not transferred to the caller. 1070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_DECL asio::io_service::service* do_use_service( 1080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const asio::io_service::service::key& key, 1090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie factory_type factory); 1100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Add a service object. Throws on error, in which case ownership of the 1120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // object is retained by the caller. 1130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_DECL void do_add_service( 1140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const asio::io_service::service::key& key, 1150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::io_service::service* new_service); 1160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Check whether a service object with the specified key already exists. 1180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_DECL bool do_has_service( 1190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const asio::io_service::service::key& key) const; 1200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Mutex to protect access to internal data. 1220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie mutable asio::detail::mutex mutex_; 1230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // The owner of this service registry and the services it contains. 1250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::io_service& owner_; 1260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // The first service in the list of contained services. 1280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::io_service::service* first_service_; 1290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie}; 1300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace detail 1320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace asio 1330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/pop_options.hpp" 1350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/impl/service_registry.hpp" 1370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie# include "asio/detail/impl/service_registry.ipp" 1380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#endif // ASIO_DETAIL_SERVICE_REGISTRY_HPP 140