This has been done in the
ACE-Project and you can use different aproaches to that queue- put/get methods with semaphores. Best is to use premade classes, when you insist on creating them yourself:
template <class T> class Blocking_Queue
{
public:
Blocking_Queue()
{
pthread_mutex_init(&_lock, NULL);
pthread_cond_init(&_cond, NULL);
}
~Blocking_Queue()
{
pthread_mutex_destroy(&_lock);
pthread_cond_destroy(&_cond);
}
void put(T t)
{
pthread_mutex_lock(&_lock);
_queue.push(t);
pthread_cond_signal(&_cond);
pthread_mutex_unlock(&_lock);
}
T pull()
{
pthread_mutex_lock(&_lock);
while(_queue.empty())
{
pthread_cond_wait(&_cond, &_lock);
}
T t = _queue.front();
_queue.pop();
pthread_mutex_unlock(&_lock);
return t;
}
private:
std::queue<T> _queue;
pthread_cond_t _cond;
pthread_mutex_t _lock;
}
-----
(^^ This is an example of something I wrote at another place, feel free to use it)
Now you can extend this by making put-method check for std::queue<T>::size and return a fail when the queue is too big (make the caller wait in a way he wants) or block until the size is as small as you like, this of course also blocks the execution of the calling code.