$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r79966 - trunk/boost/interprocess/ipc
From: igaztanaga_at_[hidden]
Date: 2012-08-11 08:48:53
Author: igaztanaga
Date: 2012-08-11 08:48:52 EDT (Sat, 11 Aug 2012)
New Revision: 79966
URL: http://svn.boost.org/trac/boost/changeset/79966
Log:
Optimized notify usage: called only when full or empty and outside the lock.
Text files modified: 
   trunk/boost/interprocess/ipc/message_queue.hpp |    35 ++++++++++++++++++-----------------     
   1 files changed, 18 insertions(+), 17 deletions(-)
Modified: trunk/boost/interprocess/ipc/message_queue.hpp
==============================================================================
--- trunk/boost/interprocess/ipc/message_queue.hpp	(original)
+++ trunk/boost/interprocess/ipc/message_queue.hpp	2012-08-11 08:48:52 EDT (Sat, 11 Aug 2012)
@@ -697,13 +697,13 @@
       throw interprocess_exception(size_error);
    }
 
+   bool was_empty = false;
    //---------------------------------------------
    scoped_lock<interprocess_mutex> lock(p_hdr->m_mutex);
    //---------------------------------------------
    {
       //If the queue is full execute blocking logic
       if (p_hdr->is_full()) {
-
          switch(block){
             case non_blocking :
                return false;
@@ -724,7 +724,6 @@
                      break;
                   }
                }
-
                while (p_hdr->is_full());
             break;
             default:
@@ -732,10 +731,7 @@
          }
       }
 
-      //Get the first free message from free message queue
-      //ipcdetail::msg_hdr_t<VoidPointer> &free_msg_hdr = p_hdr->first_free_msg_hdr();
-
-//      bool was_empty = p_hdr->is_empty();
+      was_empty = p_hdr->is_empty();
       //Insert the first free message in the priority queue
       ipcdetail::msg_hdr_t<VoidPointer> &free_msg_hdr = p_hdr->queue_free_msg(priority);
 
@@ -749,13 +745,15 @@
 
       //Copy user buffer to the message
       std::memcpy(free_msg_hdr.data(), buffer, buffer_size);
-
-      //If this message changes the queue empty state, notify it to receivers
-//      if (was_empty){
-         p_hdr->m_cond_recv.notify_one();
-//      }
    }  // Lock end
 
+   //Notify outside lock to avoid contention. This might produce some
+   //spurious wakeups, but it's usually far better than notifying inside.
+   //If this message changes the queue empty state, notify it to receivers
+   if (was_empty){
+      p_hdr->m_cond_recv.notify_one();
+   }
+
    return true;
 }
 
@@ -796,6 +794,7 @@
       throw interprocess_exception(size_error);
    }
 
+   bool was_full = false;
    //---------------------------------------------
    scoped_lock<interprocess_mutex> lock(p_hdr->m_mutex);
    //---------------------------------------------
@@ -845,17 +844,19 @@
       //Copy data to receiver's bufers
       std::memcpy(buffer, top_msg.data(), recvd_size);
 
-//      bool was_full = p_hdr->is_full();
+      was_full = p_hdr->is_full();
 
       //Free top message and put it in the free message list
       p_hdr->free_top_msg();
-
-      //If this reception changes the queue full state, notify senders
-//      if (was_full){
-         p_hdr->m_cond_send.notify_one();
-//      }
    }  //Lock end
 
+   //Notify outside lock to avoid contention. This might produce some
+   //spurious wakeups, but it's usually far better than notifying inside.
+   //If this reception changes the queue full state, notify senders
+   if (was_full){
+      p_hdr->m_cond_send.notify_one();
+   }
+
    return true;
 }