forked from aniani/vim
patch 7.4.1826
Problem: Callbacks are invoked when it's not safe. (Andrew Stewart) Solution: When a channel is to be closed don't invoke callbacks right away, wait for a safe moment.
This commit is contained in:
@@ -2782,7 +2782,8 @@ channel_wait(channel_T *channel, sock_T fd, int timeout)
|
|||||||
channel_close_on_error(channel_T *channel, char *func)
|
channel_close_on_error(channel_T *channel, char *func)
|
||||||
{
|
{
|
||||||
/* Do not call emsg(), most likely the other end just exited. */
|
/* Do not call emsg(), most likely the other end just exited. */
|
||||||
ch_errors(channel, "%s(): Cannot read from channel", func);
|
ch_errors(channel, "%s(): Cannot read from channel, will close it soon",
|
||||||
|
func);
|
||||||
|
|
||||||
/* Queue a "DETACH" netbeans message in the command queue in order to
|
/* Queue a "DETACH" netbeans message in the command queue in order to
|
||||||
* terminate the netbeans session later. Do not end the session here
|
* terminate the netbeans session later. Do not end the session here
|
||||||
@@ -2800,7 +2801,15 @@ channel_close_on_error(channel_T *channel, char *func)
|
|||||||
(int)STRLEN(DETACH_MSG_RAW), FALSE, "PUT ");
|
(int)STRLEN(DETACH_MSG_RAW), FALSE, "PUT ");
|
||||||
|
|
||||||
/* When reading from stdout is not possible, assume the other side has
|
/* When reading from stdout is not possible, assume the other side has
|
||||||
* died. */
|
* died. Don't close the channel right away, it may be the wrong moment
|
||||||
|
* to invoke callbacks. */
|
||||||
|
channel->ch_to_be_closed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
channel_close_now(channel_T *channel)
|
||||||
|
{
|
||||||
|
ch_log(channel, "Closing channel because of previous read error");
|
||||||
channel_close(channel, TRUE);
|
channel_close(channel, TRUE);
|
||||||
if (channel->ch_nb_close_cb != NULL)
|
if (channel->ch_nb_close_cb != NULL)
|
||||||
(*channel->ch_nb_close_cb)();
|
(*channel->ch_nb_close_cb)();
|
||||||
@@ -3515,6 +3524,14 @@ channel_parse_messages(void)
|
|||||||
}
|
}
|
||||||
while (channel != NULL)
|
while (channel != NULL)
|
||||||
{
|
{
|
||||||
|
if (channel->ch_to_be_closed)
|
||||||
|
{
|
||||||
|
channel->ch_to_be_closed = FALSE;
|
||||||
|
channel_close_now(channel);
|
||||||
|
/* channel may have been freed, start over */
|
||||||
|
channel = first_channel;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (channel->ch_refcount == 0 && !channel_still_useful(channel))
|
if (channel->ch_refcount == 0 && !channel_still_useful(channel))
|
||||||
{
|
{
|
||||||
/* channel is no longer useful, free it */
|
/* channel is no longer useful, free it */
|
||||||
|
@@ -1416,6 +1416,9 @@ struct channel_S {
|
|||||||
char *ch_hostname; /* only for socket, allocated */
|
char *ch_hostname; /* only for socket, allocated */
|
||||||
int ch_port; /* only for socket */
|
int ch_port; /* only for socket */
|
||||||
|
|
||||||
|
int ch_to_be_closed; /* When TRUE reading or writing failed and
|
||||||
|
* the channel must be closed when it's safe
|
||||||
|
* to invoke callbacks. */
|
||||||
int ch_error; /* When TRUE an error was reported. Avoids
|
int ch_error; /* When TRUE an error was reported. Avoids
|
||||||
* giving pages full of error messages when
|
* giving pages full of error messages when
|
||||||
* the other side has exited, only mention the
|
* the other side has exited, only mention the
|
||||||
|
@@ -753,6 +753,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1826,
|
||||||
/**/
|
/**/
|
||||||
1825,
|
1825,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user