diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c
index 3c7a9171635641d982d273c767d7cb510f6e1ef9..5dbb0b86030a3acda3c4cad74aa725e8e40a60b7 100644
--- a/apps/app_chanspy.c
+++ b/apps/app_chanspy.c
@@ -598,12 +598,12 @@ static int attach_barge(struct ast_autochan *spyee_autochan,
 		return -1;
 	}
 
-	ast_channel_lock(internal_bridge_autochan->chan);
+	ast_autochan_channel_lock(internal_bridge_autochan);
 	if (start_spying(internal_bridge_autochan, spyer_name, bridge_whisper_audiohook)) {
 		ast_log(LOG_WARNING, "Unable to attach barge audiohook on spyee '%s'. Barge mode disabled.\n", name);
 		retval = -1;
 	}
-	ast_channel_unlock(internal_bridge_autochan->chan);
+	ast_autochan_channel_unlock(internal_bridge_autochan);
 
 	*spyee_bridge_autochan = internal_bridge_autochan;
 
@@ -632,9 +632,9 @@ static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_auto
 	spyer_name = ast_strdupa(ast_channel_name(chan));
 	ast_channel_unlock(chan);
 
-	ast_channel_lock(spyee_autochan->chan);
+	ast_autochan_channel_lock(spyee_autochan);
 	name = ast_strdupa(ast_channel_name(spyee_autochan->chan));
-	ast_channel_unlock(spyee_autochan->chan);
+	ast_autochan_channel_unlock(spyee_autochan);
 
 	ast_verb(2, "Spying on channel %s\n", name);
 	publish_chanspy_message(chan, spyee_autochan->chan, 1);
diff --git a/apps/app_mixmonitor.c b/apps/app_mixmonitor.c
index f5f9b22c17b8335c7fc1c44ffa7e9c87e5886fa6..7d7a0cbf914b40f3cebc40671fcf9012042718ff 100644
--- a/apps/app_mixmonitor.c
+++ b/apps/app_mixmonitor.c
@@ -726,11 +726,11 @@ static void *mixmonitor_thread(void *obj)
 
 	ast_audiohook_unlock(&mixmonitor->audiohook);
 
-	ast_channel_lock(mixmonitor->autochan->chan);
+	ast_autochan_channel_lock(mixmonitor->autochan);
 	if (ast_test_flag(mixmonitor, MUXFLAG_BEEP_STOP)) {
 		ast_stream_and_wait(mixmonitor->autochan->chan, "beep", "");
 	}
-	ast_channel_unlock(mixmonitor->autochan->chan);
+	ast_autochan_channel_unlock(mixmonitor->autochan);
 
 	ast_autochan_destroy(mixmonitor->autochan);
 
@@ -802,11 +802,11 @@ static int setup_mixmonitor_ds(struct mixmonitor *mixmonitor, struct ast_channel
 		return -1;
 	}
 
-	ast_channel_lock(mixmonitor->autochan->chan);
+	ast_autochan_channel_lock(mixmonitor->autochan);
 	if (ast_test_flag(mixmonitor, MUXFLAG_BEEP_START)) {
 		ast_stream_and_wait(mixmonitor->autochan->chan, "beep", "");
 	}
-	ast_channel_unlock(mixmonitor->autochan->chan);
+	ast_autochan_channel_unlock(mixmonitor->autochan);
 
 	mixmonitor_ds->samp_rate = 8000;
 	mixmonitor_ds->audiohook = &mixmonitor->audiohook;
diff --git a/include/asterisk/autochan.h b/include/asterisk/autochan.h
index a0981b7c9f6b5cedbf824773021c05745e04db2d..319c203ab1557d74da6c3ded4de388cfb33dcbf7 100644
--- a/include/asterisk/autochan.h
+++ b/include/asterisk/autochan.h
@@ -56,8 +56,28 @@ struct ast_autochan {
  * to save off the pointer using ast_channel_ref and to unref the channel when you
  * are finished with the pointer. If you do not do this and a masquerade occurs on
  * the channel, then it is possible that your saved pointer will become invalid.
+ *
+ * 3. If you want to lock the autochan->chan channel, be sure to use
+ * ast_autochan_channel_lock and ast_autochan_channel_unlock. An attempt to lock
+ * the autochan->chan directly may result in it being changed after you've
+ * retrieved the value of chan, but before you've had a chance to lock it.
+ * First when chan is locked, the autochan structure is guaranteed to keep the
+ * same channel.
  */
 
+#define ast_autochan_channel_lock(autochan) \
+	do { \
+		struct ast_channel *autochan_chan = autochan->chan; \
+		ast_channel_lock(autochan_chan); \
+		if (autochan->chan == autochan_chan) { \
+			break; \
+		} \
+		ast_channel_unlock(autochan_chan); \
+	} while (1)
+
+#define ast_autochan_channel_unlock(autochan) \
+	ast_channel_unlock(autochan->chan)
+
 /*!
  * \brief set up a new ast_autochan structure
  *
diff --git a/main/autochan.c b/main/autochan.c
index d41a8d82143387cf9a84aacac2ac76d76f7cffac..38d778438cbd7de81955e55cf26ffe0c691eaa9c 100644
--- a/main/autochan.c
+++ b/main/autochan.c
@@ -51,7 +51,7 @@ struct ast_autochan *ast_autochan_setup(struct ast_channel *chan)
 
 	autochan->chan = ast_channel_ref(chan);
 
-	ast_channel_lock(autochan->chan);
+	ast_channel_lock(autochan->chan); /* autochan is still private, no need for ast_autochan_channel_lock() */
 	AST_LIST_INSERT_TAIL(ast_channel_autochans(autochan->chan), autochan, list);
 	ast_channel_unlock(autochan->chan);
 
@@ -64,7 +64,7 @@ void ast_autochan_destroy(struct ast_autochan *autochan)
 {
 	struct ast_autochan *autochan_iter;
 
-	ast_channel_lock(autochan->chan);
+	ast_autochan_channel_lock(autochan);
 	AST_LIST_TRAVERSE_SAFE_BEGIN(ast_channel_autochans(autochan->chan), autochan_iter, list) {
 		if (autochan_iter == autochan) {
 			AST_LIST_REMOVE_CURRENT(list);
@@ -73,7 +73,7 @@ void ast_autochan_destroy(struct ast_autochan *autochan)
 		}
 	}
 	AST_LIST_TRAVERSE_SAFE_END;
-	ast_channel_unlock(autochan->chan);
+	ast_autochan_channel_unlock(autochan);
 
 	autochan->chan = ast_channel_unref(autochan->chan);