diff --git a/openrtx/include/core/ringbuf.h b/openrtx/include/core/ringbuf.h index 419e427b..77385e6b 100644 --- a/openrtx/include/core/ringbuf.h +++ b/openrtx/include/core/ringbuf.h @@ -108,25 +108,27 @@ public: { pthread_mutex_lock(&mutex); - if(numElements == 0) + if((numElements == 0) && (blocking == false)) { - if(blocking) - { - while(numElements == 0) - { - pthread_cond_wait(¬_empty, &mutex); - } - } - else - { - pthread_mutex_unlock(&mutex); - return false; - } + // No elements present and non-blocking call: unlock mutex and return + pthread_mutex_unlock(&mutex); + return false; } - elem = data[readPos]; - readPos = (readPos + 1) % N; + // The call is blocking: wait until there is something into the queue + while(numElements == 0) + { + pthread_cond_wait(¬_empty, &mutex); + } + + // At least one element present pop one. + elem = data[readPos]; + readPos = (readPos + 1) % N; + + // Signal that the queue is no more full + if(numElements >= N) pthread_cond_signal(¬_full); numElements -= 1; + pthread_mutex_unlock(&mutex); return true; @@ -152,6 +154,27 @@ public: return numElements >= N; } + /** + * Discard one element from the buffer's tail, creating a new empty slot. + * In case the buffer is full calling this function unlocks the eventual + * threads waiting to push data. + */ + void eraseElement() + { + // Nothing to erase + if(numElements == 0) return; + + pthread_mutex_lock(&mutex); + + // Chomp away one element just by advancing the read pointer. + readPos = (readPos + 1) % N; + + if(numElements >= N) pthread_cond_signal(¬_full); + numElements -= 1; + + pthread_mutex_unlock(&mutex); + } + private: size_t readPos; ///< Read pointer.