149fd3cd2SShuo Chen// excerpts from http://code.google.com/p/muduo/
249fd3cd2SShuo Chen//
349fd3cd2SShuo Chen// Use of this source code is governed by a BSD-style license
449fd3cd2SShuo Chen// that can be found in the License file.
549fd3cd2SShuo Chen//
649fd3cd2SShuo Chen// Author: Shuo Chen (giantchen at gmail dot com)
749fd3cd2SShuo Chen
89d9bda4cSShuo Chen#ifndef MUDUO_BASE_BOUNDEDBLOCKINGQUEUE_H
99d9bda4cSShuo Chen#define MUDUO_BASE_BOUNDEDBLOCKINGQUEUE_H
109d9bda4cSShuo Chen
119d9bda4cSShuo Chen#include "Condition.h"
129d9bda4cSShuo Chen#include "Mutex.h"
139d9bda4cSShuo Chen
149d9bda4cSShuo Chen#include <boost/circular_buffer.hpp>
159d9bda4cSShuo Chen#include <boost/noncopyable.hpp>
169d9bda4cSShuo Chen#include <assert.h>
179d9bda4cSShuo Chen
189d9bda4cSShuo Chennamespace muduo
199d9bda4cSShuo Chen{
209d9bda4cSShuo Chen
219d9bda4cSShuo Chentemplate<typename T>
229d9bda4cSShuo Chenclass BoundedBlockingQueue : boost::noncopyable
239d9bda4cSShuo Chen{
249d9bda4cSShuo Chen public:
259d9bda4cSShuo Chen  explicit BoundedBlockingQueue(int maxSize)
269d9bda4cSShuo Chen    : mutex_(),
279d9bda4cSShuo Chen      notEmpty_(mutex_),
289d9bda4cSShuo Chen      notFull_(mutex_),
299d9bda4cSShuo Chen      queue_(maxSize)
309d9bda4cSShuo Chen  {
319d9bda4cSShuo Chen  }
329d9bda4cSShuo Chen
3349fd3cd2SShuo Chen  void put(const T& x)
349d9bda4cSShuo Chen  {
359d9bda4cSShuo Chen    MutexLockGuard lock(mutex_);
369d9bda4cSShuo Chen    while (queue_.full())
379d9bda4cSShuo Chen    {
389d9bda4cSShuo Chen      notFull_.wait();
399d9bda4cSShuo Chen    }
409d9bda4cSShuo Chen    assert(!queue_.full());
419d9bda4cSShuo Chen    queue_.push_back(x);
429d9bda4cSShuo Chen    notEmpty_.notify(); // TODO: move outside of lock
439d9bda4cSShuo Chen  }
449d9bda4cSShuo Chen
45ecd08fd9SShuo Chen  T take()
469d9bda4cSShuo Chen  {
479d9bda4cSShuo Chen    MutexLockGuard lock(mutex_);
489d9bda4cSShuo Chen    while (queue_.empty())
499d9bda4cSShuo Chen    {
509d9bda4cSShuo Chen      notEmpty_.wait();
519d9bda4cSShuo Chen    }
529d9bda4cSShuo Chen    assert(!queue_.empty());
539d9bda4cSShuo Chen    T front(queue_.front());
549d9bda4cSShuo Chen    queue_.pop_front();
559d9bda4cSShuo Chen    notFull_.notify(); // TODO: move outside of lock
569d9bda4cSShuo Chen    return front;
579d9bda4cSShuo Chen  }
589d9bda4cSShuo Chen
599d9bda4cSShuo Chen  bool empty() const
609d9bda4cSShuo Chen  {
619d9bda4cSShuo Chen    MutexLockGuard lock(mutex_);
629d9bda4cSShuo Chen    return queue_.empty();
639d9bda4cSShuo Chen  }
649d9bda4cSShuo Chen
659d9bda4cSShuo Chen  bool full() const
669d9bda4cSShuo Chen  {
679d9bda4cSShuo Chen    MutexLockGuard lock(mutex_);
689d9bda4cSShuo Chen    return queue_.full();
699d9bda4cSShuo Chen  }
709d9bda4cSShuo Chen
719d9bda4cSShuo Chen  size_t size() const
729d9bda4cSShuo Chen  {
739d9bda4cSShuo Chen    MutexLockGuard lock(mutex_);
749d9bda4cSShuo Chen    return queue_.size();
759d9bda4cSShuo Chen  }
769d9bda4cSShuo Chen
779d9bda4cSShuo Chen  size_t capacity() const
789d9bda4cSShuo Chen  {
799d9bda4cSShuo Chen    MutexLockGuard lock(mutex_);
809d9bda4cSShuo Chen    return queue_.capacity();
819d9bda4cSShuo Chen  }
829d9bda4cSShuo Chen
839d9bda4cSShuo Chen private:
849d9bda4cSShuo Chen  mutable MutexLock          mutex_;
859d9bda4cSShuo Chen  Condition                  notEmpty_;
869d9bda4cSShuo Chen  Condition                  notFull_;
879d9bda4cSShuo Chen  boost::circular_buffer<T>  queue_;
889d9bda4cSShuo Chen};
899d9bda4cSShuo Chen
909d9bda4cSShuo Chen}
919d9bda4cSShuo Chen
929d9bda4cSShuo Chen#endif  // MUDUO_BASE_BOUNDEDBLOCKINGQUEUE_H
93