BoundedBlockingQueue.h revision 9d9bda4c
19d9bda4cSShuo Chen#ifndef MUDUO_BASE_BOUNDEDBLOCKINGQUEUE_H
29d9bda4cSShuo Chen#define MUDUO_BASE_BOUNDEDBLOCKINGQUEUE_H
39d9bda4cSShuo Chen
49d9bda4cSShuo Chen#include "Condition.h"
59d9bda4cSShuo Chen#include "Mutex.h"
69d9bda4cSShuo Chen
79d9bda4cSShuo Chen#include <boost/circular_buffer.hpp>
89d9bda4cSShuo Chen#include <boost/noncopyable.hpp>
99d9bda4cSShuo Chen#include <assert.h>
109d9bda4cSShuo Chen
119d9bda4cSShuo Chennamespace muduo
129d9bda4cSShuo Chen{
139d9bda4cSShuo Chen
149d9bda4cSShuo Chentemplate<typename T>
159d9bda4cSShuo Chenclass BoundedBlockingQueue : boost::noncopyable
169d9bda4cSShuo Chen{
179d9bda4cSShuo Chen public:
189d9bda4cSShuo Chen  explicit BoundedBlockingQueue(int maxSize)
199d9bda4cSShuo Chen    : mutex_(),
209d9bda4cSShuo Chen      notEmpty_(mutex_),
219d9bda4cSShuo Chen      notFull_(mutex_),
229d9bda4cSShuo Chen      queue_(maxSize)
239d9bda4cSShuo Chen  {
249d9bda4cSShuo Chen  }
259d9bda4cSShuo Chen
269d9bda4cSShuo Chen  void put(T x)
279d9bda4cSShuo Chen  {
289d9bda4cSShuo Chen    MutexLockGuard lock(mutex_);
299d9bda4cSShuo Chen    while (queue_.full())
309d9bda4cSShuo Chen    {
319d9bda4cSShuo Chen      notFull_.wait();
329d9bda4cSShuo Chen    }
339d9bda4cSShuo Chen    assert(!queue_.full());
349d9bda4cSShuo Chen    queue_.push_back(x);
359d9bda4cSShuo Chen    notEmpty_.notify(); // TODO: move outside of lock
369d9bda4cSShuo Chen  }
379d9bda4cSShuo Chen
389d9bda4cSShuo Chen  T get()
399d9bda4cSShuo Chen  {
409d9bda4cSShuo Chen    MutexLockGuard lock(mutex_);
419d9bda4cSShuo Chen    while (queue_.empty())
429d9bda4cSShuo Chen    {
439d9bda4cSShuo Chen      notEmpty_.wait();
449d9bda4cSShuo Chen    }
459d9bda4cSShuo Chen    assert(!queue_.empty());
469d9bda4cSShuo Chen    T front(queue_.front());
479d9bda4cSShuo Chen    queue_.pop_front();
489d9bda4cSShuo Chen    notFull_.notify(); // TODO: move outside of lock
499d9bda4cSShuo Chen    return front;
509d9bda4cSShuo Chen  }
519d9bda4cSShuo Chen
529d9bda4cSShuo Chen  bool empty() const
539d9bda4cSShuo Chen  {
549d9bda4cSShuo Chen    MutexLockGuard lock(mutex_);
559d9bda4cSShuo Chen    return queue_.empty();
569d9bda4cSShuo Chen  }
579d9bda4cSShuo Chen
589d9bda4cSShuo Chen  bool full() const
599d9bda4cSShuo Chen  {
609d9bda4cSShuo Chen    MutexLockGuard lock(mutex_);
619d9bda4cSShuo Chen    return queue_.full();
629d9bda4cSShuo Chen  }
639d9bda4cSShuo Chen
649d9bda4cSShuo Chen  size_t size() const
659d9bda4cSShuo Chen  {
669d9bda4cSShuo Chen    MutexLockGuard lock(mutex_);
679d9bda4cSShuo Chen    return queue_.size();
689d9bda4cSShuo Chen  }
699d9bda4cSShuo Chen
709d9bda4cSShuo Chen  size_t capacity() const
719d9bda4cSShuo Chen  {
729d9bda4cSShuo Chen    MutexLockGuard lock(mutex_);
739d9bda4cSShuo Chen    return queue_.capacity();
749d9bda4cSShuo Chen  }
759d9bda4cSShuo Chen
769d9bda4cSShuo Chen private:
779d9bda4cSShuo Chen  mutable MutexLock          mutex_;
789d9bda4cSShuo Chen  Condition                  notEmpty_;
799d9bda4cSShuo Chen  Condition                  notFull_;
809d9bda4cSShuo Chen  boost::circular_buffer<T>  queue_;
819d9bda4cSShuo Chen};
829d9bda4cSShuo Chen
839d9bda4cSShuo Chen}
849d9bda4cSShuo Chen
859d9bda4cSShuo Chen#endif  // MUDUO_BASE_BOUNDEDBLOCKINGQUEUE_H
86