comparison src/channel.c @ 8055:6db4b1c863ec v7.4.1322

commit https://github.com/vim/vim/commit/3bece9fee9c02934d3e295b29d253e13d4ef26a7 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Feb 15 20:39:46 2016 +0100 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.
author Christian Brabandt <cb@256bit.org>
date Mon, 15 Feb 2016 20:45:04 +0100
parents 15253130abd8
children 19304db153bc
comparison
equal deleted inserted replaced
8054:adb3150edaaf 8055:6db4b1c863ec
1215 channel->CH_ERR = -1; 1215 channel->CH_ERR = -1;
1216 } 1216 }
1217 #endif 1217 #endif
1218 1218
1219 channel->ch_close_cb = NULL; 1219 channel->ch_close_cb = NULL;
1220 vim_free(channel->ch_callback);
1221 channel->ch_callback = NULL;
1222 channel_clear(channel); 1220 channel_clear(channel);
1223 } 1221 }
1224 1222
1225 /* 1223 /*
1226 * Store "buf[len]" on channel "channel". 1224 * Store "buf[len]" on channel "channel".
1296 while (json_head->jq_next != NULL) 1294 while (json_head->jq_next != NULL)
1297 { 1295 {
1298 free_tv(json_head->jq_next->jq_value); 1296 free_tv(json_head->jq_next->jq_value);
1299 remove_json_node(json_head, json_head->jq_next); 1297 remove_json_node(json_head, json_head->jq_next);
1300 } 1298 }
1299
1300 vim_free(channel->ch_callback);
1301 channel->ch_callback = NULL;
1301 } 1302 }
1302 1303
1303 #if defined(EXITFREE) || defined(PROTO) 1304 #if defined(EXITFREE) || defined(PROTO)
1304 void 1305 void
1305 channel_free_all(void) 1306 channel_free_all(void)
1800 * Return TRUE when something was done. 1801 * Return TRUE when something was done.
1801 */ 1802 */
1802 int 1803 int
1803 channel_parse_messages(void) 1804 channel_parse_messages(void)
1804 { 1805 {
1805 channel_T *channel; 1806 channel_T *channel = first_channel;
1806 int ret = FALSE; 1807 int ret = FALSE;
1807 1808 int r;
1808 for (channel = first_channel; channel != NULL; channel = channel->ch_next) 1809
1809 while (may_invoke_callback(channel) == OK) 1810 while (channel != NULL)
1810 { 1811 {
1811 channel = first_channel; /* start over */ 1812 /* Increase the refcount, in case the handler causes the channel to be
1813 * unreferenced or closed. */
1814 ++channel->ch_refcount;
1815 r = may_invoke_callback(channel);
1816 if (channel_unref(channel))
1817 /* channel was freed, start over */
1818 channel = first_channel;
1819
1820 if (r == OK)
1821 {
1822 channel = first_channel; /* something was done, start over */
1812 ret = TRUE; 1823 ret = TRUE;
1813 } 1824 }
1825 else
1826 channel = channel->ch_next;
1827 }
1814 return ret; 1828 return ret;
1815 } 1829 }
1816 1830
1817 /* 1831 /*
1818 * Mark references to lists used in channels. 1832 * Mark references to lists used in channels.