File indexing completed on 2025-01-18 09:28:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_DETAIL_IMPL_SERVICE_REGISTRY_IPP
0012 #define BOOST_ASIO_DETAIL_IMPL_SERVICE_REGISTRY_IPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <vector>
0020 #include <boost/asio/detail/service_registry.hpp>
0021 #include <boost/asio/detail/throw_exception.hpp>
0022
0023 #include <boost/asio/detail/push_options.hpp>
0024
0025 namespace boost {
0026 namespace asio {
0027 namespace detail {
0028
0029 service_registry::service_registry(execution_context& owner)
0030 : owner_(owner),
0031 first_service_(0)
0032 {
0033 }
0034
0035 service_registry::~service_registry()
0036 {
0037 }
0038
0039 void service_registry::shutdown_services()
0040 {
0041 execution_context::service* service = first_service_;
0042 while (service)
0043 {
0044 service->shutdown();
0045 service = service->next_;
0046 }
0047 }
0048
0049 void service_registry::destroy_services()
0050 {
0051 while (first_service_)
0052 {
0053 execution_context::service* next_service = first_service_->next_;
0054 destroy(first_service_);
0055 first_service_ = next_service;
0056 }
0057 }
0058
0059 void service_registry::notify_fork(execution_context::fork_event fork_ev)
0060 {
0061
0062
0063
0064 std::vector<execution_context::service*> services;
0065 {
0066 boost::asio::detail::mutex::scoped_lock lock(mutex_);
0067 execution_context::service* service = first_service_;
0068 while (service)
0069 {
0070 services.push_back(service);
0071 service = service->next_;
0072 }
0073 }
0074
0075
0076
0077
0078
0079 std::size_t num_services = services.size();
0080 if (fork_ev == execution_context::fork_prepare)
0081 for (std::size_t i = 0; i < num_services; ++i)
0082 services[i]->notify_fork(fork_ev);
0083 else
0084 for (std::size_t i = num_services; i > 0; --i)
0085 services[i - 1]->notify_fork(fork_ev);
0086 }
0087
0088 void service_registry::init_key_from_id(execution_context::service::key& key,
0089 const execution_context::id& id)
0090 {
0091 key.type_info_ = 0;
0092 key.id_ = &id;
0093 }
0094
0095 bool service_registry::keys_match(
0096 const execution_context::service::key& key1,
0097 const execution_context::service::key& key2)
0098 {
0099 if (key1.id_ && key2.id_)
0100 if (key1.id_ == key2.id_)
0101 return true;
0102 if (key1.type_info_ && key2.type_info_)
0103 if (*key1.type_info_ == *key2.type_info_)
0104 return true;
0105 return false;
0106 }
0107
0108 void service_registry::destroy(execution_context::service* service)
0109 {
0110 delete service;
0111 }
0112
0113 execution_context::service* service_registry::do_use_service(
0114 const execution_context::service::key& key,
0115 factory_type factory, void* owner)
0116 {
0117 boost::asio::detail::mutex::scoped_lock lock(mutex_);
0118
0119
0120 execution_context::service* service = first_service_;
0121 while (service)
0122 {
0123 if (keys_match(service->key_, key))
0124 return service;
0125 service = service->next_;
0126 }
0127
0128
0129
0130
0131 lock.unlock();
0132 auto_service_ptr new_service = { factory(owner) };
0133 new_service.ptr_->key_ = key;
0134 lock.lock();
0135
0136
0137
0138 service = first_service_;
0139 while (service)
0140 {
0141 if (keys_match(service->key_, key))
0142 return service;
0143 service = service->next_;
0144 }
0145
0146
0147 new_service.ptr_->next_ = first_service_;
0148 first_service_ = new_service.ptr_;
0149 new_service.ptr_ = 0;
0150 return first_service_;
0151 }
0152
0153 void service_registry::do_add_service(
0154 const execution_context::service::key& key,
0155 execution_context::service* new_service)
0156 {
0157 if (&owner_ != &new_service->context())
0158 boost::asio::detail::throw_exception(invalid_service_owner());
0159
0160 boost::asio::detail::mutex::scoped_lock lock(mutex_);
0161
0162
0163 execution_context::service* service = first_service_;
0164 while (service)
0165 {
0166 if (keys_match(service->key_, key))
0167 boost::asio::detail::throw_exception(service_already_exists());
0168 service = service->next_;
0169 }
0170
0171
0172 new_service->key_ = key;
0173 new_service->next_ = first_service_;
0174 first_service_ = new_service;
0175 }
0176
0177 bool service_registry::do_has_service(
0178 const execution_context::service::key& key) const
0179 {
0180 boost::asio::detail::mutex::scoped_lock lock(mutex_);
0181
0182 execution_context::service* service = first_service_;
0183 while (service)
0184 {
0185 if (keys_match(service->key_, key))
0186 return true;
0187 service = service->next_;
0188 }
0189
0190 return false;
0191 }
0192
0193 }
0194 }
0195 }
0196
0197 #include <boost/asio/detail/pop_options.hpp>
0198
0199 #endif