Skip to content

Instantly share code, notes, and snippets.

@matiasfha
Created June 9, 2011 16:32
Show Gist options
  • Save matiasfha/1017119 to your computer and use it in GitHub Desktop.
Save matiasfha/1017119 to your computer and use it in GitHub Desktop.
Buffer Circular (boost)
/**
This file is part of VisionStreaming.
VisionStreaming is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
VisionStreaming is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with VisionStreaming. If not, see <http://www.gnu.org/licenses/>.
@version: 0.1
@author : Matías Hernández <mhernandez@visionlabs.cl>
@date : 23/04/2011
*/
/** Esta clase representa un buffer circular utilizado para comunidar distintos hilos
resolviendo el problema productor/consumidor
Está implementada basandose en boost::circular_buffer_space_optimized
Escribe de forma infinita en el buffer, si se llega al tamaño maximo sobreescribe los datos iniciales
Para leer espera que el buffer tenga algo que leer
*/
#ifndef CIRCULARBUFFER_H
#define CIRCULARBUFFER_H
#include <boost/circular_buffer.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/thread.hpp>
#include <boost/progress.hpp>
#include <boost/bind.hpp>
namespace Utils{
template <class T>
class CircularBuffer {
public:
typedef boost::circular_buffer_space_optimized<T> container_type;
typedef typename container_type::size_type size_type;
typedef typename container_type::value_type value_type;
explicit CircularBuffer(size_type capacity) : m_unread(0), m_container(capacity) {}
void push_front(const value_type& item) {
boost::mutex::scoped_lock lock(m_mutex);
m_not_full.wait(lock, boost::bind(&CircularBuffer<value_type>::is_not_full, this));
m_container.push_front(item);
++m_unread;
lock.unlock();
m_not_empty.notify_one();
}
void pop_back(value_type* pItem) {
boost::mutex::scoped_lock lock(m_mutex);
m_not_empty.wait(lock, boost::bind(&CircularBuffer<value_type>::is_not_empty, this));
*pItem = m_container[--m_unread];
lock.unlock();
m_not_full.notify_one();
}
size_type actual_size(){
return m_unread;
}
size_type max_size(){
return m_container.capacity();
}
bool is_not_empty() const { return m_unread > 0; }
bool is_not_full() const { return m_unread < m_container.capacity(); }
private:
CircularBuffer(const CircularBuffer&); // Disabled copy constructor
CircularBuffer& operator = (const CircularBuffer&); // Disabled assign operator
size_type m_unread;
container_type m_container;
boost::mutex m_mutex;
boost::condition m_not_empty;
boost::condition m_not_full;
};
}
#endif // CIRCULARBUFFER_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment