patch 7.4.1322
Problem:    Crash when unletting the variable that holds the channel in a
            callback function.  (Christian Robinson)
Solution:   Increase the reference count while invoking the callback.
diff --git a/src/channel.c b/src/channel.c
index a806c56..cad5a1b 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -1217,8 +1217,6 @@
 #endif
 
     channel->ch_close_cb = NULL;
-    vim_free(channel->ch_callback);
-    channel->ch_callback = NULL;
     channel_clear(channel);
 }
 
@@ -1298,6 +1296,9 @@
 	free_tv(json_head->jq_next->jq_value);
 	remove_json_node(json_head, json_head->jq_next);
     }
+
+    vim_free(channel->ch_callback);
+    channel->ch_callback = NULL;
 }
 
 #if defined(EXITFREE) || defined(PROTO)
@@ -1802,15 +1803,28 @@
     int
 channel_parse_messages(void)
 {
-    channel_T *channel;
-    int	    ret = FALSE;
+    channel_T	*channel = first_channel;
+    int		ret = FALSE;
+    int		r;
 
-    for (channel = first_channel; channel != NULL; channel = channel->ch_next)
-	while (may_invoke_callback(channel) == OK)
+    while (channel != NULL)
+    {
+	/* Increase the refcount, in case the handler causes the channel to be
+	 * unreferenced or closed. */
+	++channel->ch_refcount;
+	r = may_invoke_callback(channel);
+	if (channel_unref(channel))
+	    /* channel was freed, start over */
+	    channel = first_channel;
+
+	if (r == OK)
 	{
-	    channel = first_channel;  /* start over */
+	    channel = first_channel;  /* something was done, start over */
 	    ret = TRUE;
 	}
+	else
+	    channel = channel->ch_next;
+    }
     return ret;
 }