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_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. | |
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. |
An API for managing task processing threads that can be shared across modules.
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.
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().
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 };
struct ast_taskprocessor* ast_taskprocessor_get | ( | const char * | name, | |
enum ast_tps_options | create | |||
) | [read] |
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().
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 |
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, 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().
00425 { 00426 struct ast_taskprocessor *p, tmp_tps = { 00427 .name = name, 00428 }; 00429 00430 if (ast_strlen_zero(name)) { 00431 ast_log(LOG_ERROR, "requesting a nameless taskprocessor!!!\n"); 00432 return NULL; 00433 } 00434 ao2_lock(tps_singletons); 00435 p = ao2_find(tps_singletons, &tmp_tps, OBJ_POINTER); 00436 if (p) { 00437 ao2_unlock(tps_singletons); 00438 return p; 00439 } 00440 if (create & TPS_REF_IF_EXISTS) { 00441 /* calling function does not want a new taskprocessor to be created if it doesn't already exist */ 00442 ao2_unlock(tps_singletons); 00443 return NULL; 00444 } 00445 /* create a new taskprocessor */ 00446 if (!(p = ao2_alloc(sizeof(*p), tps_taskprocessor_destroy))) { 00447 ao2_unlock(tps_singletons); 00448 ast_log(LOG_WARNING, "failed to create taskprocessor '%s'\n", name); 00449 return NULL; 00450 } 00451 00452 ast_cond_init(&p->poll_cond, NULL); 00453 ast_mutex_init(&p->taskprocessor_lock); 00454 00455 if (!(p->stats = ast_calloc(1, sizeof(*p->stats)))) { 00456 ao2_unlock(tps_singletons); 00457 ast_log(LOG_WARNING, "failed to create taskprocessor stats for '%s'\n", name); 00458 ao2_ref(p, -1); 00459 return NULL; 00460 } 00461 if (!(p->name = ast_strdup(name))) { 00462 ao2_unlock(tps_singletons); 00463 ao2_ref(p, -1); 00464 return NULL; 00465 } 00466 p->poll_thread_run = 1; 00467 p->poll_thread = AST_PTHREADT_NULL; 00468 if (ast_pthread_create(&p->poll_thread, NULL, tps_processing_function, p) < 0) { 00469 ao2_unlock(tps_singletons); 00470 ast_log(LOG_ERROR, "Taskprocessor '%s' failed to create the processing thread.\n", p->name); 00471 ao2_ref(p, -1); 00472 return NULL; 00473 } 00474 if (!(ao2_link(tps_singletons, p))) { 00475 ao2_unlock(tps_singletons); 00476 ast_log(LOG_ERROR, "Failed to add taskprocessor '%s' to container\n", p->name); 00477 ao2_ref(p, -1); 00478 return NULL; 00479 } 00480 ao2_unlock(tps_singletons); 00481 return p; 00482 }
const char* ast_taskprocessor_name | ( | struct ast_taskprocessor * | tps | ) |
Return the name of the taskprocessor singleton.
Definition at line 412 of file taskprocessor.c.
References ast_log(), LOG_ERROR, and ast_taskprocessor::name.
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.
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 |
0 | success | |
-1 | failure |
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().
00500 { 00501 struct tps_task *t; 00502 00503 if (!tps || !task_exe) { 00504 ast_log(LOG_ERROR, "%s is missing!!\n", (tps) ? "task callback" : "taskprocessor"); 00505 return -1; 00506 } 00507 if (!(t = tps_task_alloc(task_exe, datap))) { 00508 ast_log(LOG_ERROR, "failed to allocate task! Can't push to '%s'\n", tps->name); 00509 return -1; 00510 } 00511 ast_mutex_lock(&tps->taskprocessor_lock); 00512 AST_LIST_INSERT_TAIL(&tps->tps_queue, t, list); 00513 tps->tps_queue_size++; 00514 ast_cond_signal(&tps->poll_cond); 00515 ast_mutex_unlock(&tps->taskprocessor_lock); 00516 return 0; 00517 }
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.
tps | taskprocessor to unreference |
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().
00486 { 00487 if (tps) { 00488 ao2_lock(tps_singletons); 00489 ao2_unlink(tps_singletons, tps); 00490 if (ao2_ref(tps, -1) > 1) { 00491 ao2_link(tps_singletons, tps); 00492 } 00493 ao2_unlock(tps_singletons); 00494 } 00495 return NULL; 00496 }