Wed Jan 8 2020 09:50:21

Asterisk developer's documentation


taskprocessor.h File Reference

An API for managing task processing threads that can be shared across modules. More...

Go to the source code of this file.

Enumerations

enum  ast_tps_options { TPS_REF_DEFAULT = 0, TPS_REF_IF_EXISTS = (1 << 0) }
 ast_tps_options for specification of taskprocessor options More...
 

Functions

struct ast_taskprocessorast_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. More...
 
const char * ast_taskprocessor_name (struct ast_taskprocessor *tps)
 Return the name of the taskprocessor singleton. More...
 
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. More...
 
void * ast_taskprocessor_unreference (struct ast_taskprocessor *tps)
 Unreference the specified taskprocessor and its reference count will decrement. More...
 

Detailed Description

An API for managing task processing threads that can be shared across modules.

Author
Dwayne M. Hubbard dhubb.nosp@m.ard@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Note
A taskprocessor is a named singleton containing a processing thread and a task queue that serializes tasks pushed into it by [a] module(s) that reference the taskprocessor. A taskprocessor is created the first time its name is requested via the ast_taskprocessor_get() function and destroyed when the taskprocessor reference count reaches zero.

Modules that obtain a reference to a taskprocessor can queue tasks into the taskprocessor to be processed by the singleton processing thread when the task is popped off the front of the queue. A task is a wrapper around a task-handling function pointer and a data pointer. It is the responsibility of the task handling function to free memory allocated for the task data pointer. A task is pushed into a taskprocessor queue using the ast_taskprocessor_push(taskprocessor, taskhandler, taskdata) function and freed by the taskprocessor after the task handling function returns. A module releases its reference to a taskprocessor using the ast_taskprocessor_unreference() function which may result in the destruction of the taskprocessor if the taskprocessor's reference count reaches zero. Tasks waiting to be processed in the taskprocessor queue when the taskprocessor reference count reaches zero will be purged and released from the taskprocessor queue without being processed.

Definition in file taskprocessor.h.

Enumeration Type Documentation

ast_tps_options for specification of taskprocessor options

Specify whether a taskprocessor should be created via ast_taskprocessor_get() if the taskprocessor does not already exist. The default behavior is to create a taskprocessor if it does not already exist and provide its reference to the calling function. To only return a reference to a taskprocessor if and only if it exists, use the TPS_REF_IF_EXISTS option in ast_taskprocessor_get().

Enumerator
TPS_REF_DEFAULT 

return a reference to a taskprocessor, create one if it does not exist

TPS_REF_IF_EXISTS 

return a reference to a taskprocessor ONLY if it already exists

Definition at line 56 of file taskprocessor.h.

56  {
57  /*! \brief return a reference to a taskprocessor, create one if it does not exist */
58  TPS_REF_DEFAULT = 0,
59  /*! \brief return a reference to a taskprocessor ONLY if it already exists */
60  TPS_REF_IF_EXISTS = (1 << 0),
61 };
return a reference to a taskprocessor, create one if it does not exist
Definition: taskprocessor.h:58
return a reference to a taskprocessor ONLY if it already exists
Definition: taskprocessor.h:60

Function Documentation

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.

The default behavior of instantiating a taskprocessor if one does not already exist can be disabled by specifying the TPS_REF_IF_EXISTS ast_tps_options as the second argument to ast_taskprocessor_get().

Parameters
nameThe name of the taskprocessor
createUse 0 by default or specify TPS_REF_IF_EXISTS to return NULL if the taskprocessor does not already exist return A pointer to a reference counted taskprocessor under normal conditions, or NULL if the TPS_REF_IF_EXISTS reference type is specified and the taskprocessor does not exist
Since
1.6.1

Definition at line 424 of file taskprocessor.c.

References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_calloc, ast_cond_init, ast_log(), ast_mutex_init, ast_pthread_create, AST_PTHREADT_NULL, ast_strdup, ast_strlen_zero(), LOG_ERROR, LOG_WARNING, name, ast_taskprocessor::name, OBJ_POINTER, ast_taskprocessor::poll_cond, ast_taskprocessor::poll_thread, ast_taskprocessor::poll_thread_run, ast_taskprocessor::stats, ast_taskprocessor::taskprocessor_lock, tps_processing_function(), TPS_REF_IF_EXISTS, tps_singletons, and tps_taskprocessor_destroy().

Referenced by ast_cc_init(), ast_event_init(), cli_tps_ping(), load_module(), load_objects(), and load_pbx().

425 {
426  struct ast_taskprocessor *p, tmp_tps = {
427  .name = name,
428  };
429 
430  if (ast_strlen_zero(name)) {
431  ast_log(LOG_ERROR, "requesting a nameless taskprocessor!!!\n");
432  return NULL;
433  }
435  p = ao2_find(tps_singletons, &tmp_tps, OBJ_POINTER);
436  if (p) {
438  return p;
439  }
440  if (create & TPS_REF_IF_EXISTS) {
441  /* calling function does not want a new taskprocessor to be created if it doesn't already exist */
443  return NULL;
444  }
445  /* create a new taskprocessor */
446  if (!(p = ao2_alloc(sizeof(*p), tps_taskprocessor_destroy))) {
448  ast_log(LOG_WARNING, "failed to create taskprocessor '%s'\n", name);
449  return NULL;
450  }
451 
452  ast_cond_init(&p->poll_cond, NULL);
454 
455  if (!(p->stats = ast_calloc(1, sizeof(*p->stats)))) {
457  ast_log(LOG_WARNING, "failed to create taskprocessor stats for '%s'\n", name);
458  ao2_ref(p, -1);
459  return NULL;
460  }
461  if (!(p->name = ast_strdup(name))) {
463  ao2_ref(p, -1);
464  return NULL;
465  }
466  p->poll_thread_run = 1;
468  if (ast_pthread_create(&p->poll_thread, NULL, tps_processing_function, p) < 0) {
470  ast_log(LOG_ERROR, "Taskprocessor '%s' failed to create the processing thread.\n", p->name);
471  ao2_ref(p, -1);
472  return NULL;
473  }
474  if (!(ao2_link(tps_singletons, p))) {
476  ast_log(LOG_ERROR, "Failed to add taskprocessor '%s' to container\n", p->name);
477  ao2_ref(p, -1);
478  return NULL;
479  }
481  return p;
482 }
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
const char * name
Friendly name of the taskprocessor.
Definition: taskprocessor.c:69
#define ast_strdup(a)
Definition: astmm.h:109
#define LOG_WARNING
Definition: logger.h:144
ast_cond_t poll_cond
Thread poll condition.
Definition: taskprocessor.c:71
static struct ao2_container * tps_singletons
tps_singletons is the astobj2 container for taskprocessor singletons
Definition: taskprocessor.c:89
#define ast_cond_init(cond, attr)
Definition: lock.h:167
#define ao2_unlock(a)
Definition: astobj2.h:497
static void * tps_processing_function(void *data)
The task processing function executed by a taskprocessor.
ast_mutex_t taskprocessor_lock
Taskprocessor lock.
Definition: taskprocessor.c:75
static void tps_taskprocessor_destroy(void *tps)
Destroy the taskprocessor when its refcount reaches zero.
#define AST_PTHREADT_NULL
Definition: lock.h:65
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
unsigned char poll_thread_run
Taskprocesor thread run flag.
Definition: taskprocessor.c:77
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
static const char name[]
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:418
pthread_t poll_thread
Taskprocessor thread.
Definition: taskprocessor.c:73
return a reference to a taskprocessor ONLY if it already exists
Definition: taskprocessor.h:60
A ast_taskprocessor structure is a singleton by name.
Definition: taskprocessor.c:67
#define ast_calloc(a, b)
Definition: astmm.h:82
#define ast_mutex_init(pmutex)
Definition: lock.h:152
struct tps_taskprocessor_stats * stats
Taskprocessor statistics.
Definition: taskprocessor.c:79
const char* ast_taskprocessor_name ( struct ast_taskprocessor tps)

Return the name of the taskprocessor singleton.

Since
1.6.1

Definition at line 412 of file taskprocessor.c.

References ast_log(), LOG_ERROR, and ast_taskprocessor::name.

413 {
414  if (!tps) {
415  ast_log(LOG_ERROR, "no taskprocessor specified!\n");
416  return NULL;
417  }
418  return tps->name;
419 }
const char * name
Friendly name of the taskprocessor.
Definition: taskprocessor.c:69
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_taskprocessor_push ( struct ast_taskprocessor tps,
int(*)(void *datap)  task_exe,
void *  datap 
)

Push a task into the specified taskprocessor queue and signal the taskprocessor thread.

Parameters
tpsThe taskprocessor structure
task_exeThe task handling function to push into the taskprocessor queue
datapThe data to be used by the task handling function
Return values
0success
-1failure
Since
1.6.1

Definition at line 499 of file taskprocessor.c.

References ast_cond_signal, AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock, ast_mutex_unlock, LOG_ERROR, ast_taskprocessor::name, ast_taskprocessor::poll_cond, ast_taskprocessor::taskprocessor_lock, ast_taskprocessor::tps_queue, ast_taskprocessor::tps_queue_size, and tps_task_alloc().

Referenced by ast_cc_agent_status_response(), ast_cc_monitor_failed(), ast_cc_monitor_party_b_free(), ast_cc_monitor_status_request(), ast_cc_monitor_stop_ringing(), ast_event_queue(), cc_request_state_change(), cli_tps_ping(), device_state_cb(), generic_agent_devstate_cb(), generic_monitor_devstate_cb(), handle_cc_status(), iax2_transmit(), mwi_sub_event_cb(), and mwi_unsub_event_cb().

500 {
501  struct tps_task *t;
502 
503  if (!tps || !task_exe) {
504  ast_log(LOG_ERROR, "%s is missing!!\n", (tps) ? "task callback" : "taskprocessor");
505  return -1;
506  }
507  if (!(t = tps_task_alloc(task_exe, datap))) {
508  ast_log(LOG_ERROR, "failed to allocate task! Can't push to '%s'\n", tps->name);
509  return -1;
510  }
513  tps->tps_queue_size++;
514  ast_cond_signal(&tps->poll_cond);
516  return 0;
517 }
const char * name
Friendly name of the taskprocessor.
Definition: taskprocessor.c:69
ast_cond_t poll_cond
Thread poll condition.
Definition: taskprocessor.c:71
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_cond_signal(cond)
Definition: lock.h:169
void * datap
The data pointer for the task execute() function.
Definition: taskprocessor.c:53
ast_mutex_t taskprocessor_lock
Taskprocessor lock.
Definition: taskprocessor.c:75
#define LOG_ERROR
Definition: logger.h:155
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct tps_task::@303 list
AST_LIST_ENTRY overhead.
struct ast_taskprocessor::tps_queue tps_queue
tps_task structure is queued to a taskprocessor
Definition: taskprocessor.c:49
long tps_queue_size
Taskprocessor current queue size.
Definition: taskprocessor.c:81
static struct tps_task * tps_task_alloc(int(*task_exe)(void *datap), void *datap)
#define ast_mutex_unlock(a)
Definition: lock.h:156
void* ast_taskprocessor_unreference ( struct ast_taskprocessor tps)

Unreference the specified taskprocessor and its reference count will decrement.

Taskprocessors use astobj2 and will unlink from the taskprocessor singleton container and destroy themself when the taskprocessor reference count reaches zero.

Parameters
tpstaskprocessor to unreference
Returns
NULL
Since
1.6.1

Definition at line 485 of file taskprocessor.c.

References ao2_link, ao2_lock, ao2_ref, ao2_unlink, ao2_unlock, and tps_singletons.

Referenced by __unload_module(), cc_shutdown(), event_shutdown(), unload_module(), and unload_pbx().

486 {
487  if (tps) {
490  if (ao2_ref(tps, -1) > 1) {
491  ao2_link(tps_singletons, tps);
492  }
494  }
495  return NULL;
496 }
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
static struct ao2_container * tps_singletons
tps_singletons is the astobj2 container for taskprocessor singletons
Definition: taskprocessor.c:89
#define ao2_unlock(a)
Definition: astobj2.h:497
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
#define ao2_unlink(arg1, arg2)
Definition: astobj2.h:817