[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