stasis: Add function to delete topic from pool

There's been a long standing leak when using topic pools.  The
topics in the pool get cleaned up when the last pool reference is
released but you can't remove a topic specifically.  If you reloaded
app_voicemail for instance, and mailboxes went away, their topics
were left in the pool.

* Added stasis_topic_pool_delete_topic() so modules can clean up
  topics from pools.
* Registered the topic pool containers so it can be examined from
  the CLI when AO2_DEBUG is enabled.  They'll be named
  "<topic_pool_name>-pool".

Change-Id: Ib7957951ee5c9b9b4482af7b9b4349112d62bc25
This commit is contained in:
George Joseph 2018-09-20 08:41:15 -06:00
parent 84b60aeb70
commit 1a9c69d729
2 changed files with 48 additions and 0 deletions

View File

@ -752,6 +752,18 @@ struct stasis_topic_pool *stasis_topic_pool_create(struct stasis_topic *pooled_t
*/
struct stasis_topic *stasis_topic_pool_get_topic(struct stasis_topic_pool *pool, const char *topic_name);
/*!
* \brief Delete a topic from the topic pool
*
* \param pool Pool from which to delete the topic
* \param topic_name Name of the topic to delete
*
* \since 13.24
* \since 15.6
* \since 16.1
*/
void stasis_topic_pool_delete_topic(struct stasis_topic_pool *pool, const char *topic_name);
/*!
* \brief Check if a topic exists in a pool
* \param pool Pool to check

View File

@ -1079,6 +1079,15 @@ static void topic_pool_dtor(void *obj)
{
struct stasis_topic_pool *pool = obj;
#ifdef AO2_DEBUG
{
char *container_name =
ast_alloca(strlen(stasis_topic_name(pool->pool_topic)) + strlen("-pool") + 1);
sprintf(container_name, "%s-pool", stasis_topic_name(pool->pool_topic));
ao2_container_unregister(container_name);
}
#endif
ao2_cleanup(pool->pool_container);
pool->pool_container = NULL;
ao2_cleanup(pool->pool_topic);
@ -1143,6 +1152,18 @@ static int topic_pool_entry_cmp(void *obj, void *arg, int flags)
return CMP_MATCH;
}
#ifdef AO2_DEBUG
static void topic_pool_prnt_obj(void *v_obj, void *where, ao2_prnt_fn *prnt)
{
struct topic_pool_entry *entry = v_obj;
if (!entry) {
return;
}
prnt(where, "%s", stasis_topic_name(entry->topic));
}
#endif
struct stasis_topic_pool *stasis_topic_pool_create(struct stasis_topic *pooled_topic)
{
struct stasis_topic_pool *pool;
@ -1158,12 +1179,27 @@ struct stasis_topic_pool *stasis_topic_pool_create(struct stasis_topic *pooled_t
ao2_cleanup(pool);
return NULL;
}
#ifdef AO2_DEBUG
{
char *container_name =
ast_alloca(strlen(stasis_topic_name(pooled_topic)) + strlen("-pool") + 1);
sprintf(container_name, "%s-pool", stasis_topic_name(pooled_topic));
ao2_container_register(container_name, pool->pool_container, topic_pool_prnt_obj);
}
#endif
ao2_ref(pooled_topic, +1);
pool->pool_topic = pooled_topic;
return pool;
}
void stasis_topic_pool_delete_topic(struct stasis_topic_pool *pool, const char *topic_name)
{
ao2_find(pool->pool_container, topic_name, OBJ_SEARCH_KEY | OBJ_NODATA | OBJ_UNLINK);
}
struct stasis_topic *stasis_topic_pool_get_topic(struct stasis_topic_pool *pool, const char *topic_name)
{
RAII_VAR(struct topic_pool_entry *, topic_pool_entry, NULL, ao2_cleanup);