diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c
index ac44086f5cd464136f8552fdd3a43865060248bc..f654dd3a41f04ab1d415c8fd40b79b5dcf09fd68 100644
--- a/apps/app_chanspy.c
+++ b/apps/app_chanspy.c
@@ -211,9 +211,9 @@ static int start_spying(struct ast_channel *chan, struct ast_channel *spychan, s
 
 static void stop_spying(struct ast_channel *chan, struct ast_channel_spy *spy) 
 {
-	/* If our status has changed, then the channel we're spying on is gone....
+	/* If our status has changed to DONE, then the channel we're spying on is gone....
 	   DON'T TOUCH IT!!!  RUN AWAY!!! */
-	if (spy->status != CHANSPY_RUNNING)
+	if (spy->status == CHANSPY_DONE)
 		return;
 
 	if (!chan)
diff --git a/apps/app_mixmonitor.c b/apps/app_mixmonitor.c
index 743e699ca21765f72a768771b7f1e6342ff320c7..dd29dd2f3f6cd8f73158e33fbe57ed03ae06ffe8 100644
--- a/apps/app_mixmonitor.c
+++ b/apps/app_mixmonitor.c
@@ -86,7 +86,6 @@ LOCAL_USER_DECL;
 static const char *mixmonitor_spy_type = "MixMonitor";
 
 struct mixmonitor {
-	AST_LIST_ENTRY(mixmonitor) list;
 	struct ast_channel *chan;
 	char *filename;
 	char *post_process;
@@ -95,15 +94,12 @@ struct mixmonitor {
 	int writevol;
 };
 
-AST_LIST_HEAD_STATIC(monitors, mixmonitor);
-
 enum {
 	MUXFLAG_APPEND = (1 << 1),
 	MUXFLAG_BRIDGED = (1 << 2),
 	MUXFLAG_VOLUME = (1 << 3),
 	MUXFLAG_READVOLUME = (1 << 4),
 	MUXFLAG_WRITEVOLUME = (1 << 5),
-	FLAG_STOP = (1 << 6),
 } mixmonitor_flags;
 
 enum {
@@ -123,9 +119,9 @@ AST_APP_OPTIONS(mixmonitor_opts, {
 
 static void stopmon(struct ast_channel *chan, struct ast_channel_spy *spy) 
 {
-	/* If our status has changed, then the channel we're spying on is gone....
+	/* If our status has changed to DONE, then the channel we're spying on is gone....
 	   DON'T TOUCH IT!!!  RUN AWAY!!! */
-	if (spy->status != CHANSPY_RUNNING)
+	if (spy->status == CHANSPY_DONE)
 		return;
 
 	if (!chan)
@@ -168,10 +164,6 @@ static void *mixmonitor_thread(void *obj)
 	
 	STANDARD_INCREMENT_USECOUNT;
 
-	AST_LIST_LOCK(&monitors);
-	AST_LIST_INSERT_HEAD(&monitors, mixmonitor, list);
-	AST_LIST_UNLOCK(&monitors);
-
 	name = ast_strdupa(mixmonitor->chan->name);
 
 	oflags = O_CREAT|O_WRONLY;
@@ -226,7 +218,7 @@ static void *mixmonitor_thread(void *obj)
 
 		ast_channel_spy_trigger_wait(&spy);
 		
-		if (ast_check_hangup(mixmonitor->chan) || spy.status != CHANSPY_RUNNING || ast_test_flag(mixmonitor, FLAG_STOP)) {
+		if (ast_check_hangup(mixmonitor->chan) || spy.status != CHANSPY_RUNNING) {
 			ast_mutex_unlock(&spy.lock);
 			break;
 		}
@@ -252,8 +244,6 @@ static void *mixmonitor_thread(void *obj)
 		ast_mutex_unlock(&spy.lock);
 	}
 	
-	stopmon(mixmonitor->chan, &spy);
-
 	if (mixmonitor->post_process) {
 		char *p;
 
@@ -265,6 +255,8 @@ static void *mixmonitor_thread(void *obj)
 		pbx_substitute_variables_helper(mixmonitor->chan, mixmonitor->post_process, post_process, sizeof(post_process) - 1);
 	}
 
+	stopmon(mixmonitor->chan, &spy);
+
 	if (option_verbose > 1)
 		ast_verbose(VERBOSE_PREFIX_2 "End MixMonitor Recording %s\n", name);
 
@@ -281,10 +273,6 @@ out2:
 		ast_closestream(fs);
 
 out:
-	AST_LIST_LOCK(&monitors);
-	AST_LIST_REMOVE(&monitors, mixmonitor, list);
-	AST_LIST_UNLOCK(&monitors);
-
 	free(mixmonitor);
 
 	STANDARD_DECREMENT_USECOUNT;
@@ -415,7 +403,6 @@ static int mixmonitor_exec(struct ast_channel *chan, void *data)
 static int mixmonitor_cli(int fd, int argc, char **argv) 
 {
 	struct ast_channel *chan;
-	struct mixmonitor *mon;
 
 	if (argc < 3)
 		return RESULT_SHOWUSAGE;
@@ -427,13 +414,8 @@ static int mixmonitor_cli(int fd, int argc, char **argv)
 
 	if (!strcasecmp(argv[1], "start"))
 		mixmonitor_exec(chan, argv[3]);
-	else if (!strcasecmp(argv[1], "stop")) {
-		AST_LIST_TRAVERSE_SAFE_BEGIN(&monitors, mon, list) {
-			if (chan == mon->chan)
-				ast_set_flag(mon, FLAG_STOP);
-		}
-		AST_LIST_TRAVERSE_SAFE_END;
-	}
+	else if (!strcasecmp(argv[1], "stop"))
+		ast_channel_spy_stop_by_type(chan, mixmonitor_spy_type);
 
 	ast_mutex_unlock(&chan->lock);
 
diff --git a/channel.c b/channel.c
index a482cf1d548223c17074c7b70bed9f9b9efff5f7..4ea2168e57a3d6a6ae3767efdd070c2c1cf27014 100644
--- a/channel.c
+++ b/channel.c
@@ -996,7 +996,7 @@ void ast_channel_spy_stop_by_type(struct ast_channel *chan, const char *type)
 	AST_LIST_TRAVERSE(&chan->spies->list, spy, list) {
 		ast_mutex_lock(&spy->lock);
 		if ((spy->type == type) && (spy->status == CHANSPY_RUNNING)) {
-			spy->status = CHANSPY_DONE;
+			spy->status = CHANSPY_STOP;
 			if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
 				ast_cond_signal(&spy->trigger);
 		}
diff --git a/include/asterisk/chanspy.h b/include/asterisk/chanspy.h
index 4973763b23dd046b3e1aea88c4710eb448f55c58..5b2f5df187422f00411c3e8572e9fac3a1e59f89 100644
--- a/include/asterisk/chanspy.h
+++ b/include/asterisk/chanspy.h
@@ -30,9 +30,10 @@ extern "C" {
 #include "asterisk/linkedlists.h"
 
 enum chanspy_states {
-	CHANSPY_NEW = 0,
-	CHANSPY_RUNNING = 1,
-	CHANSPY_DONE = 2,
+	CHANSPY_NEW = 0,		/*!< spy not yet operating */
+	CHANSPY_RUNNING = 1,		/*!< normal operation, spy is still operating */
+	CHANSPY_DONE = 2,		/*!< spy is stopped and already removed from channel */
+	CHANSPY_STOP = 3,		/*!< spy requested to stop, still attached to channel */
 };
 
 enum chanspy_flags {