1cd139dc7SShuo Chen// excerpts from http://code.google.com/p/muduo/ 2cd139dc7SShuo Chen// 3cd139dc7SShuo Chen// Use of this source code is governed by a BSD-style license 4cd139dc7SShuo Chen// that can be found in the License file. 5cd139dc7SShuo Chen// 6cd139dc7SShuo Chen// Author: Shuo Chen (giantchen at gmail dot com) 7cd139dc7SShuo Chen 8cd139dc7SShuo Chen#include "ThreadPool.h" 9cd139dc7SShuo Chen#include "Exception.h" 10cd139dc7SShuo Chen 11cd139dc7SShuo Chen#include <boost/bind.hpp> 12cd139dc7SShuo Chen#include <assert.h> 13cd139dc7SShuo Chen#include <stdio.h> 14cd139dc7SShuo Chen 15cd139dc7SShuo Chenusing namespace muduo; 16cd139dc7SShuo Chen 17cd139dc7SShuo ChenThreadPool::ThreadPool(const std::string& name) 18cd139dc7SShuo Chen : mutex_(), 19cd139dc7SShuo Chen cond_(mutex_), 20cd139dc7SShuo Chen name_(name), 21cd139dc7SShuo Chen running_(false) 22cd139dc7SShuo Chen{ 23cd139dc7SShuo Chen} 24cd139dc7SShuo Chen 25cd139dc7SShuo ChenThreadPool::~ThreadPool() 26cd139dc7SShuo Chen{ 27fceafe27SShuo Chen if (running_) 28fceafe27SShuo Chen { 29fceafe27SShuo Chen stop(); 30fceafe27SShuo Chen } 31cd139dc7SShuo Chen} 32cd139dc7SShuo Chen 33cd139dc7SShuo Chenvoid ThreadPool::start(int numThreads) 34cd139dc7SShuo Chen{ 35cd139dc7SShuo Chen assert(threads_.empty()); 36cd139dc7SShuo Chen running_ = true; 37cd139dc7SShuo Chen threads_.reserve(numThreads); 38cd139dc7SShuo Chen for (int i = 0; i < numThreads; ++i) 39cd139dc7SShuo Chen { 40cd139dc7SShuo Chen char id[32]; 41cd139dc7SShuo Chen snprintf(id, sizeof id, "%d", i); 42cd139dc7SShuo Chen threads_.push_back(new muduo::Thread( 43cd139dc7SShuo Chen boost::bind(&ThreadPool::runInThread, this), name_+id)); 44cd139dc7SShuo Chen threads_[i].start(); 45cd139dc7SShuo Chen } 46cd139dc7SShuo Chen} 47cd139dc7SShuo Chen 48cd139dc7SShuo Chenvoid ThreadPool::stop() 49cd139dc7SShuo Chen{ 50cd139dc7SShuo Chen running_ = false; 51cd139dc7SShuo Chen cond_.notifyAll(); 52cd139dc7SShuo Chen for_each(threads_.begin(), 53cd139dc7SShuo Chen threads_.end(), 54cd139dc7SShuo Chen boost::bind(&muduo::Thread::join, _1)); 55cd139dc7SShuo Chen} 56cd139dc7SShuo Chen 57cd139dc7SShuo Chenvoid ThreadPool::run(const Task& task) 58cd139dc7SShuo Chen{ 59cd139dc7SShuo Chen if (threads_.empty()) 60cd139dc7SShuo Chen { 61cd139dc7SShuo Chen task(); 62cd139dc7SShuo Chen } 63cd139dc7SShuo Chen else 64cd139dc7SShuo Chen { 65cd139dc7SShuo Chen MutexLockGuard lock(mutex_); 66cd139dc7SShuo Chen queue_.push_back(task); 67cd139dc7SShuo Chen cond_.notify(); 68cd139dc7SShuo Chen } 69cd139dc7SShuo Chen} 70cd139dc7SShuo Chen 71cd139dc7SShuo ChenThreadPool::Task ThreadPool::take() 72cd139dc7SShuo Chen{ 73cd139dc7SShuo Chen MutexLockGuard lock(mutex_); 74cd139dc7SShuo Chen while (queue_.empty() && running_) 75cd139dc7SShuo Chen { 76cd139dc7SShuo Chen cond_.wait(); 77cd139dc7SShuo Chen } 78cd139dc7SShuo Chen Task task; 79cd139dc7SShuo Chen if(!queue_.empty()) 80cd139dc7SShuo Chen { 81cd139dc7SShuo Chen task = queue_.front(); 82cd139dc7SShuo Chen queue_.pop_front(); 83cd139dc7SShuo Chen } 84cd139dc7SShuo Chen return task; 85cd139dc7SShuo Chen} 86cd139dc7SShuo Chen 87cd139dc7SShuo Chenvoid ThreadPool::runInThread() 88cd139dc7SShuo Chen{ 89cd139dc7SShuo Chen try 90cd139dc7SShuo Chen { 91cd139dc7SShuo Chen while (running_) 92cd139dc7SShuo Chen { 93cd139dc7SShuo Chen Task task(take()); 94cd139dc7SShuo Chen if (task) 95cd139dc7SShuo Chen { 96cd139dc7SShuo Chen task(); 97cd139dc7SShuo Chen } 98cd139dc7SShuo Chen } 99cd139dc7SShuo Chen } 100cd139dc7SShuo Chen catch (const Exception& ex) 101cd139dc7SShuo Chen { 102cd139dc7SShuo Chen fprintf(stderr, "exception caught in ThreadPool %s\n", name_.c_str()); 103cd139dc7SShuo Chen fprintf(stderr, "reason: %s\n", ex.what()); 104cd139dc7SShuo Chen fprintf(stderr, "stack trace: %s\n", ex.stackTrace()); 105cd139dc7SShuo Chen abort(); 106cd139dc7SShuo Chen } 107214fac0cSShuo Chen catch (const std::exception& ex) 108cd139dc7SShuo Chen { 109cd139dc7SShuo Chen fprintf(stderr, "exception caught in ThreadPool %s\n", name_.c_str()); 110cd139dc7SShuo Chen fprintf(stderr, "reason: %s\n", ex.what()); 111cd139dc7SShuo Chen abort(); 112cd139dc7SShuo Chen } 113cd139dc7SShuo Chen catch (...) 114cd139dc7SShuo Chen { 115cd139dc7SShuo Chen fprintf(stderr, "unknown exception caught in ThreadPool %s\n", name_.c_str()); 116cd139dc7SShuo Chen abort(); 117cd139dc7SShuo Chen } 118cd139dc7SShuo Chen} 119cd139dc7SShuo Chen 120