blob: 6e5a17817e1af15b77d702e4fdc96f3ad8655f11 [file] [log] [blame]
Gavin McDonald0b75e1a2010-10-28 02:12:01 +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 */
19
20#ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_
21#define _THRIFT_CONCURRENCY_THREADMANAGER_H_ 1
22
23#include <boost/shared_ptr.hpp>
24#include <sys/types.h>
25#include "Thread.h"
26
27namespace apache { namespace thrift { namespace concurrency {
28
29/**
30 * Thread Pool Manager and related classes
31 *
32 * @version $Id:$
33 */
34class ThreadManager;
35
36/**
37 * ThreadManager class
38 *
39 * This class manages a pool of threads. It uses a ThreadFactory to create
40 * threads. It never actually creates or destroys worker threads, rather
41 * It maintains statistics on number of idle threads, number of active threads,
42 * task backlog, and average wait and service times and informs the PoolPolicy
43 * object bound to instances of this manager of interesting transitions. It is
44 * then up the PoolPolicy object to decide if the thread pool size needs to be
45 * adjusted and call this object addWorker and removeWorker methods to make
46 * changes.
47 *
48 * This design allows different policy implementations to used this code to
49 * handle basic worker thread management and worker task execution and focus on
50 * policy issues. The simplest policy, StaticPolicy, does nothing other than
51 * create a fixed number of threads.
52 */
53class ThreadManager {
54
55 protected:
56 ThreadManager() {}
57
58 public:
59 virtual ~ThreadManager() {}
60
61 /**
62 * Starts the thread manager. Verifies all attributes have been properly
63 * initialized, then allocates necessary resources to begin operation
64 */
65 virtual void start() = 0;
66
67 /**
68 * Stops the thread manager. Aborts all remaining unprocessed task, shuts
69 * down all created worker threads, and realeases all allocated resources.
70 * This method blocks for all worker threads to complete, thus it can
71 * potentially block forever if a worker thread is running a task that
72 * won't terminate.
73 */
74 virtual void stop() = 0;
75
76 /**
77 * Joins the thread manager. This is the same as stop, except that it will
78 * block until all the workers have finished their work. At that point
79 * the ThreadManager will transition into the STOPPED state.
80 */
81 virtual void join() = 0;
82
83 enum STATE {
84 UNINITIALIZED,
85 STARTING,
86 STARTED,
87 JOINING,
88 STOPPING,
89 STOPPED
90 };
91
92 virtual const STATE state() const = 0;
93
94 virtual boost::shared_ptr<ThreadFactory> threadFactory() const = 0;
95
96 virtual void threadFactory(boost::shared_ptr<ThreadFactory> value) = 0;
97
98 virtual void addWorker(size_t value=1) = 0;
99
100 virtual void removeWorker(size_t value=1) = 0;
101
102 /**
103 * Gets the current number of idle worker threads
104 */
105 virtual size_t idleWorkerCount() const = 0;
106
107 /**
108 * Gets the current number of total worker threads
109 */
110 virtual size_t workerCount() const = 0;
111
112 /**
113 * Gets the current number of pending tasks
114 */
115 virtual size_t pendingTaskCount() const = 0;
116
117 /**
118 * Gets the current number of pending and executing tasks
119 */
120 virtual size_t totalTaskCount() const = 0;
121
122 /**
123 * Gets the maximum pending task count. 0 indicates no maximum
124 */
125 virtual size_t pendingTaskCountMax() const = 0;
126
127 /**
128 * Adds a task to be executed at some time in the future by a worker thread.
129 *
130 * This method will block if pendingTaskCountMax() in not zero and pendingTaskCount()
131 * is greater than or equalt to pendingTaskCountMax(). If this method is called in the
132 * context of a ThreadManager worker thread it will throw a
133 * TooManyPendingTasksException
134 *
135 * @param task The task to queue for execution
136 *
137 * @param timeout Time to wait in milliseconds to add a task when a pending-task-count
138 * is specified. Specific cases:
139 * timeout = 0 : Wait forever to queue task.
140 * timeout = -1 : Return immediately if pending task count exceeds specified max
141 *
142 * @throws TooManyPendingTasksException Pending task count exceeds max pending task count
143 */
144 virtual void add(boost::shared_ptr<Runnable>task, int64_t timeout=0LL) = 0;
145
146 /**
147 * Removes a pending task
148 */
149 virtual void remove(boost::shared_ptr<Runnable> task) = 0;
150
151 static boost::shared_ptr<ThreadManager> newThreadManager();
152
153 /**
154 * Creates a simple thread manager the uses count number of worker threads and has
155 * a pendingTaskCountMax maximum pending tasks. The default, 0, specified no limit
156 * on pending tasks
157 */
158 static boost::shared_ptr<ThreadManager> newSimpleThreadManager(size_t count=4, size_t pendingTaskCountMax=0);
159
160 class Task;
161
162 class Worker;
163
164 class Impl;
165};
166
167}}} // apache::thrift::concurrency
168
169#endif // #ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_