comparison src/channel.c @ 8257:c4ffdda8cdfd v7.4.1421

commit https://github.com/vim/vim/commit/c8dcbb12c5d7f3eb0c334daebb4475bb015b91e7 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Feb 25 23:10:17 2016 +0100 patch 7.4.1421 Problem: May free a channel when a callback may need to be invoked. Solution: Keep the channel when refcount is zero.
author Christian Brabandt <cb@256bit.org>
date Thu, 25 Feb 2016 23:15:05 +0100
parents 60586ce747c4
children 99a70c3b902f
comparison
equal deleted inserted replaced
8256:1a895d499690 8257:c4ffdda8cdfd
302 } 302 }
303 first_channel = channel; 303 first_channel = channel;
304 304
305 channel->ch_refcount = 1; 305 channel->ch_refcount = 1;
306 return channel; 306 return channel;
307 }
308
309 /*
310 * Return TRUE if "channel" has a callback.
311 */
312 static int
313 channel_has_callback(channel_T *channel)
314 {
315 return channel->ch_callback != NULL
316 #ifdef CHANNEL_PIPES
317 || channel->ch_part[PART_OUT].ch_callback != NULL
318 || channel->ch_part[PART_ERR].ch_callback != NULL
319 #endif
320 || channel->ch_close_cb != NULL;
321 }
322
323 /*
324 * Close a channel and free all its resources if there is no further action
325 * possible, there is no callback to be invoked.
326 */
327 void
328 channel_may_free(channel_T *channel)
329 {
330 if (!channel_has_callback(channel))
331 channel_free(channel);
307 } 332 }
308 333
309 /* 334 /*
310 * Close a channel and free all its resources. 335 * Close a channel and free all its resources.
311 */ 336 */
1461 return "closed"; 1486 return "closed";
1462 } 1487 }
1463 1488
1464 /* 1489 /*
1465 * Close channel "channel". 1490 * Close channel "channel".
1466 * This does not trigger the close callback. 1491 * Trigger the close callback if "invoke_close_cb" is TRUE.
1467 */ 1492 */
1468 void 1493 void
1469 channel_close(channel_T *channel, int invoke_close_cb) 1494 channel_close(channel_T *channel, int invoke_close_cb)
1470 { 1495 {
1471 ch_log(channel, "Closing channel"); 1496 ch_log(channel, "Closing channel");
2147 int r; 2172 int r;
2148 int part = PART_SOCK; 2173 int part = PART_SOCK;
2149 2174
2150 while (channel != NULL) 2175 while (channel != NULL)
2151 { 2176 {
2177 if (channel->ch_refcount == 0 && !channel_has_callback(channel))
2178 {
2179 /* channel is no longer useful, free it */
2180 channel_free(channel);
2181 channel = first_channel;
2182 part = PART_SOCK;
2183 continue;
2184 }
2152 if (channel->ch_part[part].ch_fd != INVALID_FD) 2185 if (channel->ch_part[part].ch_fd != INVALID_FD)
2153 { 2186 {
2154 /* Increase the refcount, in case the handler causes the channel 2187 /* Increase the refcount, in case the handler causes the channel
2155 * to be unreferenced or closed. */ 2188 * to be unreferenced or closed. */
2156 ++channel->ch_refcount; 2189 ++channel->ch_refcount;