Sat Mar 10 01:55:49 2012

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

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


Detailed Description

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

Author:
Dwayne M. Hubbard <dhubbard@digium.com>
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

enum ast_tps_options

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.

00056                      {
00057    /*! \brief return a reference to a taskprocessor, create one if it does not exist */
00058    TPS_REF_DEFAULT = 0,
00059    /*! \brief return a reference to a taskprocessor ONLY if it already exists */
00060    TPS_REF_IF_EXISTS = (1 << 0),
00061 };


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:
name The name of the taskprocessor
create Use 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 409 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, ast_taskprocessor::name, OBJ_POINTER, 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().

00410 {
00411    struct ast_taskprocessor *p, tmp_tps = {
00412       .name = name,
00413    };
00414       
00415    if (ast_strlen_zero(name)) {
00416       ast_log(LOG_ERROR, "requesting a nameless taskprocessor!!!\n");
00417       return NULL;
00418    }
00419    ao2_lock(tps_singletons);
00420    p = ao2_find(tps_singletons, &tmp_tps, OBJ_POINTER);
00421    if (p) {
00422       ao2_unlock(tps_singletons);
00423       return p;
00424    }
00425    if (create & TPS_REF_IF_EXISTS) {
00426       /* calling function does not want a new taskprocessor to be created if it doesn't already exist */
00427       ao2_unlock(tps_singletons);
00428       return NULL;
00429    }
00430    /* create a new taskprocessor */
00431    if (!(p = ao2_alloc(sizeof(*p), tps_taskprocessor_destroy))) {
00432       ao2_unlock(tps_singletons);
00433       ast_log(LOG_WARNING, "failed to create taskprocessor '%s'\n", name);
00434       return NULL;
00435    }
00436 
00437    ast_cond_init(&p->poll_cond, NULL);
00438    ast_mutex_init(&p->taskprocessor_lock);
00439 
00440    if (!(p->stats = ast_calloc(1, sizeof(*p->stats)))) {
00441       ao2_unlock(tps_singletons);
00442       ast_log(LOG_WARNING, "failed to create taskprocessor stats for '%s'\n", name);
00443       ao2_ref(p, -1);
00444       return NULL;
00445    }
00446    if (!(p->name = ast_strdup(name))) {
00447       ao2_unlock(tps_singletons);
00448       ao2_ref(p, -1);
00449       return NULL;
00450    }
00451    p->poll_thread_run = 1;
00452    p->poll_thread = AST_PTHREADT_NULL;
00453    if (ast_pthread_create(&p->poll_thread, NULL, tps_processing_function, p) < 0) {
00454       ao2_unlock(tps_singletons);
00455       ast_log(LOG_ERROR, "Taskprocessor '%s' failed to create the processing thread.\n", p->name);
00456       ao2_ref(p, -1);
00457       return NULL;
00458    }
00459    if (!(ao2_link(tps_singletons, p))) {
00460       ao2_unlock(tps_singletons);
00461       ast_log(LOG_ERROR, "Failed to add taskprocessor '%s' to container\n", p->name);
00462       ao2_ref(p, -1);
00463       return NULL;
00464    }
00465    ao2_unlock(tps_singletons);
00466    return p;
00467 }

const char* ast_taskprocessor_name ( struct ast_taskprocessor tps  ) 

Return the name of the taskprocessor singleton.

Since:
1.6.1

Definition at line 397 of file taskprocessor.c.

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

00398 {
00399    if (!tps) {
00400       ast_log(LOG_ERROR, "no taskprocessor specified!\n");
00401       return NULL;
00402    }
00403    return tps->name;
00404 }

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:
tps The taskprocessor structure
task_exe The task handling function to push into the taskprocessor queue
datap The data to be used by the task handling function
Return values:
0 success
-1 failure
Since:
1.6.1

Definition at line 484 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().

00485 {
00486    struct tps_task *t;
00487 
00488    if (!tps || !task_exe) {
00489       ast_log(LOG_ERROR, "%s is missing!!\n", (tps) ? "task callback" : "taskprocessor");
00490       return -1;
00491    }
00492    if (!(t = tps_task_alloc(task_exe, datap))) {
00493       ast_log(LOG_ERROR, "failed to allocate task!  Can't push to '%s'\n", tps->name);
00494       return -1;
00495    }
00496    ast_mutex_lock(&tps->taskprocessor_lock);
00497    AST_LIST_INSERT_TAIL(&tps->tps_queue, t, list);
00498    tps->tps_queue_size++;
00499    ast_cond_signal(&tps->poll_cond);
00500    ast_mutex_unlock(&tps->taskprocessor_lock);
00501    return 0;
00502 }

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:
tps taskprocessor to unreference
Returns:
NULL
Since:
1.6.1

Definition at line 470 of file taskprocessor.c.

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

Referenced by __unload_module(), and unload_module().

00471 {
00472    if (tps) {
00473       ao2_lock(tps_singletons);
00474       ao2_unlink(tps_singletons, tps);
00475       if (ao2_ref(tps, -1) > 1) {
00476          ao2_link(tps_singletons, tps);
00477       }
00478       ao2_unlock(tps_singletons);
00479    }
00480    return NULL;
00481 }


Generated on Sat Mar 10 01:55:49 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7