Eliminate a lock/unlock pair when rescheduling a strand.
diff --git a/asio/include/asio/detail/impl/strand_service.ipp b/asio/include/asio/detail/impl/strand_service.ipp
index f4290cd..e264fb8 100644
--- a/asio/include/asio/detail/impl/strand_service.ipp
+++ b/asio/include/asio/detail/impl/strand_service.ipp
@@ -37,7 +37,7 @@
     impl_->mutex_.unlock();
 
     if (more_handlers)
-      owner_->post_immediate_completion(impl_);
+      owner_->post_private_immediate_completion(impl_);
   }
 };
 
diff --git a/asio/include/asio/detail/impl/task_io_service.ipp b/asio/include/asio/detail/impl/task_io_service.ipp
index 49f6265..6b3b247 100755
--- a/asio/include/asio/detail/impl/task_io_service.ipp
+++ b/asio/include/asio/detail/impl/task_io_service.ipp
@@ -132,7 +132,7 @@
   this_thread.wakeup_event = &wakeup_event;
   op_queue<operation> private_op_queue;
 #if defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS)
-  this_thread.private_op_queue = one_thread_ == 1 ? &private_op_queue : 0;
+  this_thread.private_op_queue = &private_op_queue;
 #else // defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS)
   this_thread.private_op_queue = 0;
 #endif // defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS)
@@ -183,7 +183,7 @@
   this_thread.wakeup_event = 0;
   op_queue<operation> private_op_queue;
 #if defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS)
-  this_thread.private_op_queue = one_thread_ == 1 ? &private_op_queue : 0;
+  this_thread.private_op_queue = &private_op_queue;
 #else // defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS)
   this_thread.private_op_queue = 0;
 #endif // defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS)
@@ -310,6 +310,32 @@
   }
 }
 
+void task_io_service::post_private_immediate_completion(
+    task_io_service::operation* op)
+{
+  work_started();
+  post_private_deferred_completion(op);
+}
+
+void task_io_service::post_private_deferred_completion(
+    task_io_service::operation* op)
+{
+#if defined(BOOST_HAS_THREADS) && !defined(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;
+    }
+  }
+#endif // defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS)
+
+  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)
 {
diff --git a/asio/include/asio/detail/task_io_service.hpp b/asio/include/asio/detail/task_io_service.hpp
index f7b4870..517cd4d 100644
--- a/asio/include/asio/detail/task_io_service.hpp
+++ b/asio/include/asio/detail/task_io_service.hpp
@@ -111,6 +111,16 @@
   // that work_started() was previously called for each operation.
   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.
+  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.
+  ASIO_DECL void post_private_deferred_completion(operation* op);
+
   // Process unfinished operations as part of a shutdown_service operation.
   // Assumes that work_started() was previously called for the operations.
   ASIO_DECL void abandon_operations(op_queue<operation>& ops);
diff --git a/asio/include/asio/detail/win_iocp_io_service.hpp b/asio/include/asio/detail/win_iocp_io_service.hpp
index 68f209e..20bf28f 100644
--- a/asio/include/asio/detail/win_iocp_io_service.hpp
+++ b/asio/include/asio/detail/win_iocp_io_service.hpp
@@ -134,6 +134,22 @@
   ASIO_DECL void post_deferred_completions(
       op_queue<win_iocp_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.
+  void post_private_immediate_completion(win_iocp_operation* op)
+  {
+    post_immediate_completion(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.
+  void post_private_deferred_completion(win_iocp_operation* op)
+  {
+    post_deferred_completion(op);
+  }
+
   // Process unfinished operations as part of a shutdown_service operation.
   // Assumes that work_started() was previously called for the operations.
   ASIO_DECL void abandon_operations(op_queue<operation>& ops);