From 9d41d45d9662fbb9b39bdf56d8c5562ca63820eb Mon Sep 17 00:00:00 2001
From: Theo J.A. de Vries <t.j.a.devries@imotec.nl>
Date: Mon, 9 May 2011 15:02:15 +0200
Subject: [PATCH] optionally signal() when buffer full in buffered connections

---
 rtt/rtt/ConnPolicy.cpp                    |    6 ++++--
 rtt/rtt/ConnPolicy.hpp                    |    8 +++++++-
 rtt/rtt/internal/ChannelBufferElement.hpp |   17 ++++++++++++++---
 rtt/rtt/internal/ConnFactory.hpp          |    2 +-
 4 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/rtt/rtt/ConnPolicy.cpp b/rtt/rtt/ConnPolicy.cpp
index 3a14868..6740213 100644
--- a/rtt/rtt/ConnPolicy.cpp
+++ b/rtt/rtt/ConnPolicy.cpp
@@ -51,11 +51,12 @@ using namespace std;
 
 namespace RTT
 {
-    ConnPolicy ConnPolicy::buffer(int size, int lock_policy /*= LOCK_FREE*/, bool init_connection /*= false*/, bool pull /*= false*/)
+    ConnPolicy ConnPolicy::buffer(int size, int lock_policy /*= LOCK_FREE*/, bool init_connection /*= false*/, bool pull /*= false*/, bool trigger_only_full /*= false*/)
     {
         ConnPolicy result(BUFFER, lock_policy);
         result.init = init_connection;
         result.pull = pull;
+        result.trigger_only_full = trigger_only_full;
         result.size = size;
         return result;
     }
@@ -65,11 +66,12 @@ namespace RTT
         ConnPolicy result(DATA, lock_policy);
         result.init = init_connection;
         result.pull = pull;
+        result.trigger_only_full = false; // it doesn't matter anyway
         return result;
     }
 
     ConnPolicy::ConnPolicy(int type /* = DATA*/, int lock_policy /*= LOCK_FREE*/)
-        : type(type), init(false), lock_policy(lock_policy), pull(false), size(0), transport(0), data_size(0) {}
+      : type(type), init(false), lock_policy(lock_policy), pull(false), trigger_only_full(false), size(0), transport(0), data_size(0) {}
 
     /** @cond */
     /** This is dead code. We use the boost::serialization now.
diff --git a/rtt/rtt/ConnPolicy.hpp b/rtt/rtt/ConnPolicy.hpp
index 6a97bbb..af13813 100644
--- a/rtt/rtt/ConnPolicy.hpp
+++ b/rtt/rtt/ConnPolicy.hpp
@@ -105,7 +105,7 @@ namespace RTT {
          * @param pull In inter-process cases, should the consumer pull itself ?
          * @return the specified policy.
          */
-        static ConnPolicy buffer(int size, int lock_policy = LOCK_FREE, bool init_connection = false, bool pull = false);
+        static ConnPolicy buffer(int size, int lock_policy = LOCK_FREE, bool init_connection = false, bool pull = false, bool trigger_only_full = false);
 
         /**
          * Create a policy for a (lock-free) shared data connection of a given size.
@@ -141,6 +141,12 @@ namespace RTT {
          * data is available by base::ChannelElementBase::signal()
          */
         bool   pull;
+        /** If false, then the reader side is notified that new
+         * data is available by base::ChannelElementBase::signal() when new data is written.
+         * If true, then it is notified only when the buffer is full. Makes a difference
+         * only when the type is BUFFER.
+         */
+        bool   trigger_only_full;
         /** If the connection is a buffered connection, the size of the buffer */
         int    size;
         /**
diff --git a/rtt/rtt/internal/ChannelBufferElement.hpp b/rtt/rtt/internal/ChannelBufferElement.hpp
index 4243768..ac18a33 100644
--- a/rtt/rtt/internal/ChannelBufferElement.hpp
+++ b/rtt/rtt/internal/ChannelBufferElement.hpp
@@ -54,11 +54,12 @@ namespace RTT { namespace internal {
         typename internal::AssignableDataSource<T>::shared_ptr last;
         bool written;
     public:
+        bool trigger_only_full;
         typedef typename base::ChannelElement<T>::param_t param_t;
         typedef typename base::ChannelElement<T>::reference_t reference_t;
 
-        ChannelBufferElement(typename base::BufferInterface<T>::shared_ptr buffer)
-            : buffer(buffer), last ( new internal::ValueDataSource<T>() ), written(false) {}
+        ChannelBufferElement(typename base::BufferInterface<T>::shared_ptr buffer, bool trigger_only_full = false)
+          : buffer(buffer), last ( new internal::ValueDataSource<T>() ), written(false), trigger_only_full(trigger_only_full) {}
  
         /** Appends a sample at the end of the FIFO
          *
@@ -68,7 +69,17 @@ namespace RTT { namespace internal {
         {
             written = true;
             if (buffer->Push(sample))
-                return this->signal();
+            {
+              if (trigger_only_full)
+              {
+                  if (buffer->full())
+                      return this->signal();
+                  else
+                      return true;
+              }
+              else
+                  return this->signal();
+            }
             return true;
         }
 
diff --git a/rtt/rtt/internal/ConnFactory.hpp b/rtt/rtt/internal/ConnFactory.hpp
index a12d200..95f62ae 100644
--- a/rtt/rtt/internal/ConnFactory.hpp
+++ b/rtt/rtt/internal/ConnFactory.hpp
@@ -150,7 +150,7 @@ namespace RTT
                     buffer_object = new base::BufferUnSync<T>(policy.size, initial_value);
                     break;
                 }
-                return new ChannelBufferElement<T>(typename base::BufferInterface<T>::shared_ptr(buffer_object));
+                return new ChannelBufferElement<T>(typename base::BufferInterface<T>::shared_ptr(buffer_object), policy.trigger_only_full);
             }
             return NULL;
         }
-- 
1.7.5.1

