summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/asio/detail/strand_service.hpp')
-rw-r--r--3rdParty/Boost/src/boost/asio/detail/strand_service.hpp171
1 files changed, 47 insertions, 124 deletions
diff --git a/3rdParty/Boost/src/boost/asio/detail/strand_service.hpp b/3rdParty/Boost/src/boost/asio/detail/strand_service.hpp
index 2c89a61..b228cec 100644
--- a/3rdParty/Boost/src/boost/asio/detail/strand_service.hpp
+++ b/3rdParty/Boost/src/boost/asio/detail/strand_service.hpp
@@ -2,7 +2,7 @@
// strand_service.hpp
// ~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// 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)
@@ -20,8 +20,8 @@
#include <boost/asio/detail/push_options.hpp>
#include <boost/aligned_storage.hpp>
#include <boost/assert.hpp>
-#include <boost/detail/atomic_count.hpp>
-#include <boost/intrusive_ptr.hpp>
+#include <boost/functional/hash.hpp>
+#include <boost/scoped_ptr.hpp>
#include <boost/asio/detail/pop_options.hpp>
#include <boost/asio/io_service.hpp>
@@ -49,20 +49,12 @@ public:
// The underlying implementation of a strand.
class strand_impl
{
-#if defined (__BORLANDC__)
public:
-#else
- private:
-#endif
- void add_ref()
- {
- ++ref_count_;
- }
-
- void release()
+ strand_impl()
+ : current_handler_(0),
+ first_waiter_(0),
+ last_waiter_(0)
{
- if (--ref_count_ == 0)
- delete this;
}
private:
@@ -71,55 +63,9 @@ public:
friend class post_next_waiter_on_exit;
friend class invoke_current_handler;
- strand_impl(strand_service& owner)
- : owner_(owner),
- current_handler_(0),
- first_waiter_(0),
- last_waiter_(0),
- ref_count_(0)
- {
- // Insert implementation into linked list of all implementations.
- boost::asio::detail::mutex::scoped_lock lock(owner_.mutex_);
- next_ = owner_.impl_list_;
- prev_ = 0;
- if (owner_.impl_list_)
- owner_.impl_list_->prev_ = this;
- owner_.impl_list_ = this;
- }
-
- ~strand_impl()
- {
- // Remove implementation from linked list of all implementations.
- boost::asio::detail::mutex::scoped_lock lock(owner_.mutex_);
- if (owner_.impl_list_ == this)
- owner_.impl_list_ = next_;
- if (prev_)
- prev_->next_ = next_;
- if (next_)
- next_->prev_= prev_;
- next_ = 0;
- prev_ = 0;
- lock.unlock();
-
- if (current_handler_)
- {
- current_handler_->destroy();
- }
-
- while (first_waiter_)
- {
- handler_base* next = first_waiter_->next_;
- first_waiter_->destroy();
- first_waiter_ = next;
- }
- }
-
// Mutex to protect access to internal data.
boost::asio::detail::mutex mutex_;
- // The service that owns this implementation.
- strand_service& owner_;
-
// The handler that is ready to execute. If this pointer is non-null then it
// indicates that a handler holds the lock.
handler_base* current_handler_;
@@ -137,30 +83,11 @@ public:
#else
handler_storage_type handler_storage_;
#endif
-
- // Pointers to adjacent socket implementations in linked list.
- strand_impl* next_;
- strand_impl* prev_;
-
- // The reference count on the strand implementation.
- boost::detail::atomic_count ref_count_;
-
-#if !defined(__BORLANDC__)
- friend void intrusive_ptr_add_ref(strand_impl* p)
- {
- p->add_ref();
- }
-
- friend void intrusive_ptr_release(strand_impl* p)
- {
- p->release();
- }
-#endif
};
friend class strand_impl;
- typedef boost::intrusive_ptr<strand_impl> implementation_type;
+ typedef strand_impl* implementation_type;
// Base class for all handler types.
class handler_base
@@ -328,10 +255,10 @@ public:
ptr.reset();
// Indicate that this strand is executing on the current thread.
- call_stack<strand_impl>::context ctx(impl.get());
+ call_stack<strand_impl>::context ctx(impl);
// Make the upcall.
- boost_asio_handler_invoke_helpers::invoke(handler, &handler);
+ boost_asio_handler_invoke_helpers::invoke(handler, handler);
}
static void do_destroy(handler_base* base)
@@ -361,7 +288,7 @@ public:
explicit strand_service(boost::asio::io_service& io_service)
: boost::asio::detail::service_base<strand_service>(io_service),
mutex_(),
- impl_list_(0)
+ salt_(0)
{
}
@@ -370,24 +297,25 @@ public:
{
// Construct a list of all handlers to be destroyed.
boost::asio::detail::mutex::scoped_lock lock(mutex_);
- strand_impl* impl = impl_list_;
handler_base* first_handler = 0;
- while (impl)
+ for (std::size_t i = 0; i < num_implementations; ++i)
{
- if (impl->current_handler_)
+ if (strand_impl* impl = implementations_[i].get())
{
- impl->current_handler_->next_ = first_handler;
- first_handler = impl->current_handler_;
- impl->current_handler_ = 0;
- }
- if (impl->first_waiter_)
- {
- impl->last_waiter_->next_ = first_handler;
- first_handler = impl->first_waiter_;
- impl->first_waiter_ = 0;
- impl->last_waiter_ = 0;
+ if (impl->current_handler_)
+ {
+ impl->current_handler_->next_ = first_handler;
+ first_handler = impl->current_handler_;
+ impl->current_handler_ = 0;
+ }
+ if (impl->first_waiter_)
+ {
+ impl->last_waiter_->next_ = first_handler;
+ first_handler = impl->first_waiter_;
+ impl->first_waiter_ = 0;
+ impl->last_waiter_ = 0;
+ }
}
- impl = impl->next_;
}
// Destroy all handlers without holding the lock.
@@ -403,22 +331,30 @@ public:
// Construct a new strand implementation.
void construct(implementation_type& impl)
{
- impl = implementation_type(new strand_impl(*this));
+ std::size_t index = boost::hash_value(&impl);
+ boost::hash_combine(index, salt_++);
+ index = index % num_implementations;
+
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+ if (!implementations_[index])
+ implementations_[index].reset(new strand_impl);
+ impl = implementations_[index].get();
}
// Destroy a strand implementation.
void destroy(implementation_type& impl)
{
- implementation_type().swap(impl);
+ impl = 0;
}
// Request the io_service to invoke the given handler.
template <typename Handler>
void dispatch(implementation_type& impl, Handler handler)
{
- if (call_stack<strand_impl>::contains(impl.get()))
+ if (call_stack<strand_impl>::contains(impl))
{
- boost_asio_handler_invoke_helpers::invoke(handler, &handler);
+ boost_asio_handler_invoke_helpers::invoke(handler, handler);
}
else
{
@@ -496,37 +432,24 @@ public:
}
private:
- // Mutex to protect access to the linked list of implementations.
+ // Mutex to protect access to the array of implementations.
boost::asio::detail::mutex mutex_;
+ // Number of implementations shared between all strand objects.
+ enum { num_implementations = 193 };
+
// The head of a linked list of all implementations.
- strand_impl* impl_list_;
+ boost::scoped_ptr<strand_impl> implementations_[num_implementations];
+
+ // Extra value used when hashing to prevent recycled memory locations from
+ // getting the same strand implementation.
+ std::size_t salt_;
};
} // namespace detail
} // namespace asio
} // namespace boost
-#if defined(__BORLANDC__)
-
-namespace boost {
-
-inline void intrusive_ptr_add_ref(
- boost::asio::detail::strand_service::strand_impl* p)
-{
- p->add_ref();
-}
-
-inline void intrusive_ptr_release(
- boost::asio::detail::strand_service::strand_impl* p)
-{
- p->release();
-}
-
-} // namespace boost
-
-#endif // defined(__BORLANDC__)
-
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_DETAIL_STRAND_SERVICE_HPP