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.
Files: src/eval.c, src/channel.c, src/proto/channel.pro
*** ../vim-7.4.1420/src/eval.c 2016-02-24 20:42:58.077568933 +0100
--- src/eval.c 2016-02-25 22:45:18.961035121 +0100
***************
*** 7745,7752 ****
#if defined(FEAT_CHANNEL) || defined(PROTO)
/*
! * Decrement the reference count on "channel" and free it when it goes down to
! * zero.
* Returns TRUE when the channel was freed.
*/
int
--- 7745,7752 ----
#if defined(FEAT_CHANNEL) || defined(PROTO)
/*
! * Decrement the reference count on "channel" and maybe free it when it goes
! * down to zero. Don't free it if there is a pending action.
* Returns TRUE when the channel was freed.
*/
int
***************
*** 7754,7760 ****
{
if (channel != NULL && --channel->ch_refcount <= 0)
{
! channel_free(channel);
return TRUE;
}
return FALSE;
--- 7754,7760 ----
{
if (channel != NULL && --channel->ch_refcount <= 0)
{
! channel_may_free(channel);
return TRUE;
}
return FALSE;
*** ../vim-7.4.1420/src/channel.c 2016-02-24 20:42:58.077568933 +0100
--- src/channel.c 2016-02-25 22:57:39.629196837 +0100
***************
*** 307,312 ****
--- 307,337 ----
}
/*
+ * Return TRUE if "channel" has a callback.
+ */
+ static int
+ channel_has_callback(channel_T *channel)
+ {
+ return channel->ch_callback != NULL
+ #ifdef CHANNEL_PIPES
+ || channel->ch_part[PART_OUT].ch_callback != NULL
+ || channel->ch_part[PART_ERR].ch_callback != NULL
+ #endif
+ || channel->ch_close_cb != NULL;
+ }
+
+ /*
+ * Close a channel and free all its resources if there is no further action
+ * possible, there is no callback to be invoked.
+ */
+ void
+ channel_may_free(channel_T *channel)
+ {
+ if (!channel_has_callback(channel))
+ channel_free(channel);
+ }
+
+ /*
* Close a channel and free all its resources.
*/
void
***************
*** 1463,1469 ****
/*
* Close channel "channel".
! * This does not trigger the close callback.
*/
void
channel_close(channel_T *channel, int invoke_close_cb)
--- 1488,1494 ----
/*
* Close channel "channel".
! * Trigger the close callback if "invoke_close_cb" is TRUE.
*/
void
channel_close(channel_T *channel, int invoke_close_cb)
***************
*** 2149,2154 ****
--- 2174,2187 ----
while (channel != NULL)
{
+ if (channel->ch_refcount == 0 && !channel_has_callback(channel))
+ {
+ /* channel is no longer useful, free it */
+ channel_free(channel);
+ channel = first_channel;
+ part = PART_SOCK;
+ continue;
+ }
if (channel->ch_part[part].ch_fd != INVALID_FD)
{
/* Increase the refcount, in case the handler causes the channel
*** ../vim-7.4.1420/src/proto/channel.pro 2016-02-24 20:42:58.081568892
+0100
--- src/proto/channel.pro 2016-02-25 22:57:43.161159357 +0100
***************
*** 4,9 ****
--- 4,10 ----
void ch_log(channel_T *ch, char *msg);
void ch_logs(channel_T *ch, char *msg, char *name);
channel_T *add_channel(void);
+ void channel_may_free(channel_T *channel);
void channel_free(channel_T *channel);
void channel_gui_register(channel_T *channel);
void channel_gui_register_all(void);
*** ../vim-7.4.1420/src/version.c 2016-02-25 22:37:34.969945642 +0100
--- src/version.c 2016-02-25 22:42:28.018845550 +0100
***************
*** 750,751 ****
--- 750,753 ----
{ /* Add new patch number below this line */
+ /**/
+ 1421,
/**/
--
SIGFUN -- signature too funny (core dumped)
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.