[asterisk-commits] dlee: branch dlee/ASTERISK-21970 r394440 - in /team/dlee/ASTERISK-21970/res: ...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jul 16 10:23:27 CDT 2013
Author: dlee
Date: Tue Jul 16 10:23:25 2013
New Revision: 394440
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=394440
Log:
Clean up old applications
Modified:
team/dlee/ASTERISK-21970/res/res_stasis.c
team/dlee/ASTERISK-21970/res/stasis/app.c
team/dlee/ASTERISK-21970/res/stasis/app.h
Modified: team/dlee/ASTERISK-21970/res/res_stasis.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-21970/res/res_stasis.c?view=diff&rev=394440&r1=394439&r2=394440
==============================================================================
--- team/dlee/ASTERISK-21970/res/res_stasis.c (original)
+++ team/dlee/ASTERISK-21970/res/res_stasis.c Tue Jul 16 10:23:25 2013
@@ -565,7 +565,7 @@
res = app_send_start_msg(app, chan, argc, argv);
if (res != 0) {
ast_log(LOG_ERROR,
- "Error sending start message to %s\n", app_name);
+ "Error sending start message to '%s'\n", app_name);
return res;
}
@@ -652,6 +652,29 @@
return 0;
}
+static int cleanup_cb(void *obj, void *arg, int flags)
+{
+ struct app *app = obj;
+
+ if (!app_is_finished(app)) {
+ return 0;
+ }
+
+ ast_verb(1, "Cleaning up application '%s'\n", app_name(app));
+
+ return CMP_MATCH;
+
+}
+
+/*!
+ * \brief Clean up any old apps that we don't need any more.
+ */
+static void cleanup(void)
+{
+ ao2_callback(apps_registry, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK,
+ cleanup_cb, NULL);
+}
+
int stasis_app_register(const char *app_name, stasis_app_cb handler, void *data)
{
RAII_VAR(struct app *, app, NULL, ao2_cleanup);
@@ -661,15 +684,6 @@
app = ao2_find(apps_registry, app_name, OBJ_KEY | OBJ_NOLOCK);
if (app) {
- RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref);
-
- msg = ast_json_pack("{s: s, s: s}",
- "type", "ApplicationReplaced",
- "application", app_name);
- if (msg) {
- app_send(app, msg);
- }
-
app_update(app, handler, data);
} else {
app = app_create(app_name, handler, data);
@@ -699,6 +713,11 @@
}
app_deactivate(app);
+
+ /* We lazily clean up the apps_registry, because it's good enough to
+ * prevent memory leaks, and we're lazy.
+ */
+ cleanup();
}
void stasis_app_ref(void)
Modified: team/dlee/ASTERISK-21970/res/stasis/app.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-21970/res/stasis/app.c?view=diff&rev=394440&r1=394439&r2=394440
==============================================================================
--- team/dlee/ASTERISK-21970/res/stasis/app.c (original)
+++ team/dlee/ASTERISK-21970/res/stasis/app.c Tue Jul 16 10:23:25 2013
@@ -77,6 +77,8 @@
ast_assert(name != NULL);
ast_assert(handler != NULL);
+ ast_verb(1, "Creating Stasis app '%s'\n", name);
+
size = sizeof(*app) + strlen(name) + 1;
app = ao2_alloc_options(size, app_dtor, AO2_ALLOC_OPT_LOCK_MUTEX);
@@ -105,9 +107,16 @@
int app_add_channel(struct app *app, const struct ast_channel *chan)
{
+ SCOPED_AO2LOCK(lock, app);
const char *uniqueid;
+
+ ast_assert(app != NULL);
ast_assert(chan != NULL);
- ast_assert(app != NULL);
+
+ /* Don't accept new channels in an inactive application */
+ if (!app->handler) {
+ return -1;
+ }
uniqueid = ast_channel_uniqueid(chan);
return ast_str_container_add(app->channels, uniqueid) ? -1 : 0;
@@ -115,24 +124,35 @@
void app_remove_channel(struct app* app, const struct ast_channel *chan)
{
+ SCOPED_AO2LOCK(lock, app);
+
+ ast_assert(app != NULL);
ast_assert(chan != NULL);
- ast_assert(app != NULL);
ao2_find(app->channels, ast_channel_uniqueid(chan), OBJ_KEY | OBJ_NODATA | OBJ_UNLINK);
}
int app_add_bridge(struct app *app, const char *uniqueid)
{
+ SCOPED_AO2LOCK(lock, app);
+
+ ast_assert(app != NULL);
ast_assert(uniqueid != NULL);
- ast_assert(app != NULL);
+
+ /* Don't accept new bridges in an inactive application */
+ if (!app->handler) {
+ return -1;
+ }
return ast_str_container_add(app->bridges, uniqueid) ? -1 : 0;
}
void app_remove_bridge(struct app* app, const char *uniqueid)
{
+ SCOPED_AO2LOCK(lock, app);
+
+ ast_assert(app != NULL);
ast_assert(uniqueid != NULL);
- ast_assert(app != NULL);
ao2_find(app->bridges, uniqueid, OBJ_KEY | OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE);
}
@@ -151,22 +171,26 @@
{
SCOPED_AO2LOCK(lock, app);
handler = app->handler;
- ao2_ref(app->data, +1);
- data = app->data;
+ if (app->data) {
+ ao2_ref(app->data, +1);
+ data = app->data;
+ }
/* Name is immutable; no need to copy */
}
if (!handler) {
- ast_log(LOG_WARNING,
- "Inactive application %s missed message\n", app->name);
+ ast_verb(3,
+ "Inactive Stasis app '%s' missed message\n", app->name);
return;
}
+
handler(data, app->name, message);
}
void app_deactivate(struct app *app)
{
SCOPED_AO2LOCK(lock, app);
+ ast_verb(1, "Deactivating Stasis app '%s'\n", app->name);
app->handler = NULL;
ao2_cleanup(app->data);
app->data = NULL;
@@ -178,9 +202,33 @@
return app->handler != NULL;
}
+int app_is_finished(struct app *app)
+{
+ SCOPED_AO2LOCK(lock, app);
+
+ return app->handler == NULL &&
+ ao2_container_count(app->channels) == 0;
+}
+
void app_update(struct app *app, stasis_app_cb handler, void *data)
{
SCOPED_AO2LOCK(lock, app);
+
+ if (app->handler) {
+ RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref);
+
+ ast_verb(1, "Replacing Stasis app '%s'\n", app->name);
+
+ msg = ast_json_pack("{s: s, s: s}",
+ "type", "ApplicationReplaced",
+ "application", app_name);
+ if (msg) {
+ app_send(app, msg);
+ }
+ } else {
+ ast_verb(1, "Activating Stasis app '%s'\n", app->name);
+ }
+
app->handler = handler;
ao2_cleanup(app->data);
Modified: team/dlee/ASTERISK-21970/res/stasis/app.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-21970/res/stasis/app.h?view=diff&rev=394440&r1=394439&r2=394440
==============================================================================
--- team/dlee/ASTERISK-21970/res/stasis/app.h (original)
+++ team/dlee/ASTERISK-21970/res/stasis/app.h Tue Jul 16 10:23:25 2013
@@ -65,6 +65,15 @@
* \return False (zero) if app has been deactivated.
*/
int app_is_active(struct app *app);
+
+/*!
+ * \brief Checks whether a deactivated app has no channels.
+ *
+ * \param app Application to check.
+ * \param True (non-zero) if app is deactivated, and has no associated channels.
+ * \param False (zero) otherwise.
+ */
+int app_is_finished(struct app *app);
/*!
* \brief Update the handler and data for a \c res_stasis application.
More information about the asterisk-commits
mailing list