blob: 2e5472d6de6cfc9a8767d5ab5cde67303a81d93c [file] [log] [blame]
Mark Slee9f0c6512007-02-28 23:58:26 +00001// Copyright (c) 2006- Facebook
2// Distributed under the Thrift Software License
3//
4// See accompanying file LICENSE or visit the Thrift site at:
5// http://developers.facebook.com/thrift/
6
Marc Slemko66949872006-07-15 01:52:39 +00007#include "ThreadManager.h"
Marc Slemkod466b212006-07-20 00:04:18 +00008#include "Exception.h"
Marc Slemko0e53ccd2006-07-17 23:51:05 +00009#include "Monitor.h"
Marc Slemko66949872006-07-15 01:52:39 +000010
Marc Slemko6f038a72006-08-03 18:58:09 +000011#include <boost/shared_ptr.hpp>
12
Marc Slemko66949872006-07-15 01:52:39 +000013#include <assert.h>
Marc Slemko0e53ccd2006-07-17 23:51:05 +000014#include <queue>
15#include <set>
Marc Slemko66949872006-07-15 01:52:39 +000016
Marc Slemko6f038a72006-08-03 18:58:09 +000017#if defined(DEBUG)
18#include <iostream>
19#endif //defined(DEBUG)
20
Marc Slemko66949872006-07-15 01:52:39 +000021namespace facebook { namespace thrift { namespace concurrency {
22
Marc Slemko6f038a72006-08-03 18:58:09 +000023using namespace boost;
24
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000025
Mark Sleef5f2be42006-09-05 21:05:31 +000026/**
27 * ThreadManager class
28 *
29 * This class manages a pool of threads. It uses a ThreadFactory to create
30 * threads. It never actually creates or destroys worker threads, rather
31 * it maintains statistics on number of idle threads, number of active threads,
32 * task backlog, and average wait and service times.
33 *
34 * @author marc
35 * @version $Id:$
36 */
Marc Slemko0e53ccd2006-07-17 23:51:05 +000037class ThreadManager::Impl : public ThreadManager {
38
39 public:
Marc Slemko6f038a72006-08-03 18:58:09 +000040 Impl() :
Mark Slee2f6404d2006-10-10 01:37:40 +000041 workerCount_(0),
42 workerMaxCount_(0),
43 idleCount_(0),
44 state_(ThreadManager::UNINITIALIZED) {}
Marc Slemkod466b212006-07-20 00:04:18 +000045
Mark Sleef5f2be42006-09-05 21:05:31 +000046 ~Impl() { stop(); }
Marc Slemkod466b212006-07-20 00:04:18 +000047
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000048 void start();
Marc Slemko0e53ccd2006-07-17 23:51:05 +000049
Marc Slemkod466b212006-07-20 00:04:18 +000050 void stop();
Marc Slemko0e53ccd2006-07-17 23:51:05 +000051
Mark Slee2f6404d2006-10-10 01:37:40 +000052 const ThreadManager::STATE state() const {
53 return state_;
54 }
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000055
Marc Slemko6f038a72006-08-03 18:58:09 +000056 shared_ptr<ThreadFactory> threadFactory() const {
Mark Slee2f6404d2006-10-10 01:37:40 +000057 Synchronized s(monitor_);
58 return threadFactory_;
Marc Slemko0e53ccd2006-07-17 23:51:05 +000059 }
60
Mark Sleef5f2be42006-09-05 21:05:31 +000061 void threadFactory(shared_ptr<ThreadFactory> value) {
Mark Slee2f6404d2006-10-10 01:37:40 +000062 Synchronized s(monitor_);
63 threadFactory_ = value;
Marc Slemko0e53ccd2006-07-17 23:51:05 +000064 }
65
Marc Slemkod466b212006-07-20 00:04:18 +000066 void addWorker(size_t value);
Marc Slemko0e53ccd2006-07-17 23:51:05 +000067
Marc Slemkod466b212006-07-20 00:04:18 +000068 void removeWorker(size_t value);
Marc Slemko0e53ccd2006-07-17 23:51:05 +000069
Mark Slee2f6404d2006-10-10 01:37:40 +000070 size_t idleWorkerCount() const {
71 return idleCount_;
72 }
Marc Slemko0e53ccd2006-07-17 23:51:05 +000073
74 size_t workerCount() const {
Mark Slee2f6404d2006-10-10 01:37:40 +000075 Synchronized s(monitor_);
76 return workerCount_;
Marc Slemko0e53ccd2006-07-17 23:51:05 +000077 }
78
79 size_t pendingTaskCount() const {
Mark Slee2f6404d2006-10-10 01:37:40 +000080 Synchronized s(monitor_);
81 return tasks_.size();
Marc Slemko0e53ccd2006-07-17 23:51:05 +000082 }
83
84 size_t totalTaskCount() const {
Mark Slee2f6404d2006-10-10 01:37:40 +000085 Synchronized s(monitor_);
86 return tasks_.size() + workerCount_ - idleCount_;
Marc Slemko0e53ccd2006-07-17 23:51:05 +000087 }
88
Marc Slemko6f038a72006-08-03 18:58:09 +000089 void add(shared_ptr<Runnable> value);
Marc Slemko0e53ccd2006-07-17 23:51:05 +000090
Marc Slemko6f038a72006-08-03 18:58:09 +000091 void remove(shared_ptr<Runnable> task);
Marc Slemko0e53ccd2006-07-17 23:51:05 +000092
93private:
Mark Slee2f6404d2006-10-10 01:37:40 +000094 size_t workerCount_;
95 size_t workerMaxCount_;
96 size_t idleCount_;
97 ThreadManager::STATE state_;
98 shared_ptr<ThreadFactory> threadFactory_;
Marc Slemko0e53ccd2006-07-17 23:51:05 +000099
Mark Sleef5f2be42006-09-05 21:05:31 +0000100
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000101 friend class ThreadManager::Task;
Mark Slee2f6404d2006-10-10 01:37:40 +0000102 std::queue<shared_ptr<Task> > tasks_;
103 Monitor monitor_;
104 Monitor workerMonitor_;
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000105
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000106 friend class ThreadManager::Worker;
Mark Slee2f6404d2006-10-10 01:37:40 +0000107 std::set<shared_ptr<Thread> > workers_;
108 std::set<shared_ptr<Thread> > deadWorkers_;
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000109};
Marc Slemko66949872006-07-15 01:52:39 +0000110
111class ThreadManager::Task : public Runnable {
112
Mark Sleef5f2be42006-09-05 21:05:31 +0000113 public:
Marc Slemko66949872006-07-15 01:52:39 +0000114 enum STATE {
115 WAITING,
116 EXECUTING,
117 CANCELLED,
118 COMPLETE
119 };
120
Marc Slemko6f038a72006-08-03 18:58:09 +0000121 Task(shared_ptr<Runnable> runnable) :
Mark Slee2f6404d2006-10-10 01:37:40 +0000122 runnable_(runnable),
123 state_(WAITING) {}
Marc Slemko66949872006-07-15 01:52:39 +0000124
Mark Sleef5f2be42006-09-05 21:05:31 +0000125 ~Task() {}
Marc Slemko66949872006-07-15 01:52:39 +0000126
127 void run() {
Mark Slee2f6404d2006-10-10 01:37:40 +0000128 if (state_ == EXECUTING) {
129 runnable_->run();
130 state_ = COMPLETE;
Marc Slemko66949872006-07-15 01:52:39 +0000131 }
132 }
133
134 private:
Mark Slee2f6404d2006-10-10 01:37:40 +0000135 shared_ptr<Runnable> runnable_;
Marc Slemkod466b212006-07-20 00:04:18 +0000136 friend class ThreadManager::Worker;
Mark Slee2f6404d2006-10-10 01:37:40 +0000137 STATE state_;
Marc Slemko66949872006-07-15 01:52:39 +0000138};
139
140class ThreadManager::Worker: public Runnable {
Marc Slemko66949872006-07-15 01:52:39 +0000141 enum STATE {
142 UNINITIALIZED,
143 STARTING,
144 STARTED,
145 STOPPING,
146 STOPPED
147 };
148
149 public:
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000150 Worker(ThreadManager::Impl* manager) :
Mark Slee2f6404d2006-10-10 01:37:40 +0000151 manager_(manager),
152 state_(UNINITIALIZED),
153 idle_(false) {}
Marc Slemko66949872006-07-15 01:52:39 +0000154
155 ~Worker() {}
156
Mark Slee2f6404d2006-10-10 01:37:40 +0000157 bool isActive() const {
158 return manager_->workerCount_ <= manager_->workerMaxCount_;
159 }
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000160
Mark Sleef5f2be42006-09-05 21:05:31 +0000161 /**
162 * Worker entry point
163 *
164 * As long as worker thread is running, pull tasks off the task queue and
165 * execute.
166 */
Marc Slemko66949872006-07-15 01:52:39 +0000167 void run() {
Mark Sleef5f2be42006-09-05 21:05:31 +0000168 bool active = false;
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000169 bool notifyManager = false;
170
Mark Sleef5f2be42006-09-05 21:05:31 +0000171 /**
172 * Increment worker semaphore and notify manager if worker count reached
173 * desired max
174 *
175 * Note: We have to release the monitor and acquire the workerMonitor
176 * since that is what the manager blocks on for worker add/remove
177 */
178 {
Mark Slee2f6404d2006-10-10 01:37:40 +0000179 Synchronized s(manager_->monitor_);
180 active = manager_->workerCount_ < manager_->workerMaxCount_;
Mark Sleef5f2be42006-09-05 21:05:31 +0000181 if (active) {
Mark Slee2f6404d2006-10-10 01:37:40 +0000182 manager_->workerCount_++;
183 notifyManager = manager_->workerCount_ == manager_->workerMaxCount_;
Marc Slemko66949872006-07-15 01:52:39 +0000184 }
185 }
186
Mark Sleef5f2be42006-09-05 21:05:31 +0000187 if (notifyManager) {
Mark Slee2f6404d2006-10-10 01:37:40 +0000188 Synchronized s(manager_->workerMonitor_);
189 manager_->workerMonitor_.notify();
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000190 notifyManager = false;
191 }
192
Mark Sleef5f2be42006-09-05 21:05:31 +0000193 while (active) {
Marc Slemko6f038a72006-08-03 18:58:09 +0000194 shared_ptr<ThreadManager::Task> task;
Marc Slemko66949872006-07-15 01:52:39 +0000195
Mark Sleef5f2be42006-09-05 21:05:31 +0000196 /**
197 * While holding manager monitor block for non-empty task queue (Also
198 * check that the thread hasn't been requested to stop). Once the queue
199 * is non-empty, dequeue a task, release monitor, and execute. If the
200 * worker max count has been decremented such that we exceed it, mark
201 * ourself inactive, decrement the worker count and notify the manager
202 * (technically we're notifying the next blocked thread but eventually
203 * the manager will see it.
204 */
205 {
Mark Slee2f6404d2006-10-10 01:37:40 +0000206 Synchronized s(manager_->monitor_);
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000207 active = isActive();
Mark Slee2f6404d2006-10-10 01:37:40 +0000208 while (active && manager_->tasks_.empty()) {
209 manager_->idleCount_++;
210 idle_ = true;
211 manager_->monitor_.wait();
Mark Sleef5f2be42006-09-05 21:05:31 +0000212 active = isActive();
Mark Slee2f6404d2006-10-10 01:37:40 +0000213 idle_ = false;
214 manager_->idleCount_--;
Marc Slemko66949872006-07-15 01:52:39 +0000215 }
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000216
Mark Sleef5f2be42006-09-05 21:05:31 +0000217 if (active) {
Mark Slee2f6404d2006-10-10 01:37:40 +0000218 if (!manager_->tasks_.empty()) {
219 task = manager_->tasks_.front();
220 manager_->tasks_.pop();
221 if (task->state_ == ThreadManager::Task::WAITING) {
222 task->state_ = ThreadManager::Task::EXECUTING;
Marc Slemkod466b212006-07-20 00:04:18 +0000223 }
224 }
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000225 } else {
Mark Slee2f6404d2006-10-10 01:37:40 +0000226 idle_ = true;
227 manager_->workerCount_--;
228 notifyManager = manager_->workerCount_ == manager_->workerMaxCount_;
Marc Slemko66949872006-07-15 01:52:39 +0000229 }
230 }
Mark Sleef5f2be42006-09-05 21:05:31 +0000231
232 if (task != NULL) {
Mark Slee2f6404d2006-10-10 01:37:40 +0000233 if (task->state_ == ThreadManager::Task::EXECUTING) {
Marc Slemkod466b212006-07-20 00:04:18 +0000234 try {
Mark Sleef5f2be42006-09-05 21:05:31 +0000235 task->run();
236 } catch(...) {
237 // XXX need to log this
Marc Slemkod466b212006-07-20 00:04:18 +0000238 }
Marc Slemkod466b212006-07-20 00:04:18 +0000239 }
Marc Slemko66949872006-07-15 01:52:39 +0000240 }
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000241 }
Mark Sleef5f2be42006-09-05 21:05:31 +0000242
243 {
Mark Slee2f6404d2006-10-10 01:37:40 +0000244 Synchronized s(manager_->workerMonitor_);
245 manager_->deadWorkers_.insert(this->thread());
Mark Sleef5f2be42006-09-05 21:05:31 +0000246 if (notifyManager) {
Mark Slee2f6404d2006-10-10 01:37:40 +0000247 manager_->workerMonitor_.notify();
Marc Slemko66949872006-07-15 01:52:39 +0000248 }
249 }
Mark Sleef5f2be42006-09-05 21:05:31 +0000250
Marc Slemko66949872006-07-15 01:52:39 +0000251 return;
252 }
Mark Sleef5f2be42006-09-05 21:05:31 +0000253
254 private:
Mark Slee2f6404d2006-10-10 01:37:40 +0000255 ThreadManager::Impl* manager_;
Mark Sleef5f2be42006-09-05 21:05:31 +0000256 friend class ThreadManager::Impl;
Mark Slee2f6404d2006-10-10 01:37:40 +0000257 STATE state_;
258 bool idle_;
Marc Slemko66949872006-07-15 01:52:39 +0000259};
260
Mark Sleef5f2be42006-09-05 21:05:31 +0000261
262 void ThreadManager::Impl::addWorker(size_t value) {
Marc Slemko6f038a72006-08-03 18:58:09 +0000263 std::set<shared_ptr<Thread> > newThreads;
Mark Sleef5f2be42006-09-05 21:05:31 +0000264 for (size_t ix = 0; ix < value; ix++) {
265 class ThreadManager::Worker;
Marc Slemko6f038a72006-08-03 18:58:09 +0000266 shared_ptr<ThreadManager::Worker> worker = shared_ptr<ThreadManager::Worker>(new ThreadManager::Worker(this));
Mark Slee2f6404d2006-10-10 01:37:40 +0000267 newThreads.insert(threadFactory_->newThread(worker));
Marc Slemko66949872006-07-15 01:52:39 +0000268 }
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000269
Mark Sleef5f2be42006-09-05 21:05:31 +0000270 {
Mark Slee2f6404d2006-10-10 01:37:40 +0000271 Synchronized s(monitor_);
272 workerMaxCount_ += value;
273 workers_.insert(newThreads.begin(), newThreads.end());
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000274 }
Marc Slemko66949872006-07-15 01:52:39 +0000275
Mark Sleef5f2be42006-09-05 21:05:31 +0000276 for (std::set<shared_ptr<Thread> >::iterator ix = newThreads.begin(); ix != newThreads.end(); ix++) {
Marc Slemko6f038a72006-08-03 18:58:09 +0000277 shared_ptr<ThreadManager::Worker> worker = dynamic_pointer_cast<ThreadManager::Worker, Runnable>((*ix)->runnable());
Mark Slee2f6404d2006-10-10 01:37:40 +0000278 worker->state_ = ThreadManager::Worker::STARTING;
Marc Slemkod466b212006-07-20 00:04:18 +0000279 (*ix)->start();
280 }
281
Mark Sleef5f2be42006-09-05 21:05:31 +0000282 {
Mark Slee2f6404d2006-10-10 01:37:40 +0000283 Synchronized s(workerMonitor_);
284 while (workerCount_ != workerMaxCount_) {
285 workerMonitor_.wait();
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000286 }
287 }
288}
Marc Slemkod466b212006-07-20 00:04:18 +0000289
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000290void ThreadManager::Impl::start() {
291
Mark Slee2f6404d2006-10-10 01:37:40 +0000292 if (state_ == ThreadManager::STOPPED) {
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000293 return;
294 }
295
Mark Sleef5f2be42006-09-05 21:05:31 +0000296 {
Mark Slee2f6404d2006-10-10 01:37:40 +0000297 Synchronized s(monitor_);
298 if (state_ == ThreadManager::UNINITIALIZED) {
299 if (threadFactory_ == NULL) {
Mark Sleef5f2be42006-09-05 21:05:31 +0000300 throw InvalidArgumentException();
301 }
Mark Slee2f6404d2006-10-10 01:37:40 +0000302 state_ = ThreadManager::STARTED;
303 monitor_.notifyAll();
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000304 }
305
Mark Slee2f6404d2006-10-10 01:37:40 +0000306 while (state_ == STARTING) {
307 monitor_.wait();
Marc Slemkod466b212006-07-20 00:04:18 +0000308 }
309 }
310}
311
312void ThreadManager::Impl::stop() {
Marc Slemkod466b212006-07-20 00:04:18 +0000313 bool doStop = false;
Mark Slee2f6404d2006-10-10 01:37:40 +0000314 if (state_ == ThreadManager::STOPPED) {
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000315 return;
316 }
317
Mark Sleef5f2be42006-09-05 21:05:31 +0000318 {
Mark Slee2f6404d2006-10-10 01:37:40 +0000319 Synchronized s(monitor_);
320 if (!state_ != ThreadManager::STOPPING && state_ != ThreadManager::STOPPED) {
Marc Slemkod466b212006-07-20 00:04:18 +0000321 doStop = true;
Mark Slee2f6404d2006-10-10 01:37:40 +0000322 state_ = ThreadManager::STOPPING;
Marc Slemkod466b212006-07-20 00:04:18 +0000323 }
324 }
325
Mark Sleef5f2be42006-09-05 21:05:31 +0000326 if (doStop) {
Mark Slee2f6404d2006-10-10 01:37:40 +0000327 removeWorker(workerCount_);
328 state_ = ThreadManager::STOPPING;
Marc Slemkod466b212006-07-20 00:04:18 +0000329 }
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000330
Marc Slemko6f038a72006-08-03 18:58:09 +0000331 // XXX
Mark Sleef5f2be42006-09-05 21:05:31 +0000332 // should be able to block here for transition to STOPPED since we're no
333 // using shared_ptrs
Marc Slemkod466b212006-07-20 00:04:18 +0000334}
335
336void ThreadManager::Impl::removeWorker(size_t value) {
Marc Slemko6f038a72006-08-03 18:58:09 +0000337 std::set<shared_ptr<Thread> > removedThreads;
Mark Sleef5f2be42006-09-05 21:05:31 +0000338 {
Mark Slee2f6404d2006-10-10 01:37:40 +0000339 Synchronized s(monitor_);
340 if (value > workerMaxCount_) {
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000341 throw InvalidArgumentException();
342 }
343
Mark Slee2f6404d2006-10-10 01:37:40 +0000344 workerMaxCount_ -= value;
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000345
Mark Slee2f6404d2006-10-10 01:37:40 +0000346 if (idleCount_ < value) {
347 for (size_t ix = 0; ix < idleCount_; ix++) {
348 monitor_.notify();
Marc Slemko66949872006-07-15 01:52:39 +0000349 }
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000350 } else {
Mark Slee2f6404d2006-10-10 01:37:40 +0000351 monitor_.notifyAll();
Marc Slemko66949872006-07-15 01:52:39 +0000352 }
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000353 }
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000354
Mark Sleef5f2be42006-09-05 21:05:31 +0000355 {
Mark Slee2f6404d2006-10-10 01:37:40 +0000356 Synchronized s(workerMonitor_);
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000357
Mark Slee2f6404d2006-10-10 01:37:40 +0000358 while (workerCount_ != workerMaxCount_) {
359 workerMonitor_.wait();
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000360 }
361
Mark Slee2f6404d2006-10-10 01:37:40 +0000362 for (std::set<shared_ptr<Thread> >::iterator ix = deadWorkers_.begin(); ix != deadWorkers_.end(); ix++) {
363 workers_.erase(*ix);
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000364 }
Mark Sleef5f2be42006-09-05 21:05:31 +0000365
Mark Slee2f6404d2006-10-10 01:37:40 +0000366 deadWorkers_.clear();
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000367 }
368}
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000369
Marc Slemko6f038a72006-08-03 18:58:09 +0000370void ThreadManager::Impl::add(shared_ptr<Runnable> value) {
Mark Slee2f6404d2006-10-10 01:37:40 +0000371 Synchronized s(monitor_);
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000372
Mark Slee2f6404d2006-10-10 01:37:40 +0000373 if (state_ != ThreadManager::STARTED) {
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000374 throw IllegalStateException();
375 }
Marc Slemkod466b212006-07-20 00:04:18 +0000376
Mark Slee2f6404d2006-10-10 01:37:40 +0000377 tasks_.push(shared_ptr<ThreadManager::Task>(new ThreadManager::Task(value)));
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000378
Mark Sleef5f2be42006-09-05 21:05:31 +0000379 // If idle thread is available notify it, otherwise all worker threads are
380 // running and will get around to this task in time.
Mark Slee2f6404d2006-10-10 01:37:40 +0000381 if (idleCount_ > 0) {
382 monitor_.notify();
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000383 }
Marc Slemko66949872006-07-15 01:52:39 +0000384 }
385
Marc Slemko6f038a72006-08-03 18:58:09 +0000386void ThreadManager::Impl::remove(shared_ptr<Runnable> task) {
Mark Slee2f6404d2006-10-10 01:37:40 +0000387 Synchronized s(monitor_);
388 if (state_ != ThreadManager::STARTED) {
Mark Sleef5f2be42006-09-05 21:05:31 +0000389 throw IllegalStateException();
390 }
Marc Slemko66949872006-07-15 01:52:39 +0000391}
392
Marc Slemkod466b212006-07-20 00:04:18 +0000393class SimpleThreadManager : public ThreadManager::Impl {
Marc Slemko66949872006-07-15 01:52:39 +0000394
Marc Slemkod466b212006-07-20 00:04:18 +0000395public:
Marc Slemkod466b212006-07-20 00:04:18 +0000396 SimpleThreadManager(size_t workerCount=4) :
Mark Slee2f6404d2006-10-10 01:37:40 +0000397 workerCount_(workerCount),
398 firstTime_(true) {
Marc Slemkod466b212006-07-20 00:04:18 +0000399 }
Marc Slemko66949872006-07-15 01:52:39 +0000400
Marc Slemkofe5ba12e2006-07-20 21:16:27 +0000401 void start() {
402 ThreadManager::Impl::start();
Mark Slee2f6404d2006-10-10 01:37:40 +0000403 addWorker(workerCount_);
Marc Slemkod466b212006-07-20 00:04:18 +0000404 }
405
406private:
Mark Slee2f6404d2006-10-10 01:37:40 +0000407 const size_t workerCount_;
408 bool firstTime_;
409 Monitor monitor_;
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000410};
Marc Slemko66949872006-07-15 01:52:39 +0000411
Marc Slemko66949872006-07-15 01:52:39 +0000412
Marc Slemko6f038a72006-08-03 18:58:09 +0000413shared_ptr<ThreadManager> ThreadManager::newThreadManager() {
414 return shared_ptr<ThreadManager>(new ThreadManager::Impl());
Marc Slemkod466b212006-07-20 00:04:18 +0000415}
Marc Slemko66949872006-07-15 01:52:39 +0000416
Marc Slemko6f038a72006-08-03 18:58:09 +0000417shared_ptr<ThreadManager> ThreadManager::newSimpleThreadManager(size_t count) {
418 return shared_ptr<ThreadManager>(new SimpleThreadManager(count));
Marc Slemkod466b212006-07-20 00:04:18 +0000419}
Marc Slemko66949872006-07-15 01:52:39 +0000420
421}}} // facebook::thrift::concurrency