123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- /*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2012-2013, Digium, Inc.
- *
- * Mark Michelson <mmmichelson@digium.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
- #ifndef _ASTERISK_THREADPOOL_H
- #define _ASTERISK_THREADPOOL_H
- struct ast_threadpool;
- struct ast_taskprocessor;
- struct ast_threadpool_listener;
- struct ast_threadpool_listener_callbacks {
- /*!
- * \brief Indicates that the state of threads in the pool has changed
- *
- * \param pool The pool whose state has changed
- * \param listener The threadpool listener
- * \param active_threads The number of active threads in the pool
- * \param idle_threads The number of idle threads in the pool
- */
- void (*state_changed)(struct ast_threadpool *pool,
- struct ast_threadpool_listener *listener,
- int active_threads,
- int idle_threads);
- /*!
- * \brief Indicates that a task was pushed to the threadpool
- *
- * \param pool The pool that had a task pushed
- * \param listener The threadpool listener
- * \param was_empty Indicates whether there were any tasks prior to adding the new one.
- */
- void (*task_pushed)(struct ast_threadpool *pool,
- struct ast_threadpool_listener *listener,
- int was_empty);
- /*!
- * \brief Indicates the threadpool's taskprocessor has become empty
- *
- * \param pool The pool that has become empty
- * \param listener The threadpool's listener
- */
- void (*emptied)(struct ast_threadpool *pool, struct ast_threadpool_listener *listener);
- /*!
- * \brief The threadpool is shutting down
- *
- * This would be an opportune time to free the listener's user data
- * if one wishes. However, it is acceptable to not do so if the user data
- * should persist beyond the lifetime of the pool.
- *
- * \param listener The threadpool's listener
- */
- void (*shutdown)(struct ast_threadpool_listener *listener);
- };
- struct ast_threadpool_options {
- #define AST_THREADPOOL_OPTIONS_VERSION 1
- /*! Version of threadpool options in use */
- int version;
- /*!
- * \brief Time limit in seconds for idle threads
- *
- * A time of 0 or less will mean no timeout.
- */
- int idle_timeout;
- /*!
- * \brief Number of threads to increment pool by
- *
- * If a task is added into a pool and no idle thread is
- * available to activate, then the pool can automatically
- * grow by the given amount.
- *
- * Zero is a perfectly valid value to give here if you want
- * to control threadpool growth yourself via your listener.
- */
- int auto_increment;
- /*!
- * \brief Number of threads the pool will start with
- *
- * When the threadpool is allocated, it will immediately size
- * itself to have this number of threads in it.
- *
- * Zero is a valid value if the threadpool should start
- * without any threads allocated.
- */
- int initial_size;
- /*!
- * \brief Maximum number of threads a pool may have
- *
- * When the threadpool's size increases, it can never increase
- * beyond this number of threads.
- *
- * Zero is a valid value if the threadpool does not have a
- * maximum size.
- */
- int max_size;
- /*!
- * \brief Function to call when a thread starts
- *
- * This is useful if there is something common that all threads
- * in a threadpool need to do when they start.
- */
- void (*thread_start)(void);
- /*!
- * \brief Function to call when a thread ends
- *
- * This is useful if there is common cleanup to execute when
- * a thread completes
- */
- void (*thread_end)(void);
- };
- /*!
- * \brief Allocate a threadpool listener
- *
- * This function will call back into the alloc callback for the
- * listener.
- *
- * \param callbacks Listener callbacks to assign to the listener
- * \param user_data User data to be stored in the threadpool listener
- * \retval NULL Failed to allocate the listener
- * \retval non-NULL The newly-created threadpool listener
- */
- struct ast_threadpool_listener *ast_threadpool_listener_alloc(
- const struct ast_threadpool_listener_callbacks *callbacks, void *user_data);
- /*!
- * \brief Get the threadpool listener's user data
- * \param listener The threadpool listener
- * \return The user data
- */
- void *ast_threadpool_listener_get_user_data(const struct ast_threadpool_listener *listener);
- /*!
- * \brief Create a new threadpool
- *
- * This function creates a threadpool. Tasks may be pushed onto this thread pool
- * and will be automatically acted upon by threads within the pool.
- *
- * Only a single threadpool with a given name may exist. This function will fail
- * if a threadpool with the given name already exists.
- *
- * \param name The unique name for the threadpool
- * \param listener The listener the threadpool will notify of changes. Can be NULL.
- * \param options The behavioral options for this threadpool
- * \retval NULL Failed to create the threadpool
- * \retval non-NULL The newly-created threadpool
- */
- struct ast_threadpool *ast_threadpool_create(const char *name,
- struct ast_threadpool_listener *listener,
- const struct ast_threadpool_options *options);
- /*!
- * \brief Set the number of threads for the thread pool
- *
- * This number may be more or less than the current number of
- * threads in the threadpool.
- *
- * \param threadpool The threadpool to adjust
- * \param size The new desired size of the threadpool
- */
- void ast_threadpool_set_size(struct ast_threadpool *threadpool, unsigned int size);
- /*!
- * \brief Push a task to the threadpool
- *
- * Tasks pushed into the threadpool will be automatically taken by
- * one of the threads within
- * \param pool The threadpool to add the task to
- * \param task The task to add
- * \param data The parameter for the task
- * \retval 0 success
- * \retval -1 failure
- */
- int ast_threadpool_push(struct ast_threadpool *pool, int (*task)(void *data), void *data)
- attribute_warn_unused_result;
- /*!
- * \brief Shut down a threadpool and destroy it
- *
- * \param pool The pool to shut down
- */
- void ast_threadpool_shutdown(struct ast_threadpool *pool);
- struct ast_serializer_shutdown_group;
- /*!
- * \brief Create a serializer group shutdown control object.
- * \since 13.5.0
- *
- * \return ao2 object to control shutdown of a serializer group.
- */
- struct ast_serializer_shutdown_group *ast_serializer_shutdown_group_alloc(void);
- /*!
- * \brief Wait for the serializers in the group to shutdown with timeout.
- * \since 13.5.0
- *
- * \param shutdown_group Group shutdown controller. (Returns 0 immediately if NULL)
- * \param timeout Number of seconds to wait for the serializers in the group to shutdown.
- * Zero if the timeout is disabled.
- *
- * \return Number of seriaizers that did not get shutdown within the timeout.
- */
- int ast_serializer_shutdown_group_join(struct ast_serializer_shutdown_group *shutdown_group, int timeout);
- /*!
- * \brief Get the threadpool serializer currently associated with this thread.
- * \since 14.0.0
- *
- * \note The returned pointer is valid while the serializer
- * thread is running.
- *
- * \note Use ao2_ref() on serializer if you are going to keep it
- * for another thread. To unref it you must then use
- * ast_taskprocessor_unreference().
- *
- * \retval serializer on success.
- * \retval NULL on error or no serializer associated with the thread.
- */
- struct ast_taskprocessor *ast_threadpool_serializer_get_current(void);
- /*!
- * \brief Serialized execution of tasks within a \ref ast_threadpool.
- *
- * \since 12.0.0
- *
- * A \ref ast_taskprocessor with the same contract as a default taskprocessor
- * (tasks execute serially) except instead of executing out of a dedicated
- * thread, execution occurs in a thread from a \ref ast_threadpool. Think of it
- * as a lightweight thread.
- *
- * While it guarantees that each task will complete before executing the next,
- * there is no guarantee as to which thread from the \c pool individual tasks
- * will execute. This normally only matters if your code relys on thread
- * specific information, such as thread locals.
- *
- * Use ast_taskprocessor_unreference() to dispose of the returned \ref
- * ast_taskprocessor.
- *
- * Only a single taskprocessor with a given name may exist. This function will fail
- * if a taskprocessor with the given name already exists.
- *
- * \param name Name of the serializer. (must be unique)
- * \param pool \ref ast_threadpool for execution.
- *
- * \return \ref ast_taskprocessor for enqueuing work.
- * \return \c NULL on error.
- */
- struct ast_taskprocessor *ast_threadpool_serializer(const char *name, struct ast_threadpool *pool);
- /*!
- * \brief Serialized execution of tasks within a \ref ast_threadpool.
- * \since 13.5.0
- *
- * A \ref ast_taskprocessor with the same contract as a default taskprocessor
- * (tasks execute serially) except instead of executing out of a dedicated
- * thread, execution occurs in a thread from a \ref ast_threadpool. Think of it
- * as a lightweight thread.
- *
- * While it guarantees that each task will complete before executing the next,
- * there is no guarantee as to which thread from the \c pool individual tasks
- * will execute. This normally only matters if your code relys on thread
- * specific information, such as thread locals.
- *
- * Use ast_taskprocessor_unreference() to dispose of the returned \ref
- * ast_taskprocessor.
- *
- * Only a single taskprocessor with a given name may exist. This function will fail
- * if a taskprocessor with the given name already exists.
- *
- * \param name Name of the serializer. (must be unique)
- * \param pool \ref ast_threadpool for execution.
- * \param shutdown_group Group shutdown controller. (NULL if no group association)
- *
- * \return \ref ast_taskprocessor for enqueuing work.
- * \return \c NULL on error.
- */
- struct ast_taskprocessor *ast_threadpool_serializer_group(const char *name,
- struct ast_threadpool *pool, struct ast_serializer_shutdown_group *shutdown_group);
- /*!
- * \brief Return the size of the threadpool's task queue
- * \since 13.7.0
- */
- long ast_threadpool_queue_size(struct ast_threadpool *pool);
- #endif /* ASTERISK_THREADPOOL_H */
|