Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r77002 - in branches/release: boost/asio/detail boost/asio/detail/impl libs/asio/doc
From: chris_at_[hidden]
Date: 2012-02-12 16:20:30


Author: chris_kohlhoff
Date: 2012-02-12 16:20:29 EST (Sun, 12 Feb 2012)
New Revision: 77002
URL: http://svn.boost.org/trac/boost/changeset/77002

Log:
Merge [76990] from trunk:

Reverted earlier change to allow some speculative operations to be performed
without holding the lock, as it introduced a race condition in some
multithreaded scenarios.

Text files modified:
   branches/release/boost/asio/detail/epoll_reactor.hpp | 2 --
   branches/release/boost/asio/detail/impl/epoll_reactor.ipp | 35 ++---------------------------------
   branches/release/boost/asio/detail/impl/kqueue_reactor.ipp | 32 ++------------------------------
   branches/release/boost/asio/detail/kqueue_reactor.hpp | 2 --
   branches/release/libs/asio/doc/history.qbk | 3 +++
   5 files changed, 7 insertions(+), 67 deletions(-)

Modified: branches/release/boost/asio/detail/epoll_reactor.hpp
==============================================================================
--- branches/release/boost/asio/detail/epoll_reactor.hpp (original)
+++ branches/release/boost/asio/detail/epoll_reactor.hpp 2012-02-12 16:20:29 EST (Sun, 12 Feb 2012)
@@ -56,8 +56,6 @@
     descriptor_state* next_;
     descriptor_state* prev_;
 
- bool op_queue_is_empty_[max_ops];
-
     mutex mutex_;
     epoll_reactor* reactor_;
     int descriptor_;

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-02-12 16:20:29 EST (Sun, 12 Feb 2012)
@@ -156,10 +156,6 @@
     descriptor_data->reactor_ = this;
     descriptor_data->descriptor_ = descriptor;
     descriptor_data->shutdown_ = false;
-
- for (int i = 0; i < max_ops; ++i)
- descriptor_data->op_queue_is_empty_[i] =
- descriptor_data->op_queue_[i].empty();
   }
 
   epoll_event ev = { 0, { 0 } };
@@ -185,10 +181,6 @@
     descriptor_data->descriptor_ = descriptor;
     descriptor_data->shutdown_ = false;
     descriptor_data->op_queue_[op_type].push(op);
-
- for (int i = 0; i < max_ops; ++i)
- descriptor_data->op_queue_is_empty_[i] =
- descriptor_data->op_queue_[i].empty();
   }
 
   epoll_event ev = { 0, { 0 } };
@@ -220,22 +212,6 @@
     return;
   }
 
- bool perform_speculative = allow_speculative;
- if (perform_speculative)
- {
- if (descriptor_data->op_queue_is_empty_[op_type]
- && (op_type != read_op
- || descriptor_data->op_queue_is_empty_[except_op]))
- {
- if (op->perform())
- {
- io_service_.post_immediate_completion(op);
- return;
- }
- perform_speculative = false;
- }
- }
-
   mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
 
   if (descriptor_data->shutdown_)
@@ -244,17 +220,11 @@
     return;
   }
 
- for (int i = 0; i < max_ops; ++i)
- descriptor_data->op_queue_is_empty_[i] =
- descriptor_data->op_queue_[i].empty();
-
- if (descriptor_data->op_queue_is_empty_[op_type])
+ if (descriptor_data->op_queue_[op_type].empty())
   {
     if (allow_speculative)
     {
- if (perform_speculative
- && (op_type != read_op
- || descriptor_data->op_queue_is_empty_[except_op]))
+ if (op_type != read_op || descriptor_data->op_queue_[except_op].empty())
       {
         if (op->perform())
         {
@@ -275,7 +245,6 @@
   }
 
   descriptor_data->op_queue_[op_type].push(op);
- descriptor_data->op_queue_is_empty_[op_type] = false;
   io_service_.work_started();
 }
 

Modified: branches/release/boost/asio/detail/impl/kqueue_reactor.ipp
==============================================================================
--- branches/release/boost/asio/detail/impl/kqueue_reactor.ipp (original)
+++ branches/release/boost/asio/detail/impl/kqueue_reactor.ipp 2012-02-12 16:20:29 EST (Sun, 12 Feb 2012)
@@ -133,10 +133,6 @@
   descriptor_data->descriptor_ = descriptor;
   descriptor_data->shutdown_ = false;
 
- for (int i = 0; i < max_ops; ++i)
- descriptor_data->op_queue_is_empty_[i] =
- descriptor_data->op_queue_[i].empty();
-
   return 0;
 }
 
@@ -152,10 +148,6 @@
   descriptor_data->shutdown_ = false;
   descriptor_data->op_queue_[op_type].push(op);
 
- for (int i = 0; i < max_ops; ++i)
- descriptor_data->op_queue_is_empty_[i] =
- descriptor_data->op_queue_[i].empty();
-
   struct kevent event;
   switch (op_type)
   {
@@ -196,21 +188,6 @@
     return;
   }
 
- if (allow_speculative)
- {
- if (descriptor_data->op_queue_is_empty_[op_type]
- && (op_type != read_op
- || descriptor_data->op_queue_is_empty_[except_op]))
- {
- if (op->perform())
- {
- io_service_.post_immediate_completion(op);
- return;
- }
- allow_speculative = false;
- }
- }
-
   mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
 
   if (descriptor_data->shutdown_)
@@ -219,16 +196,12 @@
     return;
   }
 
- for (int i = 0; i < max_ops; ++i)
- descriptor_data->op_queue_is_empty_[i] =
- descriptor_data->op_queue_[i].empty();
-
- bool first = descriptor_data->op_queue_is_empty_[op_type];
+ bool first = descriptor_data->op_queue_[op_type].empty();
   if (first)
   {
     if (allow_speculative)
     {
- if (op_type != read_op || descriptor_data->op_queue_is_empty_[except_op])
+ if (op_type != read_op || descriptor_data->op_queue_[except_op].empty())
       {
         if (op->perform())
         {
@@ -241,7 +214,6 @@
   }
 
   descriptor_data->op_queue_[op_type].push(op);
- descriptor_data->op_queue_is_empty_[op_type] = false;
   io_service_.work_started();
 
   if (first)

Modified: branches/release/boost/asio/detail/kqueue_reactor.hpp
==============================================================================
--- branches/release/boost/asio/detail/kqueue_reactor.hpp (original)
+++ branches/release/boost/asio/detail/kqueue_reactor.hpp 2012-02-12 16:20:29 EST (Sun, 12 Feb 2012)
@@ -66,8 +66,6 @@
     descriptor_state* next_;
     descriptor_state* prev_;
 
- bool op_queue_is_empty_[max_ops];
-
     mutex mutex_;
     int descriptor_;
     op_queue<reactor_op> op_queue_[max_ops];

Modified: branches/release/libs/asio/doc/history.qbk
==============================================================================
--- branches/release/libs/asio/doc/history.qbk (original)
+++ branches/release/libs/asio/doc/history.qbk 2012-02-12 16:20:29 EST (Sun, 12 Feb 2012)
@@ -29,6 +29,9 @@
 * Fixed a non-paged pool "leak" on Windows when an `io_service` is repeatedly
   run without anything to do
   ([@https://svn.boost.org/trac/boost/ticket/6321 #6321]).
+* Reverted earlier change to allow some speculative operations to be performed
+ without holding the lock, as it introduced a race condition in some
+ multithreaded scenarios.
 
 [heading Asio 1.6.1 / Boost 1.48]
 


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