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