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