apr_thread_pool.h revision 302408
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed
4 * with this work for additional information regarding copyright
5 * ownership.  The ASF licenses this file to you under the Apache
6 * License, Version 2.0 (the "License"); you may not use this file
7 * except in compliance with the License.  You may obtain a copy of
8 * 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, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15 * implied.  See the License for the specific language governing
16 * permissions and limitations under the License.
17 */
18
19#ifndef APU_THREAD_POOL_H
20#define APU_THREAD_POOL_H
21
22#include "apu.h"
23#include "apr_thread_proc.h"
24
25/**
26 * @file apr_thread_pool.h
27 * @brief APR Thread Pool Library
28
29 * @remarks This library implements a thread pool using apr_thread_t. A thread
30 * pool is a set of threads that can be created in advance or on demand until a
31 * maximum number. When a task is scheduled, the thread pool will find an idle
32 * thread to handle the task. In case all existing threads are busy and the
33 * number of tasks in the queue is higher than the adjustable threshold, the
34 * pool will try to create a new thread to serve the task if the maximum number
35 * has not been reached. Otherwise, the task will be put into a queue based on
36 * priority, which can be valued from 0 to 255, with higher values being served
37 * first. If there are tasks with the same priority, the new task might be put at
38 * the top or at the bottom - it depends on which function is used to put the task.
39 *
40 * @remarks There may be the case where the thread pool can use up to the maximum
41 * number of threads at peak load, but having those threads idle afterwards. A
42 * maximum number of idle threads can be set so that the extra idling threads will
43 * be terminated to save system resources.
44 */
45#if APR_HAS_THREADS
46
47#ifdef __cplusplus
48extern "C" {
49#endif /* __cplusplus */
50
51/**
52 * @defgroup APR_Util_TP Thread Pool routines
53 * @ingroup APR_Util
54 * @{
55 */
56
57/** Opaque Thread Pool structure. */
58typedef struct apr_thread_pool apr_thread_pool_t;
59
60#define APR_THREAD_TASK_PRIORITY_LOWEST 0
61#define APR_THREAD_TASK_PRIORITY_LOW 63
62#define APR_THREAD_TASK_PRIORITY_NORMAL 127
63#define APR_THREAD_TASK_PRIORITY_HIGH 191
64#define APR_THREAD_TASK_PRIORITY_HIGHEST 255
65
66/**
67 * Create a thread pool
68 * @param me The pointer in which to return the newly created apr_thread_pool
69 * object, or NULL if thread pool creation fails.
70 * @param init_threads The number of threads to be created initially, this number
71 * will also be used as the initial value for the maximum number of idle threads.
72 * @param max_threads The maximum number of threads that can be created
73 * @param pool The pool to use
74 * @return APR_SUCCESS if the thread pool was created successfully. Otherwise,
75 * the error code.
76 */
77APU_DECLARE(apr_status_t) apr_thread_pool_create(apr_thread_pool_t **me,
78                                                 apr_size_t init_threads,
79                                                 apr_size_t max_threads,
80                                                 apr_pool_t *pool);
81
82/**
83 * Destroy the thread pool and stop all the threads
84 * @return APR_SUCCESS if all threads are stopped.
85 */
86APU_DECLARE(apr_status_t) apr_thread_pool_destroy(apr_thread_pool_t *me);
87
88/**
89 * Schedule a task to the bottom of the tasks of same priority.
90 * @param me The thread pool
91 * @param func The task function
92 * @param param The parameter for the task function
93 * @param priority The priority of the task.
94 * @param owner Owner of this task.
95 * @return APR_SUCCESS if the task had been scheduled successfully
96 */
97APU_DECLARE(apr_status_t) apr_thread_pool_push(apr_thread_pool_t *me,
98                                               apr_thread_start_t func,
99                                               void *param,
100                                               apr_byte_t priority,
101                                               void *owner);
102/**
103 * Schedule a task to be run after a delay
104 * @param me The thread pool
105 * @param func The task function
106 * @param param The parameter for the task function
107 * @param time Time in microseconds
108 * @param owner Owner of this task.
109 * @return APR_SUCCESS if the task had been scheduled successfully
110 */
111APU_DECLARE(apr_status_t) apr_thread_pool_schedule(apr_thread_pool_t *me,
112                                                   apr_thread_start_t func,
113                                                   void *param,
114                                                   apr_interval_time_t time,
115                                                   void *owner);
116
117/**
118 * Schedule a task to the top of the tasks of same priority.
119 * @param me The thread pool
120 * @param func The task function
121 * @param param The parameter for the task function
122 * @param priority The priority of the task.
123 * @param owner Owner of this task.
124 * @return APR_SUCCESS if the task had been scheduled successfully
125 */
126APU_DECLARE(apr_status_t) apr_thread_pool_top(apr_thread_pool_t *me,
127                                              apr_thread_start_t func,
128                                              void *param,
129                                              apr_byte_t priority,
130                                              void *owner);
131
132/**
133 * Cancel tasks submitted by the owner. If there is any task from the owner that
134 * is currently running, the function will spin until the task finished.
135 * @param me The thread pool
136 * @param owner Owner of the task
137 * @return APR_SUCCESS if the task has been cancelled successfully
138 * @note The task function should not be calling cancel, otherwise the function
139 * may get stuck forever. The function assert if it detect such a case.
140 */
141APU_DECLARE(apr_status_t) apr_thread_pool_tasks_cancel(apr_thread_pool_t *me,
142                                                       void *owner);
143
144/**
145 * Get the current number of tasks waiting in the queue
146 * @param me The thread pool
147 * @return Number of tasks in the queue
148 */
149APU_DECLARE(apr_size_t) apr_thread_pool_tasks_count(apr_thread_pool_t *me);
150
151/**
152 * Get the current number of scheduled tasks waiting in the queue
153 * @param me The thread pool
154 * @return Number of scheduled tasks in the queue
155 */
156APU_DECLARE(apr_size_t) apr_thread_pool_scheduled_tasks_count(apr_thread_pool_t *me);
157
158/**
159 * Get the current number of threads
160 * @param me The thread pool
161 * @return Total number of threads
162 */
163APU_DECLARE(apr_size_t) apr_thread_pool_threads_count(apr_thread_pool_t *me);
164
165/**
166 * Get the current number of busy threads
167 * @param me The thread pool
168 * @return Number of busy threads
169 */
170APU_DECLARE(apr_size_t) apr_thread_pool_busy_count(apr_thread_pool_t *me);
171
172/**
173 * Get the current number of idle threads
174 * @param me The thread pool
175 * @return Number of idle threads
176 */
177APU_DECLARE(apr_size_t) apr_thread_pool_idle_count(apr_thread_pool_t *me);
178
179/**
180 * Access function for the maximum number of idle threads. Number of current
181 * idle threads will be reduced to the new limit.
182 * @param me The thread pool
183 * @param cnt The number
184 * @return The number of threads that were stopped.
185 */
186APU_DECLARE(apr_size_t) apr_thread_pool_idle_max_set(apr_thread_pool_t *me,
187                                                     apr_size_t cnt);
188
189/**
190 * Get number of tasks that have run
191 * @param me The thread pool
192 * @return Number of tasks that have run
193 */
194APU_DECLARE(apr_size_t)
195    apr_thread_pool_tasks_run_count(apr_thread_pool_t * me);
196
197/**
198 * Get high water mark of the number of tasks waiting to run
199 * @param me The thread pool
200 * @return High water mark of tasks waiting to run
201 */
202APU_DECLARE(apr_size_t)
203    apr_thread_pool_tasks_high_count(apr_thread_pool_t * me);
204
205/**
206 * Get high water mark of the number of threads
207 * @param me The thread pool
208 * @return High water mark of threads in thread pool
209 */
210APU_DECLARE(apr_size_t)
211    apr_thread_pool_threads_high_count(apr_thread_pool_t * me);
212
213/**
214 * Get the number of idle threads that were destroyed after timing out
215 * @param me The thread pool
216 * @return Number of idle threads that timed out
217 */
218APU_DECLARE(apr_size_t)
219    apr_thread_pool_threads_idle_timeout_count(apr_thread_pool_t * me);
220
221/**
222 * Access function for the maximum number of idle threads
223 * @param me The thread pool
224 * @return The current maximum number
225 */
226APU_DECLARE(apr_size_t) apr_thread_pool_idle_max_get(apr_thread_pool_t *me);
227
228/**
229 * Access function for the maximum number of threads.
230 * @param me The thread pool
231 * @param cnt Number of threads
232 * @return The original maximum number of threads
233 */
234APU_DECLARE(apr_size_t) apr_thread_pool_thread_max_set(apr_thread_pool_t *me,
235                                                       apr_size_t cnt);
236
237/**
238 * Access function for the maximum wait time (in microseconds) of an
239 * idling thread that exceeds the maximum number of idling threads.
240 * A non-zero value allows for the reaping of idling threads to shrink
241 * over time.  Which helps reduce thrashing.
242 * @param me The thread pool
243 * @param timeout The number of microseconds an idle thread should wait
244 * till it reaps itself
245 * @return The original maximum wait time
246 */
247APU_DECLARE(apr_interval_time_t)
248    apr_thread_pool_idle_wait_set(apr_thread_pool_t * me,
249                                  apr_interval_time_t timeout);
250
251/**
252 * Access function for the maximum wait time (in microseconds) of an
253 * idling thread that exceeds the maximum number of idling threads
254 * @param me The thread pool
255 * @return The current maximum wait time
256 */
257APU_DECLARE(apr_interval_time_t)
258    apr_thread_pool_idle_wait_get(apr_thread_pool_t * me);
259
260/**
261 * Access function for the maximum number of threads
262 * @param me The thread pool
263 * @return The current maximum number
264 */
265APU_DECLARE(apr_size_t) apr_thread_pool_thread_max_get(apr_thread_pool_t *me);
266
267/**
268 * Access function for the threshold of tasks in queue to trigger a new thread.
269 * @param me The thread pool
270 * @param cnt The new threshold
271 * @return The original threshold
272 */
273APU_DECLARE(apr_size_t) apr_thread_pool_threshold_set(apr_thread_pool_t *me,
274                                                      apr_size_t val);
275
276/**
277 * Access function for the threshold of tasks in queue to trigger a new thread.
278 * @param me The thread pool
279 * @return The current threshold
280 */
281APU_DECLARE(apr_size_t) apr_thread_pool_threshold_get(apr_thread_pool_t * me);
282
283/**
284 * Get owner of the task currently been executed by the thread.
285 * @param thd The thread is executing a task
286 * @param owner Pointer to receive owner of the task.
287 * @return APR_SUCCESS if the owner is retrieved successfully
288 */
289APU_DECLARE(apr_status_t) apr_thread_pool_task_owner_get(apr_thread_t *thd,
290                                                         void **owner);
291
292/** @} */
293
294#ifdef __cplusplus
295}
296#endif
297
298#endif /* APR_HAS_THREADS */
299#endif /* !APR_THREAD_POOL_H */
300