Skip to content

Commit cf7ff70

Browse files
committed
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.
1 parent 5d96e3a commit cf7ff70

3 files changed

Lines changed: 24 additions & 2 deletions

File tree

src/channel.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2782,7 +2782,8 @@ channel_wait(channel_T *channel, sock_T fd, int timeout)
27822782
channel_close_on_error(channel_T *channel, char *func)
27832783
{
27842784
/* Do not call emsg(), most likely the other end just exited. */
2785-
ch_errors(channel, "%s(): Cannot read from channel", func);
2785+
ch_errors(channel, "%s(): Cannot read from channel, will close it soon",
2786+
func);
27862787

27872788
/* Queue a "DETACH" netbeans message in the command queue in order to
27882789
* terminate the netbeans session later. Do not end the session here
@@ -2800,7 +2801,15 @@ channel_close_on_error(channel_T *channel, char *func)
28002801
(int)STRLEN(DETACH_MSG_RAW), FALSE, "PUT ");
28012802

28022803
/* When reading from stdout is not possible, assume the other side has
2803-
* died. */
2804+
* died. Don't close the channel right away, it may be the wrong moment
2805+
* to invoke callbacks. */
2806+
channel->ch_to_be_closed = TRUE;
2807+
}
2808+
2809+
static void
2810+
channel_close_now(channel_T *channel)
2811+
{
2812+
ch_log(channel, "Closing channel because of previous read error");
28042813
channel_close(channel, TRUE);
28052814
if (channel->ch_nb_close_cb != NULL)
28062815
(*channel->ch_nb_close_cb)();
@@ -3515,6 +3524,14 @@ channel_parse_messages(void)
35153524
}
35163525
while (channel != NULL)
35173526
{
3527+
if (channel->ch_to_be_closed)
3528+
{
3529+
channel->ch_to_be_closed = FALSE;
3530+
channel_close_now(channel);
3531+
/* channel may have been freed, start over */
3532+
channel = first_channel;
3533+
continue;
3534+
}
35183535
if (channel->ch_refcount == 0 && !channel_still_useful(channel))
35193536
{
35203537
/* channel is no longer useful, free it */

src/structs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,9 @@ struct channel_S {
14161416
char *ch_hostname; /* only for socket, allocated */
14171417
int ch_port; /* only for socket */
14181418

1419+
int ch_to_be_closed; /* When TRUE reading or writing failed and
1420+
* the channel must be closed when it's safe
1421+
* to invoke callbacks. */
14191422
int ch_error; /* When TRUE an error was reported. Avoids
14201423
* giving pages full of error messages when
14211424
* the other side has exited, only mention the

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,8 @@ static char *(features[]) =
753753

754754
static int included_patches[] =
755755
{ /* Add new patch number below this line */
756+
/**/
757+
1826,
756758
/**/
757759
1825,
758760
/**/

0 commit comments

Comments
 (0)