Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r79549 - in branches/release/boost/asio: . detail detail/impl ssl/detail/impl
From: chris_at_[hidden]
Date: 2012-07-16 02:26:32


Author: chris_kohlhoff
Date: 2012-07-16 02:26:30 EDT (Mon, 16 Jul 2012)
New Revision: 79549
URL: http://svn.boost.org/trac/boost/changeset/79549

Log:
Merge from trunk:

* Make strand destruction a no-op, to allow strand objects to be destroyed after their associated io_service has been destroyed.

* Use the __thread keyword extension when compiling with gcc on linux x86.

* Avoid calling work_finished() if a completion handler creates more work.

* Eliminate redundant call to call_stack::contains(this) when dispatching a completion handler.

* Add support for some newer versions of glibc which provide the epoll_create1 function but always fail with ENOSYS. Fixes #7012

* Use SSE2 load and store fences.

* Throw exception if SSL engine initialisation fails. Fixes #6303

* Fix another regression in buffered_write_stream. Fixes #6310

Added:
   branches/release/boost/asio/detail/keyword_tss_ptr.hpp (contents, props changed)
Text files modified:
   branches/release/boost/asio/buffered_write_stream.hpp | 2
   branches/release/boost/asio/detail/atomic_count.hpp | 3
   branches/release/boost/asio/detail/config.hpp | 11 ++
   branches/release/boost/asio/detail/gcc_x86_fenced_block.hpp | 21 ++++-
   branches/release/boost/asio/detail/impl/epoll_reactor.ipp | 2
   branches/release/boost/asio/detail/impl/strand_service.hpp | 5 -
   branches/release/boost/asio/detail/impl/task_io_service.hpp | 2
   branches/release/boost/asio/detail/impl/task_io_service.ipp | 148 +++++++++++++++++++++++----------------
   branches/release/boost/asio/detail/strand_service.hpp | 3
   branches/release/boost/asio/detail/task_io_service.hpp | 30 +++++--
   branches/release/boost/asio/detail/tss_ptr.hpp | 6 +
   branches/release/boost/asio/ssl/detail/impl/engine.ipp | 10 ++
   branches/release/boost/asio/strand.hpp | 1
   13 files changed, 154 insertions(+), 90 deletions(-)

Modified: branches/release/boost/asio/buffered_write_stream.hpp
==============================================================================
--- branches/release/boost/asio/buffered_write_stream.hpp (original)
+++ branches/release/boost/asio/buffered_write_stream.hpp 2012-07-16 02:26:30 EDT (Mon, 16 Jul 2012)
@@ -232,7 +232,7 @@
           ? bytes_avail : space_avail;
         storage_.resize(orig_size + length);
         std::size_t bytes_copied = boost::asio::buffer_copy(
- storage_.data(), buffers_, length);
+ storage_.data() + orig_size, buffers_, length);
 
         io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied));
       }

Modified: branches/release/boost/asio/detail/atomic_count.hpp
==============================================================================
--- branches/release/boost/asio/detail/atomic_count.hpp (original)
+++ branches/release/boost/asio/detail/atomic_count.hpp 2012-07-16 02:26:30 EDT (Mon, 16 Jul 2012)
@@ -31,10 +31,13 @@
 
 #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
 typedef long atomic_count;
+inline void increment(atomic_count& a, long b) { a += b; }
 #elif defined(BOOST_ASIO_HAS_STD_ATOMIC)
 typedef std::atomic<long> atomic_count;
+inline void increment(atomic_count& a, long b) { a += b; }
 #else // defined(BOOST_ASIO_HAS_STD_ATOMIC)
 typedef boost::detail::atomic_count atomic_count;
+inline void increment(atomic_count& a, long b) { while (b > 0) ++a, --b; }
 #endif // defined(BOOST_ASIO_HAS_STD_ATOMIC)
 
 } // namespace detail

Modified: branches/release/boost/asio/detail/config.hpp
==============================================================================
--- branches/release/boost/asio/detail/config.hpp (original)
+++ branches/release/boost/asio/detail/config.hpp 2012-07-16 02:26:30 EDT (Mon, 16 Jul 2012)
@@ -371,4 +371,15 @@
 # endif // !defined(UNDER_CE)
 #endif // !defined(BOOST_ASIO_DISABLE_SIGNAL)
 
+// Support for the __thread keyword extension.
+#if !defined(BOOST_ASIO_DISABLE_THREAD_KEYWORD_EXTENSION)
+# if defined(__linux__)
+# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+# if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)
+# define BOOST_ASIO_HAS_THREAD_KEYWORD_EXTENSION 1
+# endif // ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)
+# endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+# endif // defined(__linux__)
+#endif // !defined(BOOST_ASIO_DISABLE_THREAD_KEYWORD_EXTENSION)
+
 #endif // BOOST_ASIO_DETAIL_CONFIG_HPP

Modified: branches/release/boost/asio/detail/gcc_x86_fenced_block.hpp
==============================================================================
--- branches/release/boost/asio/detail/gcc_x86_fenced_block.hpp (original)
+++ branches/release/boost/asio/detail/gcc_x86_fenced_block.hpp 2012-07-16 02:26:30 EDT (Mon, 16 Jul 2012)
@@ -40,17 +40,17 @@
   // Constructor for a full fenced block.
   explicit gcc_x86_fenced_block(full_t)
   {
- barrier1();
+ lbarrier();
   }
 
   // Destructor.
   ~gcc_x86_fenced_block()
   {
- barrier2();
+ sbarrier();
   }
 
 private:
- static int barrier1()
+ static int barrier()
   {
     int r = 0, m = 1;
     __asm__ __volatile__ (
@@ -61,12 +61,21 @@
     return r;
   }
 
- static void barrier2()
+ static void lbarrier()
   {
 #if defined(__SSE2__)
- __asm__ __volatile__ ("mfence" ::: "memory");
+ __asm__ __volatile__ ("lfence" ::: "memory");
 #else // defined(__SSE2__)
- barrier1();
+ barrier();
+#endif // defined(__SSE2__)
+ }
+
+ static void sbarrier()
+ {
+#if defined(__SSE2__)
+ __asm__ __volatile__ ("sfence" ::: "memory");
+#else // defined(__SSE2__)
+ barrier();
 #endif // defined(__SSE2__)
   }
 };

Modified: branches/release/boost/asio/detail/impl/epoll_reactor.ipp
==============================================================================
--- branches/release/boost/asio/detail/impl/epoll_reactor.ipp (original)
+++ branches/release/boost/asio/detail/impl/epoll_reactor.ipp 2012-07-16 02:26:30 EDT (Mon, 16 Jul 2012)
@@ -466,7 +466,7 @@
   errno = EINVAL;
 #endif // defined(EPOLL_CLOEXEC)
 
- if (fd == -1 && errno == EINVAL)
+ if (fd == -1 && (errno == EINVAL || errno == ENOSYS))
   {
     fd = epoll_create(epoll_size);
     if (fd != -1)

Modified: branches/release/boost/asio/detail/impl/strand_service.hpp
==============================================================================
--- branches/release/boost/asio/detail/impl/strand_service.hpp (original)
+++ branches/release/boost/asio/detail/impl/strand_service.hpp 2012-07-16 02:26:30 EDT (Mon, 16 Jul 2012)
@@ -50,11 +50,6 @@
   }
 };
 
-inline void strand_service::destroy(strand_service::implementation_type& impl)
-{
- impl = 0;
-}
-
 template <typename Handler>
 void strand_service::dispatch(strand_service::implementation_type& impl,
     Handler handler)

Modified: branches/release/boost/asio/detail/impl/task_io_service.hpp
==============================================================================
--- branches/release/boost/asio/detail/impl/task_io_service.hpp (original)
+++ branches/release/boost/asio/detail/impl/task_io_service.hpp 2012-07-16 02:26:30 EDT (Mon, 16 Jul 2012)
@@ -45,7 +45,7 @@
 
     BOOST_ASIO_HANDLER_CREATION((p.p, "io_service", this, "dispatch"));
 
- post_immediate_completion(p.p);
+ post_non_private_immediate_completion(p.p);
     p.v = p.p = 0;
   }
 }

Modified: branches/release/boost/asio/detail/impl/task_io_service.ipp
==============================================================================
--- branches/release/boost/asio/detail/impl/task_io_service.ipp (original)
+++ branches/release/boost/asio/detail/impl/task_io_service.ipp 2012-07-16 02:26:30 EDT (Mon, 16 Jul 2012)
@@ -30,48 +30,67 @@
 namespace asio {
 namespace detail {
 
+struct task_io_service::thread_info
+{
+ event* wakeup_event;
+ op_queue<operation> private_op_queue;
+ long private_outstanding_work;
+ thread_info* next;
+};
+
 struct task_io_service::task_cleanup
 {
   ~task_cleanup()
   {
+ if (this_thread_->private_outstanding_work > 0)
+ {
+ boost::asio::detail::increment(
+ task_io_service_->outstanding_work_,
+ this_thread_->private_outstanding_work);
+ }
+ this_thread_->private_outstanding_work = 0;
+
     // Enqueue the completed operations and reinsert the task at the end of
     // the operation queue.
     lock_->lock();
     task_io_service_->task_interrupted_ = true;
- task_io_service_->op_queue_.push(*ops_);
+ task_io_service_->op_queue_.push(this_thread_->private_op_queue);
     task_io_service_->op_queue_.push(&task_io_service_->task_operation_);
   }
 
   task_io_service* task_io_service_;
   mutex::scoped_lock* lock_;
- op_queue<operation>* ops_;
+ thread_info* this_thread_;
 };
 
 struct task_io_service::work_cleanup
 {
   ~work_cleanup()
   {
- task_io_service_->work_finished();
+ if (this_thread_->private_outstanding_work > 1)
+ {
+ boost::asio::detail::increment(
+ task_io_service_->outstanding_work_,
+ this_thread_->private_outstanding_work - 1);
+ }
+ else if (this_thread_->private_outstanding_work < 1)
+ {
+ task_io_service_->work_finished();
+ }
+ this_thread_->private_outstanding_work = 0;
 
 #if defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
- if (!ops_->empty())
+ if (!this_thread_->private_op_queue.empty())
     {
       lock_->lock();
- task_io_service_->op_queue_.push(*ops_);
+ task_io_service_->op_queue_.push(this_thread_->private_op_queue);
     }
 #endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
   }
 
   task_io_service* task_io_service_;
   mutex::scoped_lock* lock_;
- op_queue<operation>* ops_;
-};
-
-struct task_io_service::thread_info
-{
- event* wakeup_event;
- op_queue<operation>* private_op_queue;
- thread_info* next;
+ thread_info* this_thread_;
 };
 
 task_io_service::task_io_service(
@@ -131,19 +150,14 @@
   thread_info this_thread;
   event wakeup_event;
   this_thread.wakeup_event = &wakeup_event;
- op_queue<operation> private_op_queue;
-#if defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
- this_thread.private_op_queue = &private_op_queue;
-#else // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
- this_thread.private_op_queue = 0;
-#endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+ this_thread.private_outstanding_work = 0;
   this_thread.next = 0;
   thread_call_stack::context ctx(this, this_thread);
 
   mutex::scoped_lock lock(mutex_);
 
   std::size_t n = 0;
- for (; do_run_one(lock, this_thread, private_op_queue, ec); lock.lock())
+ for (; do_run_one(lock, this_thread, ec); lock.lock())
     if (n != (std::numeric_limits<std::size_t>::max)())
       ++n;
   return n;
@@ -161,14 +175,13 @@
   thread_info this_thread;
   event wakeup_event;
   this_thread.wakeup_event = &wakeup_event;
- op_queue<operation> private_op_queue;
- this_thread.private_op_queue = 0;
+ this_thread.private_outstanding_work = 0;
   this_thread.next = 0;
   thread_call_stack::context ctx(this, this_thread);
 
   mutex::scoped_lock lock(mutex_);
 
- return do_run_one(lock, this_thread, private_op_queue, ec);
+ return do_run_one(lock, this_thread, ec);
 }
 
 std::size_t task_io_service::poll(boost::system::error_code& ec)
@@ -182,12 +195,7 @@
 
   thread_info this_thread;
   this_thread.wakeup_event = 0;
- op_queue<operation> private_op_queue;
-#if defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
- this_thread.private_op_queue = &private_op_queue;
-#else // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
- this_thread.private_op_queue = 0;
-#endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+ this_thread.private_outstanding_work = 0;
   this_thread.next = 0;
   thread_call_stack::context ctx(this, this_thread);
 
@@ -199,12 +207,11 @@
   // queue now.
   if (one_thread_)
     if (thread_info* outer_thread_info = ctx.next_by_key())
- if (outer_thread_info->private_op_queue)
- op_queue_.push(*outer_thread_info->private_op_queue);
+ op_queue_.push(outer_thread_info->private_op_queue);
 #endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
 
   std::size_t n = 0;
- for (; do_poll_one(lock, private_op_queue, ec); lock.lock())
+ for (; do_poll_one(lock, this_thread, ec); lock.lock())
     if (n != (std::numeric_limits<std::size_t>::max)())
       ++n;
   return n;
@@ -221,8 +228,7 @@
 
   thread_info this_thread;
   this_thread.wakeup_event = 0;
- op_queue<operation> private_op_queue;
- this_thread.private_op_queue = 0;
+ this_thread.private_outstanding_work = 0;
   this_thread.next = 0;
   thread_call_stack::context ctx(this, this_thread);
 
@@ -234,11 +240,10 @@
   // queue now.
   if (one_thread_)
     if (thread_info* outer_thread_info = ctx.next_by_key())
- if (outer_thread_info->private_op_queue)
- op_queue_.push(*outer_thread_info->private_op_queue);
+ op_queue_.push(outer_thread_info->private_op_queue);
 #endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
 
- return do_poll_one(lock, private_op_queue, ec);
+ return do_poll_one(lock, this_thread, ec);
 }
 
 void task_io_service::stop()
@@ -261,8 +266,22 @@
 
 void task_io_service::post_immediate_completion(task_io_service::operation* op)
 {
+#if defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+ if (one_thread_)
+ {
+ if (thread_info* this_thread = thread_call_stack::contains(this))
+ {
+ ++this_thread->private_outstanding_work;
+ this_thread->private_op_queue.push(op);
+ return;
+ }
+ }
+#endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+
   work_started();
- post_deferred_completion(op);
+ mutex::scoped_lock lock(mutex_);
+ op_queue_.push(op);
+ wake_one_thread_and_unlock(lock);
 }
 
 void task_io_service::post_deferred_completion(task_io_service::operation* op)
@@ -272,11 +291,8 @@
   {
     if (thread_info* this_thread = thread_call_stack::contains(this))
     {
- if (this_thread->private_op_queue)
- {
- this_thread->private_op_queue->push(op);
- return;
- }
+ this_thread->private_op_queue.push(op);
+ return;
     }
   }
 #endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
@@ -296,11 +312,8 @@
     {
       if (thread_info* this_thread = thread_call_stack::contains(this))
       {
- if (this_thread->private_op_queue)
- {
- this_thread->private_op_queue->push(ops);
- return;
- }
+ this_thread->private_op_queue.push(ops);
+ return;
       }
     }
 #endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
@@ -324,11 +337,8 @@
 #if defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
   if (thread_info* this_thread = thread_call_stack::contains(this))
   {
- if (this_thread->private_op_queue)
- {
- this_thread->private_op_queue->push(op);
- return;
- }
+ this_thread->private_op_queue.push(op);
+ return;
   }
 #endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
 
@@ -337,6 +347,21 @@
   wake_one_thread_and_unlock(lock);
 }
 
+void task_io_service::post_non_private_immediate_completion(
+ task_io_service::operation* op)
+{
+ work_started();
+ post_non_private_deferred_completion(op);
+}
+
+void task_io_service::post_non_private_deferred_completion(
+ task_io_service::operation* op)
+{
+ mutex::scoped_lock lock(mutex_);
+ op_queue_.push(op);
+ wake_one_thread_and_unlock(lock);
+}
+
 void task_io_service::abandon_operations(
     op_queue<task_io_service::operation>& ops)
 {
@@ -346,7 +371,7 @@
 
 std::size_t task_io_service::do_run_one(mutex::scoped_lock& lock,
     task_io_service::thread_info& this_thread,
- op_queue<operation>& private_op_queue, const boost::system::error_code& ec)
+ const boost::system::error_code& ec)
 {
   while (!stopped_)
   {
@@ -369,13 +394,13 @@
         else
           lock.unlock();
 
- task_cleanup on_exit = { this, &lock, &private_op_queue };
+ task_cleanup on_exit = { this, &lock, &this_thread };
         (void)on_exit;
 
         // Run the task. May throw an exception. Only block if the operation
         // queue is empty and we're not polling, otherwise we want to return
         // as soon as possible.
- task_->run(!more_handlers, private_op_queue);
+ task_->run(!more_handlers, this_thread.private_op_queue);
       }
       else
       {
@@ -387,7 +412,7 @@
           lock.unlock();
 
         // Ensure the count of outstanding work is decremented on block exit.
- work_cleanup on_exit = { this, &lock, &private_op_queue };
+ work_cleanup on_exit = { this, &lock, &this_thread };
         (void)on_exit;
 
         // Complete the operation. May throw an exception. Deletes the object.
@@ -410,7 +435,8 @@
 }
 
 std::size_t task_io_service::do_poll_one(mutex::scoped_lock& lock,
- op_queue<operation>& private_op_queue, const boost::system::error_code& ec)
+ task_io_service::thread_info& this_thread,
+ const boost::system::error_code& ec)
 {
   if (stopped_)
     return 0;
@@ -422,13 +448,13 @@
     lock.unlock();
 
     {
- task_cleanup c = { this, &lock, &private_op_queue };
+ task_cleanup c = { this, &lock, &this_thread };
       (void)c;
 
       // Run the task. May throw an exception. Only block if the operation
       // queue is empty and we're not polling, otherwise we want to return
       // as soon as possible.
- task_->run(false, private_op_queue);
+ task_->run(false, this_thread.private_op_queue);
     }
 
     o = op_queue_.front();
@@ -450,7 +476,7 @@
     lock.unlock();
 
   // Ensure the count of outstanding work is decremented on block exit.
- work_cleanup on_exit = { this, &lock, &private_op_queue };
+ work_cleanup on_exit = { this, &lock, &this_thread };
   (void)on_exit;
 
   // Complete the operation. May throw an exception. Deletes the object.

Added: branches/release/boost/asio/detail/keyword_tss_ptr.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/asio/detail/keyword_tss_ptr.hpp 2012-07-16 02:26:30 EDT (Mon, 16 Jul 2012)
@@ -0,0 +1,72 @@
+//
+// detail/keyword_tss_ptr.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2012 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_KEYWORD_TSS_PTR_HPP
+#define BOOST_ASIO_DETAIL_KEYWORD_TSS_PTR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_THREAD_KEYWORD_EXTENSION)
+
+#include <boost/asio/detail/noncopyable.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename T>
+class keyword_tss_ptr
+ : private noncopyable
+{
+public:
+ // Constructor.
+ keyword_tss_ptr()
+ {
+ }
+
+ // Destructor.
+ ~keyword_tss_ptr()
+ {
+ }
+
+ // Get the value.
+ operator T*() const
+ {
+ return value_;
+ }
+
+ // Set the value.
+ void operator=(T* value)
+ {
+ value_ = value;
+ }
+
+private:
+ static __thread T* value_;
+};
+
+template <typename T>
+__thread T* keyword_tss_ptr<T>::value_;
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_THREAD_KEYWORD_EXTENSION)
+
+#endif // BOOST_ASIO_DETAIL_KEYWORD_TSS_PTR_HPP

Modified: branches/release/boost/asio/detail/strand_service.hpp
==============================================================================
--- branches/release/boost/asio/detail/strand_service.hpp (original)
+++ branches/release/boost/asio/detail/strand_service.hpp 2012-07-16 02:26:30 EDT (Mon, 16 Jul 2012)
@@ -84,9 +84,6 @@
   // Construct a new strand implementation.
   BOOST_ASIO_DECL void construct(implementation_type& impl);
 
- // Destroy a strand implementation.
- void destroy(implementation_type& impl);
-
   // Request the io_service to invoke the given handler.
   template <typename Handler>
   void dispatch(implementation_type& impl, Handler handler);

Modified: branches/release/boost/asio/detail/task_io_service.hpp
==============================================================================
--- branches/release/boost/asio/detail/task_io_service.hpp (original)
+++ branches/release/boost/asio/detail/task_io_service.hpp 2012-07-16 02:26:30 EDT (Mon, 16 Jul 2012)
@@ -112,14 +112,14 @@
   // that work_started() was previously called for each operation.
   BOOST_ASIO_DECL void post_deferred_completions(op_queue<operation>& ops);
 
- // Request invocation of the given operation using the thread-private queue
- // and return immediately. Assumes that work_started() has not yet been
- // called for the operation.
+ // Request invocation of the given operation, preferring the thread-private
+ // queue if available, and return immediately. Assumes that work_started()
+ // has not yet been called for the operation.
   BOOST_ASIO_DECL void post_private_immediate_completion(operation* op);
 
- // Request invocation of the given operation using the thread-private queue
- // and return immediately. Assumes that work_started() was previously called
- // for the operation.
+ // Request invocation of the given operation, preferring the thread-private
+ // queue if available, and return immediately. Assumes that work_started()
+ // was previously called for the operation.
   BOOST_ASIO_DECL void post_private_deferred_completion(operation* op);
 
   // Process unfinished operations as part of a shutdown_service operation.
@@ -130,15 +130,23 @@
   // Structure containing information about an idle thread.
   struct thread_info;
 
- // Run at most one operation. Blocks only if this_idle_thread is non-null.
+ // Request invocation of the given operation, avoiding the thread-private
+ // queue, and return immediately. Assumes that work_started() has not yet
+ // been called for the operation.
+ BOOST_ASIO_DECL void post_non_private_immediate_completion(operation* op);
+
+ // Request invocation of the given operation, avoiding the thread-private
+ // queue, and return immediately. Assumes that work_started() was previously
+ // called for the operation.
+ BOOST_ASIO_DECL void post_non_private_deferred_completion(operation* op);
+
+ // Run at most one operation. May block.
   BOOST_ASIO_DECL std::size_t do_run_one(mutex::scoped_lock& lock,
- thread_info& this_thread, op_queue<operation>& private_op_queue,
- const boost::system::error_code& ec);
+ thread_info& this_thread, const boost::system::error_code& ec);
 
   // Poll for at most one operation.
   BOOST_ASIO_DECL std::size_t do_poll_one(mutex::scoped_lock& lock,
- op_queue<operation>& private_op_queue,
- const boost::system::error_code& ec);
+ thread_info& this_thread, const boost::system::error_code& ec);
 
   // Stop the task and all idle threads.
   BOOST_ASIO_DECL void stop_all_threads(mutex::scoped_lock& lock);

Modified: branches/release/boost/asio/detail/tss_ptr.hpp
==============================================================================
--- branches/release/boost/asio/detail/tss_ptr.hpp (original)
+++ branches/release/boost/asio/detail/tss_ptr.hpp 2012-07-16 02:26:30 EDT (Mon, 16 Jul 2012)
@@ -19,6 +19,8 @@
 
 #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
 # include <boost/asio/detail/null_tss_ptr.hpp>
+#elif defined(BOOST_ASIO_HAS_THREAD_KEYWORD_EXTENSION)
+# include <boost/asio/detail/keyword_tss_ptr.hpp>
 #elif defined(BOOST_WINDOWS)
 # include <boost/asio/detail/win_tss_ptr.hpp>
 #elif defined(BOOST_HAS_PTHREADS)
@@ -37,6 +39,8 @@
 class tss_ptr
 #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
   : public null_tss_ptr<T>
+#elif defined(BOOST_ASIO_HAS_THREAD_KEYWORD_EXTENSION)
+ : public keyword_tss_ptr<T>
 #elif defined(BOOST_WINDOWS)
   : public win_tss_ptr<T>
 #elif defined(BOOST_HAS_PTHREADS)
@@ -48,6 +52,8 @@
   {
 #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
     null_tss_ptr<T>::operator=(value);
+#elif defined(BOOST_ASIO_HAS_THREAD_KEYWORD_EXTENSION)
+ keyword_tss_ptr<T>::operator=(value);
 #elif defined(BOOST_WINDOWS)
     win_tss_ptr<T>::operator=(value);
 #elif defined(BOOST_HAS_PTHREADS)

Modified: branches/release/boost/asio/ssl/detail/impl/engine.ipp
==============================================================================
--- branches/release/boost/asio/ssl/detail/impl/engine.ipp (original)
+++ branches/release/boost/asio/ssl/detail/impl/engine.ipp 2012-07-16 02:26:30 EDT (Mon, 16 Jul 2012)
@@ -18,7 +18,10 @@
 #include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_ASIO_ENABLE_OLD_SSL)
+# include <boost/asio/detail/throw_error.hpp>
+# include <boost/asio/error.hpp>
 # include <boost/asio/ssl/detail/engine.hpp>
+# include <boost/asio/ssl/error.hpp>
 # include <boost/asio/ssl/verify_context.hpp>
 #endif // !defined(BOOST_ASIO_ENABLE_OLD_SSL)
 
@@ -34,6 +37,13 @@
 engine::engine(SSL_CTX* context)
   : ssl_(::SSL_new(context))
 {
+ if (!ssl_)
+ {
+ boost::system::error_code ec(::ERR_get_error(),
+ boost::asio::error::get_ssl_category());
+ boost::asio::detail::throw_error(ec, "engine");
+ }
+
   accept_mutex().init();
 
   ::SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE);

Modified: branches/release/boost/asio/strand.hpp
==============================================================================
--- branches/release/boost/asio/strand.hpp (original)
+++ branches/release/boost/asio/strand.hpp 2012-07-16 02:26:30 EDT (Mon, 16 Jul 2012)
@@ -105,7 +105,6 @@
    */
   ~strand()
   {
- service_.destroy(impl_);
   }
 
   /// Get the io_service associated with the strand.


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk