Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef ASIO_DETAIL_SERVICE_REGISTRY_HPP
00012 #define ASIO_DETAIL_SERVICE_REGISTRY_HPP
00013
00014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00015 # pragma once
00016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
00017
00018 #include "asio/detail/push_options.hpp"
00019
00020 #include "asio/detail/push_options.hpp"
00021 #include <memory>
00022 #include <typeinfo>
00023 #include "asio/detail/pop_options.hpp"
00024
00025 #include "asio/io_service.hpp"
00026 #include "asio/detail/mutex.hpp"
00027 #include "asio/detail/noncopyable.hpp"
00028 #include "asio/detail/service_id.hpp"
00029
00030 #if defined(BOOST_NO_TYPEID)
00031 # if !defined(ASIO_NO_TYPEID)
00032 # define ASIO_NO_TYPEID
00033 # endif // !defined(ASIO_NO_TYPEID)
00034 #endif // defined(BOOST_NO_TYPEID)
00035
00036 namespace asio {
00037 namespace detail {
00038
00039 class service_registry
00040 : private noncopyable
00041 {
00042 public:
00043
00044 service_registry(asio::io_service& o)
00045 : owner_(o),
00046 first_service_(0)
00047 {
00048 }
00049
00050
00051 ~service_registry()
00052 {
00053
00054
00055
00056 asio::io_service::service* service = first_service_;
00057 while (service)
00058 {
00059 service->shutdown_service();
00060 service = service->next_;
00061 }
00062
00063
00064 while (first_service_)
00065 {
00066 asio::io_service::service* next_service = first_service_->next_;
00067 delete first_service_;
00068 first_service_ = next_service;
00069 }
00070 }
00071
00072
00073
00074
00075 template <typename Service>
00076 Service& use_service()
00077 {
00078 asio::detail::mutex::scoped_lock lock(mutex_);
00079
00080
00081 asio::io_service::service* service = first_service_;
00082 while (service)
00083 {
00084 if (service_id_matches(*service, Service::id))
00085 return *static_cast<Service*>(service);
00086 service = service->next_;
00087 }
00088
00089
00090
00091
00092 lock.unlock();
00093 std::auto_ptr<Service> new_service(new Service(owner_));
00094 init_service_id(*new_service, Service::id);
00095 Service& new_service_ref = *new_service;
00096 lock.lock();
00097
00098
00099
00100 service = first_service_;
00101 while (service)
00102 {
00103 if (service_id_matches(*service, Service::id))
00104 return *static_cast<Service*>(service);
00105 service = service->next_;
00106 }
00107
00108
00109 new_service->next_ = first_service_;
00110 first_service_ = new_service.release();
00111
00112 return new_service_ref;
00113 }
00114
00115
00116
00117 template <typename Service>
00118 bool add_service(Service* new_service)
00119 {
00120 asio::detail::mutex::scoped_lock lock(mutex_);
00121
00122
00123 asio::io_service::service* service = first_service_;
00124 while (service)
00125 {
00126 if (service_id_matches(*service, Service::id))
00127 return false;
00128 service = service->next_;
00129 }
00130
00131
00132 init_service_id(*new_service, Service::id);
00133 new_service->next_ = first_service_;
00134 first_service_ = new_service;
00135
00136 return true;
00137 }
00138
00139
00140 template <typename Service>
00141 bool has_service() const
00142 {
00143 asio::detail::mutex::scoped_lock lock(mutex_);
00144
00145 asio::io_service::service* service = first_service_;
00146 while (service)
00147 {
00148 if (service_id_matches(*service, Service::id))
00149 return true;
00150 service = service->next_;
00151 }
00152
00153 return false;
00154 }
00155
00156 private:
00157
00158 void init_service_id(asio::io_service::service& service,
00159 const asio::io_service::id& id)
00160 {
00161 service.type_info_ = 0;
00162 service.id_ = &id;
00163 }
00164
00165 #if !defined(ASIO_NO_TYPEID)
00166
00167 template <typename Service>
00168 void init_service_id(asio::io_service::service& service,
00169 const asio::detail::service_id<Service>& )
00170 {
00171 service.type_info_ = &typeid(Service);
00172 service.id_ = 0;
00173 }
00174 #endif // !defined(ASIO_NO_TYPEID)
00175
00176
00177 static bool service_id_matches(
00178 const asio::io_service::service& service,
00179 const asio::io_service::id& id)
00180 {
00181 return service.id_ == &id;
00182 }
00183
00184 #if !defined(ASIO_NO_TYPEID)
00185
00186 template <typename Service>
00187 static bool service_id_matches(
00188 const asio::io_service::service& service,
00189 const asio::detail::service_id<Service>& )
00190 {
00191 return service.type_info_ != 0 && *service.type_info_ == typeid(Service);
00192 }
00193 #endif // !defined(ASIO_NO_TYPEID)
00194
00195
00196 mutable asio::detail::mutex mutex_;
00197
00198
00199 asio::io_service& owner_;
00200
00201
00202 asio::io_service::service* first_service_;
00203 };
00204
00205 }
00206 }
00207
00208 #include "asio/detail/pop_options.hpp"
00209
00210 #endif // ASIO_DETAIL_SERVICE_REGISTRY_HPP