summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/asio/detail/impl/service_registry.ipp')
-rw-r--r--3rdParty/Boost/src/boost/asio/detail/impl/service_registry.ipp166
1 files changed, 166 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.ipp
new file mode 100644
index 0000000..9f7381e
--- /dev/null
+++ b/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.ipp
@@ -0,0 +1,166 @@
+//
+// detail/impl/service_registry.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_SERVICE_REGISTRY_IPP
+#define BOOST_ASIO_DETAIL_IMPL_SERVICE_REGISTRY_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/asio/detail/service_registry.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+service_registry::service_registry(boost::asio::io_service& o)
+ : owner_(o),
+ first_service_(0)
+{
+}
+
+service_registry::~service_registry()
+{
+ // Shutdown all services. This must be done in a separate loop before the
+ // services are destroyed since the destructors of user-defined handler
+ // objects may try to access other service objects.
+ boost::asio::io_service::service* service = first_service_;
+ while (service)
+ {
+ service->shutdown_service();
+ service = service->next_;
+ }
+
+ // Destroy all services.
+ while (first_service_)
+ {
+ boost::asio::io_service::service* next_service = first_service_->next_;
+ destroy(first_service_);
+ first_service_ = next_service;
+ }
+}
+
+void service_registry::init_key(boost::asio::io_service::service::key& key,
+ const boost::asio::io_service::id& id)
+{
+ key.type_info_ = 0;
+ key.id_ = &id;
+}
+
+bool service_registry::keys_match(
+ const boost::asio::io_service::service::key& key1,
+ const boost::asio::io_service::service::key& key2)
+{
+ if (key1.id_ && key2.id_)
+ if (key1.id_ == key2.id_)
+ return true;
+ if (key1.type_info_ && key2.type_info_)
+ if (*key1.type_info_ == *key2.type_info_)
+ return true;
+ return false;
+}
+
+void service_registry::destroy(boost::asio::io_service::service* service)
+{
+ delete service;
+}
+
+boost::asio::io_service::service* service_registry::do_use_service(
+ const boost::asio::io_service::service::key& key,
+ factory_type factory)
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+ // First see if there is an existing service object with the given key.
+ boost::asio::io_service::service* service = first_service_;
+ while (service)
+ {
+ if (keys_match(service->key_, key))
+ return service;
+ service = service->next_;
+ }
+
+ // Create a new service object. The service registry's mutex is not locked
+ // at this time to allow for nested calls into this function from the new
+ // service's constructor.
+ lock.unlock();
+ auto_service_ptr new_service = { factory(owner_) };
+ new_service.ptr_->key_ = key;
+ lock.lock();
+
+ // Check that nobody else created another service object of the same type
+ // while the lock was released.
+ service = first_service_;
+ while (service)
+ {
+ if (keys_match(service->key_, key))
+ return service;
+ service = service->next_;
+ }
+
+ // Service was successfully initialised, pass ownership to registry.
+ new_service.ptr_->next_ = first_service_;
+ first_service_ = new_service.ptr_;
+ new_service.ptr_ = 0;
+ return first_service_;
+}
+
+void service_registry::do_add_service(
+ const boost::asio::io_service::service::key& key,
+ boost::asio::io_service::service* new_service)
+{
+ if (&owner_ != &new_service->io_service())
+ boost::throw_exception(invalid_service_owner());
+
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+ // Check if there is an existing service object with the given key.
+ boost::asio::io_service::service* service = first_service_;
+ while (service)
+ {
+ if (keys_match(service->key_, key))
+ boost::throw_exception(service_already_exists());
+ service = service->next_;
+ }
+
+ // Take ownership of the service object.
+ new_service->key_ = key;
+ new_service->next_ = first_service_;
+ first_service_ = new_service;
+}
+
+bool service_registry::do_has_service(
+ const boost::asio::io_service::service::key& key) const
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+ boost::asio::io_service::service* service = first_service_;
+ while (service)
+ {
+ if (keys_match(service->key_, key))
+ return true;
+ service = service->next_;
+ }
+
+ return false;
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_IMPL_SERVICE_REGISTRY_IPP