diff options
author | Remko Tronçon <git@el-tramo.be> | 2010-05-06 17:44:27 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2010-05-06 17:44:27 (GMT) |
commit | d76ada0ab59634e3333f9eb5a92d0e850f60d7bf (patch) | |
tree | 5eaae441173fad2ec19ba67d6589f28ecd740991 /3rdParty/Boost/src/boost/asio/detail/service_registry.hpp | |
parent | 6f49e5abee37d37b351d68c01374232eccdac458 (diff) | |
download | swift-contrib-d76ada0ab59634e3333f9eb5a92d0e850f60d7bf.zip swift-contrib-d76ada0ab59634e3333f9eb5a92d0e850f60d7bf.tar.bz2 |
Updated Boost to 1.43.0.
Diffstat (limited to '3rdParty/Boost/src/boost/asio/detail/service_registry.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/detail/service_registry.hpp | 175 |
1 files changed, 112 insertions, 63 deletions
diff --git a/3rdParty/Boost/src/boost/asio/detail/service_registry.hpp b/3rdParty/Boost/src/boost/asio/detail/service_registry.hpp index b648939..e640ec8 100644 --- a/3rdParty/Boost/src/boost/asio/detail/service_registry.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/service_registry.hpp @@ -18,7 +18,6 @@ #include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp> -#include <memory> #include <typeinfo> #include <boost/asio/detail/pop_options.hpp> @@ -80,7 +79,7 @@ public: while (first_service_) { boost::asio::io_service::service* next_service = first_service_->next_; - delete first_service_; + destroy(first_service_); first_service_ = next_service; } } @@ -91,14 +90,105 @@ public: template <typename Service> Service& use_service() { + boost::asio::io_service::service::key key; + init_key(key, Service::id); + factory_type factory = &service_registry::create<Service>; + return *static_cast<Service*>(do_use_service(key, factory)); + } + + // Add a service object. Returns false on error, in which case ownership of + // the object is retained by the caller. + template <typename Service> + bool add_service(Service* new_service) + { + boost::asio::io_service::service::key key; + init_key(key, Service::id); + return do_add_service(key, new_service); + } + + // Check whether a service object of the specified type already exists. + template <typename Service> + bool has_service() const + { + boost::asio::io_service::service::key key; + init_key(key, Service::id); + return do_has_service(key); + } + +private: + // Initialise a service's key based on its id. + void init_key(boost::asio::io_service::service::key& key, + const boost::asio::io_service::id& id) + { + key.type_info_ = 0; + key.id_ = &id; + } + +#if !defined(BOOST_ASIO_NO_TYPEID) + // Initialise a service's key based on its id. + template <typename Service> + void init_key(boost::asio::io_service::service::key& key, + const boost::asio::detail::service_id<Service>& /*id*/) + { + key.type_info_ = &typeid(typeid_wrapper<Service>); + key.id_ = 0; + } +#endif // !defined(BOOST_ASIO_NO_TYPEID) + + // Check if a service matches the given id. + static bool 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; + } + + // The type of a factory function used for creating a service instance. + typedef boost::asio::io_service::service* + (*factory_type)(boost::asio::io_service&); + + // Factory function for creating a service instance. + template <typename Service> + static boost::asio::io_service::service* create( + boost::asio::io_service& owner) + { + return new Service(owner); + } + + // Destroy a service instance. + static void destroy(boost::asio::io_service::service* service) + { + delete service; + } + + // Helper class to manage service pointers. + struct auto_service_ptr + { + boost::asio::io_service::service* ptr_; + ~auto_service_ptr() { destroy(ptr_); } + }; + + // Get the service object corresponding to the specified service key. Will + // create a new service object automatically if no such object already + // exists. Ownership of the service object is not transferred to the caller. + boost::asio::io_service::service* 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 for the given type. + // First see if there is an existing service object with the given key. boost::asio::io_service::service* service = first_service_; while (service) { - if (service_id_matches(*service, Service::id)) - return *static_cast<Service*>(service); + if (keys_match(service->key_, key)) + return service; service = service->next_; } @@ -106,9 +196,8 @@ public: // at this time to allow for nested calls into this function from the new // service's constructor. lock.unlock(); - std::auto_ptr<Service> new_service(new Service(owner_)); - init_service_id(*new_service, Service::id); - Service& new_service_ref = *new_service; + 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 @@ -116,52 +205,52 @@ public: service = first_service_; while (service) { - if (service_id_matches(*service, Service::id)) - return *static_cast<Service*>(service); + if (keys_match(service->key_, key)) + return service; service = service->next_; } // Service was successfully initialised, pass ownership to registry. - new_service->next_ = first_service_; - first_service_ = new_service.release(); - - return new_service_ref; + new_service.ptr_->next_ = first_service_; + first_service_ = new_service.ptr_; + new_service.ptr_ = 0; + return first_service_; } // Add a service object. Returns false on error, in which case ownership of // the object is retained by the caller. - template <typename Service> - bool add_service(Service* new_service) + bool do_add_service( + const boost::asio::io_service::service::key& key, + boost::asio::io_service::service* new_service) { boost::asio::detail::mutex::scoped_lock lock(mutex_); - // Check if there is an existing service object for the given type. + // Check if there is an existing service object with the given key. boost::asio::io_service::service* service = first_service_; while (service) { - if (service_id_matches(*service, Service::id)) + if (keys_match(service->key_, key)) return false; service = service->next_; } // Take ownership of the service object. - init_service_id(*new_service, Service::id); + new_service->key_ = key; new_service->next_ = first_service_; first_service_ = new_service; return true; } - // Check whether a service object of the specified type already exists. - template <typename Service> - bool has_service() const + // Check whether a service object with the specified key already exists. + bool 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 (service_id_matches(*service, Service::id)) + if (keys_match(service->key_, key)) return true; service = service->next_; } @@ -169,46 +258,6 @@ public: return false; } -private: - // Set a service's id. - void init_service_id(boost::asio::io_service::service& service, - const boost::asio::io_service::id& id) - { - service.type_info_ = 0; - service.id_ = &id; - } - -#if !defined(BOOST_ASIO_NO_TYPEID) - // Set a service's id. - template <typename Service> - void init_service_id(boost::asio::io_service::service& service, - const boost::asio::detail::service_id<Service>& /*id*/) - { - service.type_info_ = &typeid(typeid_wrapper<Service>); - service.id_ = 0; - } -#endif // !defined(BOOST_ASIO_NO_TYPEID) - - // Check if a service matches the given id. - static bool service_id_matches( - const boost::asio::io_service::service& service, - const boost::asio::io_service::id& id) - { - return service.id_ == &id; - } - -#if !defined(BOOST_ASIO_NO_TYPEID) - // Check if a service matches the given id. - template <typename Service> - static bool service_id_matches( - const boost::asio::io_service::service& service, - const boost::asio::detail::service_id<Service>& /*id*/) - { - return service.type_info_ != 0 - && *service.type_info_ == typeid(typeid_wrapper<Service>); - } -#endif // !defined(BOOST_ASIO_NO_TYPEID) - // Mutex to protect access to internal data. mutable boost::asio::detail::mutex mutex_; |