Patch 7.4.1458
Problem: When a JSON channel has a callback it may never be cleared.
Solution: Do not write "DETACH" into a JS or JSON channel.
Files: src/channel.c
*** ../vim-7.4.1457/src/channel.c 2016-02-28 20:51:44.549531370 +0100
--- src/channel.c 2016-02-28 22:12:53.710097047 +0100
***************
*** 316,335 ****
* Called when the refcount of a channel is zero.
* Return TRUE if "channel" has a callback and the associated job wasn't
* killed.
- * If the job was killed the channel is not expected to work anymore.
- * If there is no callback then nobody can get readahead.
*/
static int
channel_still_useful(channel_T *channel)
{
if (channel->ch_job_killed && channel->ch_job == NULL)
return FALSE;
! 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;
}
/*
--- 316,362 ----
* Called when the refcount of a channel is zero.
* Return TRUE if "channel" has a callback and the associated job wasn't
* killed.
*/
static int
channel_still_useful(channel_T *channel)
{
+ int has_sock_msg;
+ #ifdef CHANNEL_PIPES
+ int has_out_msg;
+ int has_err_msg;
+ #endif
+
+ /* If the job was killed the channel is not expected to work anymore. */
if (channel->ch_job_killed && channel->ch_job == NULL)
return FALSE;
!
! /* If there is a close callback it may still need to be invoked. */
! if (channel->ch_close_cb != NULL)
! return TRUE;
!
! /* If there is no callback then nobody can get readahead. If the fd is
! * closed and there is no readahead then the callback won't be called. */
! has_sock_msg = channel->ch_part[PART_SOCK].ch_fd != INVALID_FD
! || channel->ch_part[PART_SOCK].ch_head.rq_next != NULL
! || channel->ch_part[PART_SOCK].ch_json_head.jq_next != NULL;
! #ifdef CHANNEL_PIPES
! has_out_msg = channel->ch_part[PART_OUT].ch_fd != INVALID_FD
! || channel->ch_part[PART_OUT].ch_head.rq_next != NULL
! || channel->ch_part[PART_OUT].ch_json_head.jq_next != NULL;
! has_err_msg = channel->ch_part[PART_ERR].ch_fd != INVALID_FD
! || channel->ch_part[PART_ERR].ch_head.rq_next != NULL
! || channel->ch_part[PART_ERR].ch_json_head.jq_next != NULL;
! #endif
! return (channel->ch_callback != NULL && (has_sock_msg
! #ifdef CHANNEL_PIPES
! || has_out_msg || has_err_msg
! #endif
! ))
#ifdef CHANNEL_PIPES
! || (channel->ch_part[PART_OUT].ch_callback != NULL && has_out_msg)
! || (channel->ch_part[PART_ERR].ch_callback != NULL && has_err_msg)
#endif
! ;
}
/*
***************
*** 1497,1503 ****
{
if (item->cq_seq_nr == seq_nr)
{
! ch_logs(channel, "Invoking one-time callback '%s'",
(char *)item->cq_callback);
/* Remove the item from the list first, if the callback
* invokes ch_close() the list will be cleared. */
--- 1524,1530 ----
{
if (item->cq_seq_nr == seq_nr)
{
! ch_logs(channel, "Invoking one-time callback %s",
(char *)item->cq_callback);
/* Remove the item from the list first, if the callback
* invokes ch_close() the list will be cleared. */
***************
*** 1558,1564 ****
if (callback != NULL)
{
/* invoke the channel callback */
! ch_log(channel, "Invoking channel callback");
invoke_callback(channel, callback, argv);
}
}
--- 1585,1591 ----
if (callback != NULL)
{
/* invoke the channel callback */
! ch_logs(channel, "Invoking channel callback %s", (char *)callback);
invoke_callback(channel, callback, argv);
}
}
***************
*** 1758,1764 ****
/* Sent when the channel is found closed when reading. */
#define DETACH_MSG_RAW "DETACH\n"
- #define DETACH_MSG_JSON "\"DETACH\"\n"
/* Buffer size for reading incoming messages. */
#define MAXMSGSIZE 4096
--- 1785,1790 ----
***************
*** 1854,1860 ****
int readlen = 0;
sock_T fd;
int use_socket = FALSE;
- char *msg;
fd = channel->ch_part[part].ch_fd;
if (fd == INVALID_FD)
--- 1880,1885 ----
***************
*** 1909,1919 ****
* -> ui_breakcheck
* -> gui event loop or select loop
* -> channel_read()
*/
! msg = channel->ch_part[part].ch_mode == MODE_RAW
! || channel->ch_part[part].ch_mode == MODE_NL
! ? DETACH_MSG_RAW : DETACH_MSG_JSON;
! channel_save(channel, part, (char_u *)msg, (int)STRLEN(msg));
/* TODO: When reading from stdout is not possible, should we try to
* keep stdin and stderr open? Probably not, assume the other side
--- 1934,1945 ----
* -> ui_breakcheck
* -> gui event loop or select loop
* -> channel_read()
+ * Don't send "DETACH" for a JS or JSON channel.
*/
! if (channel->ch_part[part].ch_mode == MODE_RAW
! || channel->ch_part[part].ch_mode == MODE_NL)
! channel_save(channel, part, (char_u *)DETACH_MSG_RAW,
! (int)STRLEN(DETACH_MSG_RAW));
/* TODO: When reading from stdout is not possible, should we try to
* keep stdin and stderr open? Probably not, assume the other side
*** ../vim-7.4.1457/src/version.c 2016-02-28 20:51:44.553531328 +0100
--- src/version.c 2016-02-28 22:19:47.597737477 +0100
***************
*** 745,746 ****
--- 745,748 ----
{ /* Add new patch number below this line */
+ /**/
+ 1458,
/**/
--
Wi n0t trei a h0liday in Sweden thi yer?
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
/// 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.