Address further review feedback from David Lee.

* Clarify some documentation
* Change copyright date of taskprocessor files
* Address potential issue of creating taskprocessor with listener if
  taskprocessor with that name exists already



git-svn-id: https://origsvn.digium.com/svn/asterisk/team/mmichelson/threadpool@379124 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Mark Michelson
2013-01-15 20:15:00 +00:00
parent c6bc51ef28
commit 03e89247de
4 changed files with 66 additions and 53 deletions

View File

@@ -1,7 +1,7 @@
/* /*
* Asterisk -- An open source telephony toolkit. * Asterisk -- An open source telephony toolkit.
* *
* Copyright (C) 2007-2008, Digium, Inc. * Copyright (C) 2007-2013, Digium, Inc.
* *
* Dwayne M. Hubbard <dhubbard@digium.com> * Dwayne M. Hubbard <dhubbard@digium.com>
* *
@@ -22,7 +22,7 @@
* *
* \author Dwayne M. Hubbard <dhubbard@digium.com> * \author Dwayne M. Hubbard <dhubbard@digium.com>
* *
* \note A taskprocessor is a named singleton containing a task queue that * \note A taskprocessor is a named object containing a task queue that
* serializes tasks pushed into it by [a] module(s) that reference the taskprocessor. * 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 * A taskprocessor is created the first time its name is requested via the
* ast_taskprocessor_get() function or the ast_taskprocessor_create_with_listener() * ast_taskprocessor_get() function or the ast_taskprocessor_create_with_listener()

View File

@@ -135,7 +135,7 @@ struct ast_threadpool_listener *ast_threadpool_listener_alloc(
* in and will be automatically acted upon by threads within the pool. * in and will be automatically acted upon by threads within the pool.
* *
* \param name The name for the threadpool * \param name The name for the threadpool
* \param listener The listener the threadpool will notify of changes * \param listener The listener the threadpool will notify of changes. Can be NULL.
* \param options The behavioral options for this threadpool * \param options The behavioral options for this threadpool
* \retval NULL Failed to create the threadpool * \retval NULL Failed to create the threadpool
* \retval non-NULL The newly-created threadpool * \retval non-NULL The newly-created threadpool

View File

@@ -1,7 +1,7 @@
/* /*
* Asterisk -- An open source telephony toolkit. * Asterisk -- An open source telephony toolkit.
* *
* Copyright (C) 2007-2008, Digium, Inc. * Copyright (C) 2007-2013, Digium, Inc.
* *
* Dwayne M. Hubbard <dhubbard@digium.com> * Dwayne M. Hubbard <dhubbard@digium.com>
* *
@@ -487,56 +487,10 @@ static void *default_listener_pvt_alloc(void)
return pvt; return pvt;
} }
/* Provide a reference to a taskprocessor. Create the taskprocessor if necessary, but don't static struct ast_taskprocessor *__allocate_taskprocessor(const char *name, struct ast_taskprocessor_listener *listener)
* create the taskprocessor if we were told via ast_tps_options to return a reference only
* if it already exists */
struct ast_taskprocessor *ast_taskprocessor_get(const char *name, enum ast_tps_options create)
{
struct ast_taskprocessor *p;
struct ast_taskprocessor_listener *listener;
struct default_taskprocessor_listener_pvt *pvt;
if (ast_strlen_zero(name)) {
ast_log(LOG_ERROR, "requesting a nameless taskprocessor!!!\n");
return NULL;
}
p = ao2_find(tps_singletons, name, OBJ_KEY);
if (p) {
return p;
}
if (create & TPS_REF_IF_EXISTS) {
/* calling function does not want a new taskprocessor to be created if it doesn't already exist */
return NULL;
}
/* Create a new taskprocessor. Start by creating a default listener */
pvt = default_listener_pvt_alloc();
if (!pvt) {
return NULL;
}
listener = ast_taskprocessor_listener_alloc(&default_listener_callbacks, pvt);
if (!listener) {
default_listener_pvt_destroy(pvt);
return NULL;
}
p = ast_taskprocessor_create_with_listener(name, listener);
if (!p) {
default_listener_pvt_destroy(pvt);
ao2_ref(listener, -1);
return NULL;
}
/* Unref listener here since the taskprocessor has gained a reference to the listener */
ao2_ref(listener, -1);
return p;
}
struct ast_taskprocessor *ast_taskprocessor_create_with_listener(const char *name, struct ast_taskprocessor_listener *listener)
{ {
RAII_VAR(struct ast_taskprocessor *, p, RAII_VAR(struct ast_taskprocessor *, p,
ao2_alloc(sizeof(*p), tps_taskprocessor_destroy), ao2_alloc(sizeof(*p), tps_taskprocessor_destroy), ao2_cleanup);
ao2_cleanup);
if (!p) { if (!p) {
ast_log(LOG_WARNING, "failed to create taskprocessor '%s'\n", name); ast_log(LOG_WARNING, "failed to create taskprocessor '%s'\n", name);
@@ -574,6 +528,63 @@ struct ast_taskprocessor *ast_taskprocessor_create_with_listener(const char *nam
*/ */
ao2_ref(p, +1); ao2_ref(p, +1);
return p; return p;
}
/* Provide a reference to a taskprocessor. Create the taskprocessor if necessary, but don't
* create the taskprocessor if we were told via ast_tps_options to return a reference only
* if it already exists */
struct ast_taskprocessor *ast_taskprocessor_get(const char *name, enum ast_tps_options create)
{
struct ast_taskprocessor *p;
struct ast_taskprocessor_listener *listener;
struct default_taskprocessor_listener_pvt *pvt;
if (ast_strlen_zero(name)) {
ast_log(LOG_ERROR, "requesting a nameless taskprocessor!!!\n");
return NULL;
}
p = ao2_find(tps_singletons, name, OBJ_KEY);
if (p) {
return p;
}
if (create & TPS_REF_IF_EXISTS) {
/* calling function does not want a new taskprocessor to be created if it doesn't already exist */
return NULL;
}
/* Create a new taskprocessor. Start by creating a default listener */
pvt = default_listener_pvt_alloc();
if (!pvt) {
return NULL;
}
listener = ast_taskprocessor_listener_alloc(&default_listener_callbacks, pvt);
if (!listener) {
default_listener_pvt_destroy(pvt);
return NULL;
}
p = __allocate_taskprocessor(name, listener);
if (!p) {
default_listener_pvt_destroy(pvt);
ao2_ref(listener, -1);
return NULL;
}
/* Unref listener here since the taskprocessor has gained a reference to the listener */
ao2_ref(listener, -1);
return p;
}
struct ast_taskprocessor *ast_taskprocessor_create_with_listener(const char *name, struct ast_taskprocessor_listener *listener)
{
struct ast_taskprocessor *p = ao2_find(tps_singletons, name, OBJ_KEY);
if (p) {
ast_taskprocessor_unreference(p);
return NULL;
}
return __allocate_taskprocessor(name, listener);
} }
/* decrement the taskprocessor reference count and unlink from the container if necessary */ /* decrement the taskprocessor reference count and unlink from the container if necessary */

View File

@@ -613,7 +613,9 @@ static void threadpool_tps_shutdown(struct ast_taskprocessor_listener *listener)
{ {
struct ast_threadpool *pool = listener->user_data; struct ast_threadpool *pool = listener->user_data;
pool->listener->callbacks->shutdown(pool->listener); if (pool->listener && pool->listener->callbacks->shutdown) {
pool->listener->callbacks->shutdown(pool->listener);
}
ao2_cleanup(pool->active_threads); ao2_cleanup(pool->active_threads);
ao2_cleanup(pool->idle_threads); ao2_cleanup(pool->idle_threads);
ao2_cleanup(pool->zombie_threads); ao2_cleanup(pool->zombie_threads);