50 int (*execute)(
void *
datap);
57 unsigned int wants_local:1;
85 unsigned int executing:1;
87 unsigned int high_water_warned:1;
89 unsigned int high_water_alert:1;
91 unsigned int suspended:1;
124 unsigned int alert_count;
130 #define TPS_MAX_BUCKETS 61
133 #define TPS_MAX_BUCKETS 1567
140 static ast_cond_t cli_ping_cond;
143 AST_MUTEX_DEFINE_STATIC(cli_ping_cond_lock);
146 static int tps_hash_cb(
const void *obj,
const int flags);
148 static int tps_cmp_cb(
void *obj,
void *arg,
int flags);
159 static int tps_sort_cb(
const void *obj_left,
const void *obj_right,
int flags);
163 AST_CLI_DEFINE(cli_tps_ping,
"Ping a named task processor"),
164 AST_CLI_DEFINE(cli_tps_report,
"List instantiated task processors and statistics"),
165 AST_CLI_DEFINE(cli_subsystem_alert_report,
"List task processor subsystems in alert"),
166 AST_CLI_DEFINE(cli_tps_reset_stats,
"Reset a named task processor's stats"),
167 AST_CLI_DEFINE(cli_tps_reset_stats_all,
"Reset all task processors' stats"),
171 pthread_t poll_thread;
178 ast_assert(pvt->dead);
187 default_listener_pvt_destroy(pvt);
206 if (res != 0 && errno != EINTR) {
207 ast_log(LOG_ERROR,
"ast_sem_wait(): %s\n",
217 ast_assert(res == 0 && sem_value == 0);
220 ao2_t_ref(listener->
tps, -1,
"tps-shutdown");
241 ast_log(LOG_ERROR,
"Failed to notify of enqueued task: %s\n",
246 static int default_listener_die(
void *data)
259 ao2_t_ref(listener->
tps, +1,
"tps-shutdown");
264 default_listener_die(pvt);
267 ast_assert(pvt->poll_thread != AST_PTHREADT_NULL);
269 if (pthread_equal(pthread_self(), pvt->poll_thread)) {
270 res = pthread_detach(pvt->poll_thread);
272 ast_log(LOG_ERROR,
"pthread_detach(): %s\n", strerror(errno));
275 res = pthread_join(pvt->poll_thread, NULL);
277 ast_log(LOG_ERROR,
"pthread_join(): %s\n", strerror(errno));
280 pvt->poll_thread = AST_PTHREADT_NULL;
284 .
start = default_listener_start,
285 .task_pushed = default_task_pushed,
286 .shutdown = default_listener_shutdown,
287 .dtor = default_listener_pvt_dtor,
291 #define AST_TASKPROCESSOR_SHUTDOWN_MAX_WAIT 10
297 static void tps_shutdown(
void)
304 struct timespec delay = {1, 0};
315 "waiting for taskprocessor shutdown, %d tps object(s) still allocated.\n",
321 while (nanosleep(&delay, &delay));
330 "waiting for taskprocessor shutdown, %d tps object(s) still allocated.\n",
339 "Asertion may occur, the following taskprocessors are still runing:\n");
344 ast_log(LOG_ERROR,
"unable to get sorted list of taskprocessors");
348 while ((tps = ao2_iterator_next(&iter))) {
349 ast_log(LOG_ERROR,
"taskprocessor '%s'\n", tps->
name);
353 ao2_cleanup(sorted_tps);
357 "All waiting taskprocessors cleared!\n");
363 ao2_t_ref(tps_singletons, -1,
"Unref tps_singletons in shutdown");
364 tps_singletons = NULL;
372 if (!tps_singletons) {
373 ast_log(LOG_ERROR,
"taskprocessor container failed to initialize!\n");
379 ast_log(LOG_ERROR,
"taskprocessor subsystems vector failed to initialize!\n");
383 ast_cond_init(&cli_ping_cond, NULL);
393 static struct tps_task *tps_task_alloc(
int (*task_exe)(
void *datap),
void *datap)
397 ast_log(LOG_ERROR,
"task_exe is NULL!\n");
403 ast_log(LOG_ERROR,
"failed to allocate task!\n");
417 ast_log(LOG_ERROR,
"task_exe is NULL!\n");
423 ast_log(LOG_ERROR,
"failed to allocate task!\n");
427 t->
callback.execute_local = task_exe;
446 static char *tps_taskprocessor_tab_complete(
struct ast_cli_args *a)
452 tklen = strlen(a->word);
454 while ((p = ao2_iterator_next(&i))) {
455 if (!strncasecmp(a->word, p->
name, tklen)) {
471 ast_mutex_lock(&cli_ping_cond_lock);
472 ast_cond_signal(&cli_ping_cond);
473 ast_mutex_unlock(&cli_ping_cond_lock);
480 struct timeval begin, end, delta;
488 e->
command =
"core ping taskprocessor";
490 "Usage: core ping taskprocessor <taskprocessor>\n"
491 " Displays the time required for a task to be processed\n";
495 return tps_taskprocessor_tab_complete(a);
502 return CLI_SHOWUSAGE;
506 ast_cli(a->fd,
"\nping failed: %s not found\n\n", name);
509 ast_cli(a->fd,
"\npinging %s ...", name);
519 ts.tv_sec = when.tv_sec;
520 ts.tv_nsec = when.tv_usec * 1000;
522 ast_mutex_lock(&cli_ping_cond_lock);
524 ast_mutex_unlock(&cli_ping_cond_lock);
525 ast_cli(a->fd,
"\nping failed: could not push task to %s\n\n", name);
529 ast_cond_timedwait(&cli_ping_cond, &cli_ping_cond_lock, &ts);
530 ast_mutex_unlock(&cli_ping_cond_lock);
534 ast_cli(a->fd,
"\n\t%24s ping time: %.1ld.%.6ld sec\n\n", name, (
long)delta.tv_sec, (
long int)delta.tv_usec);
555 static int tps_sort_cb(
const void *obj_left,
const void *obj_right,
int flags)
559 const char *right_key = obj_right;
565 right_key = tps_right->
name;
568 cmp = strcasecmp(tps_left->
name, right_key);
571 cmp = strncasecmp(tps_left->
name, right_key, strlen(right_key));
577 #define FMT_HEADERS "%-70s %10s %10s %10s %10s %10s\n"
578 #define FMT_FIELDS "%-70s %10lu %10lu %10lu %10lu %10lu\n"
588 static void tps_report_taskprocessor_list_helper(
int fd,
struct ast_taskprocessor *tps)
606 static int tps_report_taskprocessor_list(
int fd,
const char *like)
618 ast_debug(1,
"Failed to retrieve sorted taskprocessors\n");
619 ao2_cleanup(sorted_tps);
623 word_len = strlen(like);
625 while ((tps = ao2_iterator_next(&iter))) {
627 if (!strncasecmp(like, tps->
name, word_len)) {
628 tps_report_taskprocessor_list_helper(fd, tps);
632 tps_report_taskprocessor_list_helper(fd, tps);
649 e->
command =
"core show taskprocessors [like]";
651 "Usage: core show taskprocessors [like keyword]\n"
652 " Shows a list of instantiated task processors and their statistics\n";
655 if (a->pos == e->
args) {
656 return tps_taskprocessor_tab_complete(a);
662 if (a->argc == e->
args - 1) {
664 }
else if (a->argc == e->
args + 1 && !strcasecmp(a->argv[e->
args-1],
"like")) {
665 like = a->argv[e->
args];
667 return CLI_SHOWUSAGE;
670 ast_cli(a->fd,
"\n" FMT_HEADERS,
"Processor",
"Processed",
"In Queue",
"Max Depth",
"Low water",
"High water");
671 ast_cli(a->fd,
"\n%d taskprocessors\n\n", tps_report_taskprocessor_list(a->fd, like));
680 const char *name = flags &
OBJ_KEY ? obj : tps->
name;
689 const char *rhsname = flags &
OBJ_KEY ? arg : rhs->name;
696 return !strcmp(alert->subsystem, subsystem);
701 return strcmp(a->subsystem, b->subsystem);
707 unsigned int count = 0;
714 count = alert->alert_count;
721 static void subsystem_alert_increment(
const char *subsystem)
726 if (ast_strlen_zero(subsystem)) {
734 alert->alert_count++;
739 alert =
ast_malloc(
sizeof(*alert) + strlen(subsystem) + 1);
744 alert->alert_count = 1;
745 strcpy(alert->subsystem, subsystem);
753 static void subsystem_alert_decrement(
const char *subsystem)
758 if (ast_strlen_zero(subsystem)) {
766 "Can't decrement alert count for subsystem '%s' as it wasn't in alert\n", subsystem);
772 alert->alert_count--;
773 if (alert->alert_count <= 0) {
782 struct subsystem_alert_vector *vector)
785 alert_copy =
ast_malloc(
sizeof(*alert_copy) + strlen(alert->subsystem) + 1);
789 alert_copy->alert_count = alert->alert_count;
790 strcpy(alert_copy->subsystem, alert->subsystem);
792 ast_free(alert_copy);
798 struct subsystem_alert_vector sorted_subsystems;
801 #define FMT_HEADERS_SUBSYSTEM "%-32s %12s\n"
802 #define FMT_FIELDS_SUBSYSTEM "%-32s %12u\n"
806 e->
command =
"core show taskprocessor alerted subsystems";
808 "Usage: core show taskprocessor alerted subsystems\n"
809 " Shows a list of task processor subsystems that are currently alerted\n";
815 if (a->argc != e->
args) {
816 return CLI_SHOWUSAGE;
825 subsystem_copy(
AST_VECTOR_GET(&overloaded_subsystems, i), &sorted_subsystems);
829 ast_cli(a->fd,
"\n" FMT_HEADERS_SUBSYSTEM,
"Subsystem",
"Alert Count");
833 ast_cli(a->fd, FMT_FIELDS_SUBSYSTEM, alert->subsystem, alert->alert_count);
836 ast_cli(a->fd,
"\n%zu subsystems\n\n",
AST_VECTOR_SIZE(&sorted_subsystems));
865 tps_alert_count += delta;
868 && !old != !tps_alert_count) {
869 ast_log(LOG_DEBUG,
"Taskprocessor '%s' %s the high water alert.\n",
870 tps->
name, tps_alert_count ?
"triggered" :
"cleared");
875 subsystem_alert_increment(tps->
subsystem);
877 subsystem_alert_decrement(tps->
subsystem);
897 if (!tps || high_water < 0 || high_water < low_water) {
903 low_water = (high_water * 9) / 10;
915 tps_alert_add(tps, -1);
918 if (high_water < tps->tps_queue_size) {
921 tps_alert_add(tps, +1);
931 static void tps_taskprocessor_dtor(
void *tps)
943 tps_alert_add(t, -1);
946 ao2_cleanup(t->listener);
959 tps_alert_add(tps, -1);
974 ast_log(LOG_ERROR,
"no taskprocessor specified!\n");
986 static void taskprocessor_listener_dtor(
void *obj)
999 listener = ao2_alloc(
sizeof(*listener), taskprocessor_listener_dtor);
1012 return listener->
tps;
1020 static void *default_listener_pvt_alloc(
void)
1028 pvt->poll_thread = AST_PTHREADT_NULL;
1030 ast_log(LOG_ERROR,
"ast_sem_init(): %s\n", strerror(errno));
1051 char *subsystem_separator;
1052 size_t subsystem_length = 0;
1055 name_length = strlen(name);
1056 subsystem_separator = strchr(name,
'/');
1057 if (subsystem_separator) {
1058 subsystem_length = subsystem_separator -
name;
1061 p = ao2_alloc(
sizeof(*p) + name_length + subsystem_length + 2, tps_taskprocessor_dtor);
1063 ast_log(LOG_WARNING,
"failed to create taskprocessor '%s'\n", name);
1071 strcpy(p->
name, name);
1076 p->listener = listener;
1078 p->
thread = AST_PTHREADT_NULL;
1084 ast_log(LOG_ERROR,
"Failed to add taskprocessor '%s' to container\n", p->
name);
1085 listener->
tps = NULL;
1096 ast_log(LOG_ERROR,
"Unable to start taskprocessor listener for taskprocessor %s\n",
1115 if (ast_strlen_zero(name)) {
1116 ast_log(LOG_ERROR,
"requesting a nameless taskprocessor!!!\n");
1119 ao2_lock(tps_singletons);
1123 ao2_unlock(tps_singletons);
1128 pvt = default_listener_pvt_alloc();
1130 ao2_unlock(tps_singletons);
1135 ao2_unlock(tps_singletons);
1136 default_listener_pvt_destroy(pvt);
1140 p = __allocate_taskprocessor(name, listener);
1141 ao2_unlock(tps_singletons);
1142 p = __start_taskprocessor(p);
1152 ao2_lock(tps_singletons);
1155 ao2_unlock(tps_singletons);
1160 p = __allocate_taskprocessor(name, listener);
1161 ao2_unlock(tps_singletons);
1163 return __start_taskprocessor(p);
1170 tps->local_data = local_data;
1184 ao2_lock(tps_singletons);
1187 ao2_unlock(tps_singletons);
1197 ao2_unlock(tps_singletons);
1199 listener_shutdown(tps->listener);
1210 ast_log(LOG_ERROR,
"tps is NULL!\n");
1215 ast_log(LOG_ERROR,
"t is NULL!\n");
1225 ast_log(LOG_WARNING,
"The '%s' task processor queue reached %ld scheduled tasks%s.\n",
1229 tps_alert_add(tps, +1);
1234 was_empty = tps->
executing ? 0 : previous_size == 0;
1242 return taskprocessor_push(tps, tps_task_alloc(task_exe, datap));
1247 return taskprocessor_push(tps, tps_task_alloc_local(task_exe, datap));
1284 t = tps_taskprocessor_pop(tps);
1290 tps->
thread = pthread_self();
1293 if (t->wants_local) {
1299 if (t->wants_local) {
1307 tps->
thread = AST_PTHREADT_NULL;
1336 is_task = pthread_equal(tps->
thread, pthread_self());
1348 #define SEQ_STR_SIZE (1 + 8 + 1)
1352 int final_size = strlen(name) + SEQ_STR_SIZE;
1354 ast_assert(buf != NULL && name != NULL);
1355 ast_assert(final_size <= size);
1365 ast_assert(buf != NULL);
1366 ast_assert(SEQ_STR_SIZE <= size);
1368 va_start(ap, format);
1369 user_size = vsnprintf(buf, size - (SEQ_STR_SIZE - 1), format, ap);
1371 if (user_size < 0) {
1377 }
else if (size < user_size + SEQ_STR_SIZE) {
1379 user_size = size - SEQ_STR_SIZE;
1401 e->
command =
"core reset taskprocessor";
1403 "Usage: core reset taskprocessor <taskprocessor>\n"
1404 " Resets stats for the specified taskprocessor\n";
1407 return tps_taskprocessor_tab_complete(a);
1411 return CLI_SHOWUSAGE;
1416 ast_cli(a->fd,
"\nReset failed: %s not found\n\n", name);
1419 ast_cli(a->fd,
"\nResetting %s\n\n", name);
1421 tps_reset_stats(tps);
1435 e->
command =
"core reset taskprocessors";
1437 "Usage: core reset taskprocessors\n"
1438 " Resets stats for all taskprocessors\n";
1444 if (a->argc != e->
args) {
1445 return CLI_SHOWUSAGE;
1448 ast_cli(a->fd,
"\nResetting stats for all taskprocessors\n\n");
1451 while ((tps = ao2_iterator_next(&iter))) {
1452 tps_reset_stats(tps);
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
A listener for taskprocessors.
#define AST_VECTOR_RW_INIT(vec, size)
Initialize a vector with a read/write lock.
#define AST_VECTOR_GET_INDEX(vec, value, cmp)
Get the 1st index from a vector that matches the given comparison.
const struct ast_taskprocessor_listener_callbacks * callbacks
#define AST_VECTOR_ADD_SORTED(vec, elem, cmp)
Add an element into a sorted vector.
int ast_sem_destroy(struct ast_sem *sem)
Destroy a semaphore.
Asterisk main include file. File version handling, generic pbx functions.
void(* shutdown)(struct ast_taskprocessor_listener *listener)
Indicates the taskprocessor wishes to die.
char name[0]
Friendly name of the taskprocessor. Subsystem is appended after the name's NULL terminator.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
unsigned int ast_taskprocessor_seq_num(void)
Get the next sequence number to create a human friendly taskprocessor name.
int ast_taskprocessor_execute(struct ast_taskprocessor *tps)
Pop a task off the taskprocessor and execute it.
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap)
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
The arg parameter is a search key, but is not an object.
void(* emptied)(struct ast_taskprocessor_listener *listener)
Indicates the task processor has become empty.
Time-related functions and macros.
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
static int tps_cmp_cb(void *obj, void *arg, int flags)
The astobj2 compare callback for taskprocessors.
int ast_sem_post(struct ast_sem *sem)
Increments the semaphore, unblocking a waiter if necessary.
descriptor for a cli entry.
void ast_taskprocessor_set_local(struct ast_taskprocessor *tps, void *local_data)
Sets the local data associated with a taskprocessor.
#define AST_TASKPROCESSOR_HIGH_WATER_LEVEL
static void * default_tps_processing_function(void *data)
Function that processes tasks in the taskprocessor.
struct ast_taskprocessor * tps
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
static int tps_hash_cb(const void *obj, const int flags)
The astobj2 hash callback for taskprocessors.
unsigned int high_water_alert
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
const char * ast_taskprocessor_name(struct ast_taskprocessor *tps)
Return the name of the taskprocessor singleton.
Assume that the ao2_container is already locked.
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
#define ast_strdup(str)
A wrapper for strdup()
struct ast_taskprocessor_listener * ast_taskprocessor_listener_alloc(const struct ast_taskprocessor_listener_callbacks *callbacks, void *user_data)
Allocate a taskprocessor listener.
static AST_VECTOR_RW(subsystem_alert_vector, struct subsystem_alert *)
CLI taskprocessor ping operation requires a ping condition lock.
unsigned int high_water_warned
long tps_queue_high
Taskprocessor high water alert trigger level.
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
static int task(void *data)
Queued task for baseline test.
int args
This gets set in ast_cli_register()
void ast_taskprocessor_name_append(char *buf, unsigned int size, const char *name)
Append the next sequence number to the given string, and copy into the buffer.
void * datap
The data pointer for the task execute() function.
long tps_queue_low
Taskprocessor low water clear alert level.
unsigned long _tasks_processed_count
This is the current number of tasks processed.
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
static ast_rwlock_t tps_alert_lock
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
char * subsystem
Anything before the first '/' in the name (if there is one)
int ast_taskprocessor_is_task(struct ast_taskprocessor *tps)
Am I the given taskprocessor's current task.
#define AST_VECTOR_RW_FREE(vec)
Deallocates this locked vector.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
int ast_sem_getvalue(struct ast_sem *sem, int *sval)
Gets the current value of the semaphore.
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
#define ast_malloc(len)
A wrapper for malloc()
#define ast_debug(level,...)
Log a DEBUG message.
long ast_taskprocessor_size(struct ast_taskprocessor *tps)
Return the current size of the taskprocessor queue.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
int ast_taskprocessor_alert_set_levels(struct ast_taskprocessor *tps, long low_water, long high_water)
Set the high and low alert water marks of the given taskprocessor queue.
int ast_sem_wait(struct ast_sem *sem)
Decrements the semaphore.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
union tps_task::@412 callback
The execute() task callback function pointer.
ast_tps_options
ast_tps_options for specification of taskprocessor options
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
Copy all object references in the src container into the dest container.
int ast_taskprocessor_push_local(struct ast_taskprocessor *tps, int(*task_exe)(struct ast_taskprocessor_local *local), void *datap) attribute_warn_unused_result
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
int ast_taskprocessor_unsuspend(struct ast_taskprocessor *tps)
Indicate the taskprocessor is unsuspended.
static unsigned int tps_alert_count
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
#define AST_VECTOR_RW_WRLOCK(vec)
Obtain write lock on vector.
#define ast_calloc(num, len)
A wrapper for calloc()
unsigned int ast_taskprocessor_get_subsystem_alert(const char *subsystem)
Get the current taskprocessor high water alert count by subsystem.
unsigned int ast_taskprocessor_alert_get(void)
Get the current taskprocessor high water alert count.
#define AST_TASKPROCESSOR_SHUTDOWN_MAX_WAIT
How many seconds to wait for running taskprocessors to finish on shutdown.
int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value)
Initialize a semaphore.
Prototypes for public functions only of internal interest,.
An API for managing task processing threads that can be shared across modules.
struct ast_taskprocessor * ast_taskprocessor_listener_get_tps(const struct ast_taskprocessor_listener *listener)
Get a reference to the listener's taskprocessor.
struct tps_task::@413 list
AST_LIST_ENTRY overhead.
tps_taskprocessor_stats maintain statistics for a taskprocessor.
tps_task structure is queued to a taskprocessor
return a reference to a taskprocessor ONLY if it already exists
The arg parameter is an object of the same type.
long tps_queue_size
Taskprocessor current queue size.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
int ast_taskprocessor_is_suspended(struct ast_taskprocessor *tps)
Get the task processor suspend status.
A ast_taskprocessor structure is a singleton by name.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
struct ast_taskprocessor * ast_taskprocessor_create_with_listener(const char *name, struct ast_taskprocessor_listener *listener)
Create a taskprocessor with a custom listener.
static int tps_ping_handler(void *datap)
CLI taskprocessor ping handler function.
#define ao2_unlink_flags(container, obj, flags)
Remove an object from a container.
void(* task_pushed)(struct ast_taskprocessor_listener *listener, int was_empty)
Indicates a task was pushed to the processor.
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a red-black tree container.
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Search option field mask.
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
void ast_taskprocessor_build_name(char *buf, unsigned int size, const char *format,...)
Build a taskprocessor name with a sequence number on the end.
#define AST_VECTOR_REMOVE(vec, idx, preserve_ordered)
Remove an element from a vector by index.
Asterisk module definitions.
unsigned long max_qsize
This is the maximum number of tasks queued at any one time.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
struct ast_taskprocessor * ast_taskprocessor_get(const char *name, enum ast_tps_options create)
Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary...
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
int(* start)(struct ast_taskprocessor_listener *listener)
The taskprocessor has started completely.
void * ast_taskprocessor_listener_get_user_data(const struct ast_taskprocessor_listener *listener)
Get the user data from the listener.
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
struct tps_taskprocessor_stats stats
Taskprocessor statistics.
int ast_taskprocessor_suspend(struct ast_taskprocessor *tps)
Indicate the taskprocessor is suspended.