blob: 95c490686b2bd7bbd2c159c2ed8fb528fa3986d7 [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Mark Slee9f0c6512007-02-28 23:58:26 +000019
Mark Sleef5f2be42006-09-05 21:05:31 +000020#ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_
21#define _THRIFT_CONCURRENCY_THREADMANAGER_H_ 1
Marc Slemko66949872006-07-15 01:52:39 +000022
Marc Slemko6f038a72006-08-03 18:58:09 +000023#include <boost/shared_ptr.hpp>
David Reiss068f4162010-03-09 05:19:45 +000024#include <tr1/functional>
Marc Slemko0e53ccd2006-07-17 23:51:05 +000025#include <sys/types.h>
Marc Slemko66949872006-07-15 01:52:39 +000026#include "Thread.h"
27
T Jake Lucianib5e62212009-01-31 22:36:20 +000028namespace apache { namespace thrift { namespace concurrency {
Marc Slemko66949872006-07-15 01:52:39 +000029
Mark Sleef5f2be42006-09-05 21:05:31 +000030/**
31 * Thread Pool Manager and related classes
32 *
Mark Sleef5f2be42006-09-05 21:05:31 +000033 * @version $Id:$
34 */
Marc Slemko66949872006-07-15 01:52:39 +000035class ThreadManager;
36
Mark Sleef5f2be42006-09-05 21:05:31 +000037/**
38 * ThreadManager class
39 *
40 * This class manages a pool of threads. It uses a ThreadFactory to create
41 * threads. It never actually creates or destroys worker threads, rather
42 * It maintains statistics on number of idle threads, number of active threads,
43 * task backlog, and average wait and service times and informs the PoolPolicy
44 * object bound to instances of this manager of interesting transitions. It is
45 * then up the PoolPolicy object to decide if the thread pool size needs to be
46 * adjusted and call this object addWorker and removeWorker methods to make
47 * changes.
48 *
49 * This design allows different policy implementations to used this code to
50 * handle basic worker thread management and worker task execution and focus on
51 * policy issues. The simplest policy, StaticPolicy, does nothing other than
52 * create a fixed number of threads.
53 */
Marc Slemko66949872006-07-15 01:52:39 +000054class ThreadManager {
55
Mark Slee8cbda852007-02-01 23:05:38 +000056 protected:
Marc Slemkod466b212006-07-20 00:04:18 +000057 ThreadManager() {}
Marc Slemko66949872006-07-15 01:52:39 +000058
Mark Slee8cbda852007-02-01 23:05:38 +000059 public:
David Reiss068f4162010-03-09 05:19:45 +000060 class Task;
61 typedef std::tr1::function<void(boost::shared_ptr<Runnable>)> ExpireCallback;
62
Marc Slemkod466b212006-07-20 00:04:18 +000063 virtual ~ThreadManager() {}
Marc Slemko66949872006-07-15 01:52:39 +000064
Mark Sleef5f2be42006-09-05 21:05:31 +000065 /**
66 * Starts the thread manager. Verifies all attributes have been properly
67 * initialized, then allocates necessary resources to begin operation
68 */
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000069 virtual void start() = 0;
70
Mark Sleef5f2be42006-09-05 21:05:31 +000071 /**
72 * Stops the thread manager. Aborts all remaining unprocessed task, shuts
73 * down all created worker threads, and realeases all allocated resources.
74 * This method blocks for all worker threads to complete, thus it can
Marc Slemko3a3b53b2007-05-22 23:59:54 +000075 * potentially block forever if a worker thread is running a task that
Mark Sleef5f2be42006-09-05 21:05:31 +000076 * won't terminate.
77 */
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000078 virtual void stop() = 0;
79
Mark Slee7c10eaf2007-03-01 02:45:10 +000080 /**
81 * Joins the thread manager. This is the same as stop, except that it will
82 * block until all the workers have finished their work. At that point
83 * the ThreadManager will transition into the STOPPED state.
84 */
Mark Slee6e3f6372007-03-01 22:05:46 +000085 virtual void join() = 0;
86
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000087 enum STATE {
88 UNINITIALIZED,
89 STARTING,
90 STARTED,
Mark Slee7c10eaf2007-03-01 02:45:10 +000091 JOINING,
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000092 STOPPING,
93 STOPPED
94 };
Marc Slemko3a3b53b2007-05-22 23:59:54 +000095
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000096 virtual const STATE state() const = 0;
97
Mark Slee5ea15f92007-03-05 22:55:59 +000098 virtual boost::shared_ptr<ThreadFactory> threadFactory() const = 0;
Marc Slemko66949872006-07-15 01:52:39 +000099
Mark Slee5ea15f92007-03-05 22:55:59 +0000100 virtual void threadFactory(boost::shared_ptr<ThreadFactory> value) = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000101
Marc Slemkod466b212006-07-20 00:04:18 +0000102 virtual void addWorker(size_t value=1) = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000103
Marc Slemkod466b212006-07-20 00:04:18 +0000104 virtual void removeWorker(size_t value=1) = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000105
Mark Sleef5f2be42006-09-05 21:05:31 +0000106 /**
107 * Gets the current number of idle worker threads
108 */
Marc Slemko66949872006-07-15 01:52:39 +0000109 virtual size_t idleWorkerCount() const = 0;
110
Mark Sleef5f2be42006-09-05 21:05:31 +0000111 /**
112 * Gets the current number of total worker threads
113 */
Marc Slemko66949872006-07-15 01:52:39 +0000114 virtual size_t workerCount() const = 0;
115
Mark Sleef5f2be42006-09-05 21:05:31 +0000116 /**
117 * Gets the current number of pending tasks
118 */
Marc Slemko66949872006-07-15 01:52:39 +0000119 virtual size_t pendingTaskCount() const = 0;
120
Mark Sleef5f2be42006-09-05 21:05:31 +0000121 /**
122 * Gets the current number of pending and executing tasks
123 */
Marc Slemko66949872006-07-15 01:52:39 +0000124 virtual size_t totalTaskCount() const = 0;
125
Mark Sleef5f2be42006-09-05 21:05:31 +0000126 /**
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000127 * Gets the maximum pending task count. 0 indicates no maximum
Mark Sleef5f2be42006-09-05 21:05:31 +0000128 */
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000129 virtual size_t pendingTaskCountMax() const = 0;
130
131 /**
David Reiss068f4162010-03-09 05:19:45 +0000132 * Gets the number of tasks which have been expired without being run.
133 */
134 virtual size_t expiredTaskCount() = 0;
135
136 /**
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000137 * Adds a task to be executed at some time in the future by a worker thread.
138 *
139 * This method will block if pendingTaskCountMax() in not zero and pendingTaskCount()
140 * is greater than or equalt to pendingTaskCountMax(). If this method is called in the
141 * context of a ThreadManager worker thread it will throw a
142 * TooManyPendingTasksException
143 *
144 * @param task The task to queue for execution
145 *
146 * @param timeout Time to wait in milliseconds to add a task when a pending-task-count
Aditya Agarwal4b6ff2d2007-12-25 22:58:50 +0000147 * is specified. Specific cases:
148 * timeout = 0 : Wait forever to queue task.
149 * timeout = -1 : Return immediately if pending task count exceeds specified max
David Reiss068f4162010-03-09 05:19:45 +0000150 * @param expiration when nonzero, the number of milliseconds the task is valid
151 * to be run; if exceeded, the task will be dropped off the queue and not run.
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000152 *
153 * @throws TooManyPendingTasksException Pending task count exceeds max pending task count
154 */
David Reiss068f4162010-03-09 05:19:45 +0000155 virtual void add(boost::shared_ptr<Runnable>task,
156 int64_t timeout=0LL,
157 int64_t expiration=0LL) = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000158
Mark Sleef5f2be42006-09-05 21:05:31 +0000159 /**
160 * Removes a pending task
161 */
Mark Slee5ea15f92007-03-05 22:55:59 +0000162 virtual void remove(boost::shared_ptr<Runnable> task) = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000163
David Reiss01fe1532010-03-09 05:19:25 +0000164 /**
165 * Remove the next pending task which would be run.
166 *
167 * @return the task removed.
168 */
169 virtual boost::shared_ptr<Runnable> removeNextPending() = 0;
170
David Reiss068f4162010-03-09 05:19:45 +0000171 /**
172 * Remove tasks from front of task queue that have expired.
173 */
174 virtual void removeExpiredTasks() = 0;
175
176 /**
177 * Set a callback to be called when a task is expired and not run.
178 *
179 * @param expireCallback a function called with the shared_ptr<Runnable> for
180 * the expired task.
181 */
182 virtual void setExpireCallback(ExpireCallback expireCallback) = 0;
183
Mark Slee5ea15f92007-03-05 22:55:59 +0000184 static boost::shared_ptr<ThreadManager> newThreadManager();
Marc Slemkod466b212006-07-20 00:04:18 +0000185
Mark Sleef5f2be42006-09-05 21:05:31 +0000186 /**
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000187 * Creates a simple thread manager the uses count number of worker threads and has
188 * a pendingTaskCountMax maximum pending tasks. The default, 0, specified no limit
189 * on pending tasks
Mark Sleef5f2be42006-09-05 21:05:31 +0000190 */
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000191 static boost::shared_ptr<ThreadManager> newSimpleThreadManager(size_t count=4, size_t pendingTaskCountMax=0);
Marc Slemko66949872006-07-15 01:52:39 +0000192
193 class Task;
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000194
Marc Slemko66949872006-07-15 01:52:39 +0000195 class Worker;
196
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000197 class Impl;
Marc Slemko66949872006-07-15 01:52:39 +0000198};
199
T Jake Lucianib5e62212009-01-31 22:36:20 +0000200}}} // apache::thrift::concurrency
Marc Slemko66949872006-07-15 01:52:39 +0000201
Mark Sleef5f2be42006-09-05 21:05:31 +0000202#endif // #ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_