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 namespace asio {
00031 namespace detail {
00032
00033 class service_registry
00034 : private noncopyable
00035 {
00036 public:
00037
00038 service_registry(asio::io_service& o)
00039 : owner_(o),
00040 first_service_(0)
00041 {
00042 }
00043
00044
00045 ~service_registry()
00046 {
00047
00048
00049
00050 asio::io_service::service* service = first_service_;
00051 while (service)
00052 {
00053 service->shutdown_service();
00054 service = service->next_;
00055 }
00056
00057
00058 while (first_service_)
00059 {
00060 asio::io_service::service* next_service = first_service_->next_;
00061 delete first_service_;
00062 first_service_ = next_service;
00063 }
00064 }
00065
00066
00067
00068
00069 template <typename Service>
00070 Service& use_service()
00071 {
00072 asio::detail::mutex::scoped_lock lock(mutex_);
00073
00074
00075 asio::io_service::service* service = first_service_;
00076 while (service)
00077 {
00078 if (service_id_matches(*service, Service::id))
00079 return *static_cast<Service*>(service);
00080 service = service->next_;
00081 }
00082
00083
00084
00085
00086 lock.unlock();
00087 std::auto_ptr<Service> new_service(new Service(owner_));
00088 init_service_id(*new_service, Service::id);
00089 Service& new_service_ref = *new_service;
00090 lock.lock();
00091
00092
00093
00094 service = first_service_;
00095 while (service)
00096 {
00097 if (service_id_matches(*service, Service::id))
00098 return *static_cast<Service*>(service);
00099 service = service->next_;
00100 }
00101
00102
00103 new_service->next_ = first_service_;
00104 first_service_ = new_service.release();
00105
00106 return new_service_ref;
00107 }
00108
00109
00110
00111 template <typename Service>
00112 bool add_service(Service* new_service)
00113 {
00114 asio::detail::mutex::scoped_lock lock(mutex_);
00115
00116
00117 asio::io_service::service* service = first_service_;
00118 while (service)
00119 {
00120 if (service_id_matches(*service, Service::id))
00121 return false;
00122 service = service->next_;
00123 }
00124
00125
00126 init_service_id(*new_service, Service::id);
00127 new_service->next_ = first_service_;
00128 first_service_ = new_service;
00129
00130 return true;
00131 }
00132
00133
00134 template <typename Service>
00135 bool has_service() const
00136 {
00137 asio::detail::mutex::scoped_lock lock(mutex_);
00138
00139 asio::io_service::service* service = first_service_;
00140 while (service)
00141 {
00142 if (service_id_matches(*service, Service::id))
00143 return true;
00144 service = service->next_;
00145 }
00146
00147 return false;
00148 }
00149
00150 private:
00151
00152 void init_service_id(asio::io_service::service& service,
00153 const asio::io_service::id& id)
00154 {
00155 service.type_info_ = 0;
00156 service.id_ = &id;
00157 }
00158
00159
00160 template <typename Service>
00161 void init_service_id(asio::io_service::service& service,
00162 const asio::detail::service_id<Service>& )
00163 {
00164 service.type_info_ = &typeid(Service);
00165 service.id_ = 0;
00166 }
00167
00168
00169 bool service_id_matches(const asio::io_service::service& service,
00170 const asio::io_service::id& id)
00171 {
00172 return service.id_ == &id;
00173 }
00174
00175
00176 template <typename Service>
00177 bool service_id_matches(const asio::io_service::service& service,
00178 const asio::detail::service_id<Service>& )
00179 {
00180 return service.type_info_ != 0 && *service.type_info_ == typeid(Service);
00181 }
00182
00183
00184 mutable asio::detail::mutex mutex_;
00185
00186
00187 asio::io_service& owner_;
00188
00189
00190 asio::io_service::service* first_service_;
00191 };
00192
00193 }
00194 }
00195
00196 #include "asio/detail/pop_options.hpp"
00197
00198 #endif // ASIO_DETAIL_SERVICE_REGISTRY_HPP