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