blob: 9cfccf36fcbe078b47326afab7f38b7a52149f93 [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
Mark Sleef5f2be42006-09-05 21:05:31 +00007#ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_
8#define _THRIFT_CONCURRENCY_THREADMANAGER_H_ 1
Marc Slemko66949872006-07-15 01:52:39 +00009
Marc Slemko6f038a72006-08-03 18:58:09 +000010#include <boost/shared_ptr.hpp>
Marc Slemko0e53ccd2006-07-17 23:51:05 +000011#include <sys/types.h>
Marc Slemko66949872006-07-15 01:52:39 +000012#include "Thread.h"
13
T Jake Lucianib5e62212009-01-31 22:36:20 +000014namespace apache { namespace thrift { namespace concurrency {
Marc Slemko66949872006-07-15 01:52:39 +000015
Mark Sleef5f2be42006-09-05 21:05:31 +000016/**
17 * Thread Pool Manager and related classes
18 *
Mark Sleef5f2be42006-09-05 21:05:31 +000019 * @version $Id:$
20 */
Marc Slemko66949872006-07-15 01:52:39 +000021class ThreadManager;
22
Mark Sleef5f2be42006-09-05 21:05:31 +000023/**
24 * ThreadManager class
25 *
26 * This class manages a pool of threads. It uses a ThreadFactory to create
27 * threads. It never actually creates or destroys worker threads, rather
28 * It maintains statistics on number of idle threads, number of active threads,
29 * task backlog, and average wait and service times and informs the PoolPolicy
30 * object bound to instances of this manager of interesting transitions. It is
31 * then up the PoolPolicy object to decide if the thread pool size needs to be
32 * adjusted and call this object addWorker and removeWorker methods to make
33 * changes.
34 *
35 * This design allows different policy implementations to used this code to
36 * handle basic worker thread management and worker task execution and focus on
37 * policy issues. The simplest policy, StaticPolicy, does nothing other than
38 * create a fixed number of threads.
39 */
Marc Slemko66949872006-07-15 01:52:39 +000040class ThreadManager {
41
Mark Slee8cbda852007-02-01 23:05:38 +000042 protected:
Marc Slemkod466b212006-07-20 00:04:18 +000043 ThreadManager() {}
Marc Slemko66949872006-07-15 01:52:39 +000044
Mark Slee8cbda852007-02-01 23:05:38 +000045 public:
Marc Slemkod466b212006-07-20 00:04:18 +000046 virtual ~ThreadManager() {}
Marc Slemko66949872006-07-15 01:52:39 +000047
Mark Sleef5f2be42006-09-05 21:05:31 +000048 /**
49 * Starts the thread manager. Verifies all attributes have been properly
50 * initialized, then allocates necessary resources to begin operation
51 */
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000052 virtual void start() = 0;
53
Mark Sleef5f2be42006-09-05 21:05:31 +000054 /**
55 * Stops the thread manager. Aborts all remaining unprocessed task, shuts
56 * down all created worker threads, and realeases all allocated resources.
57 * This method blocks for all worker threads to complete, thus it can
Marc Slemko3a3b53b2007-05-22 23:59:54 +000058 * potentially block forever if a worker thread is running a task that
Mark Sleef5f2be42006-09-05 21:05:31 +000059 * won't terminate.
60 */
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000061 virtual void stop() = 0;
62
Mark Slee7c10eaf2007-03-01 02:45:10 +000063 /**
64 * Joins the thread manager. This is the same as stop, except that it will
65 * block until all the workers have finished their work. At that point
66 * the ThreadManager will transition into the STOPPED state.
67 */
Mark Slee6e3f6372007-03-01 22:05:46 +000068 virtual void join() = 0;
69
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000070 enum STATE {
71 UNINITIALIZED,
72 STARTING,
73 STARTED,
Mark Slee7c10eaf2007-03-01 02:45:10 +000074 JOINING,
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000075 STOPPING,
76 STOPPED
77 };
Marc Slemko3a3b53b2007-05-22 23:59:54 +000078
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000079 virtual const STATE state() const = 0;
80
Mark Slee5ea15f92007-03-05 22:55:59 +000081 virtual boost::shared_ptr<ThreadFactory> threadFactory() const = 0;
Marc Slemko66949872006-07-15 01:52:39 +000082
Mark Slee5ea15f92007-03-05 22:55:59 +000083 virtual void threadFactory(boost::shared_ptr<ThreadFactory> value) = 0;
Marc Slemko66949872006-07-15 01:52:39 +000084
Marc Slemkod466b212006-07-20 00:04:18 +000085 virtual void addWorker(size_t value=1) = 0;
Marc Slemko66949872006-07-15 01:52:39 +000086
Marc Slemkod466b212006-07-20 00:04:18 +000087 virtual void removeWorker(size_t value=1) = 0;
Marc Slemko66949872006-07-15 01:52:39 +000088
Mark Sleef5f2be42006-09-05 21:05:31 +000089 /**
90 * Gets the current number of idle worker threads
91 */
Marc Slemko66949872006-07-15 01:52:39 +000092 virtual size_t idleWorkerCount() const = 0;
93
Mark Sleef5f2be42006-09-05 21:05:31 +000094 /**
95 * Gets the current number of total worker threads
96 */
Marc Slemko66949872006-07-15 01:52:39 +000097 virtual size_t workerCount() const = 0;
98
Mark Sleef5f2be42006-09-05 21:05:31 +000099 /**
100 * Gets the current number of pending tasks
101 */
Marc Slemko66949872006-07-15 01:52:39 +0000102 virtual size_t pendingTaskCount() const = 0;
103
Mark Sleef5f2be42006-09-05 21:05:31 +0000104 /**
105 * Gets the current number of pending and executing tasks
106 */
Marc Slemko66949872006-07-15 01:52:39 +0000107 virtual size_t totalTaskCount() const = 0;
108
Mark Sleef5f2be42006-09-05 21:05:31 +0000109 /**
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000110 * Gets the maximum pending task count. 0 indicates no maximum
Mark Sleef5f2be42006-09-05 21:05:31 +0000111 */
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000112 virtual size_t pendingTaskCountMax() const = 0;
113
114 /**
115 * Adds a task to be executed at some time in the future by a worker thread.
116 *
117 * This method will block if pendingTaskCountMax() in not zero and pendingTaskCount()
118 * is greater than or equalt to pendingTaskCountMax(). If this method is called in the
119 * context of a ThreadManager worker thread it will throw a
120 * TooManyPendingTasksException
121 *
122 * @param task The task to queue for execution
123 *
124 * @param timeout Time to wait in milliseconds to add a task when a pending-task-count
Aditya Agarwal4b6ff2d2007-12-25 22:58:50 +0000125 * is specified. Specific cases:
126 * timeout = 0 : Wait forever to queue task.
127 * timeout = -1 : Return immediately if pending task count exceeds specified max
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000128 *
129 * @throws TooManyPendingTasksException Pending task count exceeds max pending task count
130 */
Mark Slee9b82d272007-05-23 05:16:07 +0000131 virtual void add(boost::shared_ptr<Runnable>task, int64_t timeout=0LL) = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000132
Mark Sleef5f2be42006-09-05 21:05:31 +0000133 /**
134 * Removes a pending task
135 */
Mark Slee5ea15f92007-03-05 22:55:59 +0000136 virtual void remove(boost::shared_ptr<Runnable> task) = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000137
Mark Slee5ea15f92007-03-05 22:55:59 +0000138 static boost::shared_ptr<ThreadManager> newThreadManager();
Marc Slemkod466b212006-07-20 00:04:18 +0000139
Mark Sleef5f2be42006-09-05 21:05:31 +0000140 /**
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000141 * Creates a simple thread manager the uses count number of worker threads and has
142 * a pendingTaskCountMax maximum pending tasks. The default, 0, specified no limit
143 * on pending tasks
Mark Sleef5f2be42006-09-05 21:05:31 +0000144 */
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000145 static boost::shared_ptr<ThreadManager> newSimpleThreadManager(size_t count=4, size_t pendingTaskCountMax=0);
Marc Slemko66949872006-07-15 01:52:39 +0000146
147 class Task;
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000148
Marc Slemko66949872006-07-15 01:52:39 +0000149 class Worker;
150
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000151 class Impl;
Marc Slemko66949872006-07-15 01:52:39 +0000152};
153
T Jake Lucianib5e62212009-01-31 22:36:20 +0000154}}} // apache::thrift::concurrency
Marc Slemko66949872006-07-15 01:52:39 +0000155
Mark Sleef5f2be42006-09-05 21:05:31 +0000156#endif // #ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_