forked from aniani/vim
patch 7.4.1827
Problem: No error when invoking a callback when it's not safe. Solution: Add an error message. Avoid the error when freeing a channel.
This commit is contained in:
@@ -59,6 +59,9 @@ static void channel_read(channel_T *channel, int part, char *func);
|
|||||||
/* Whether a redraw is needed for appending a line to a buffer. */
|
/* Whether a redraw is needed for appending a line to a buffer. */
|
||||||
static int channel_need_redraw = FALSE;
|
static int channel_need_redraw = FALSE;
|
||||||
|
|
||||||
|
/* Whether we are inside channel_parse_messages() or another situation where it
|
||||||
|
* is safe to invoke callbacks. */
|
||||||
|
static int safe_to_invoke_callback = 0;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
static int
|
static int
|
||||||
@@ -403,8 +406,15 @@ channel_free(channel_T *channel)
|
|||||||
{
|
{
|
||||||
if (!in_free_unref_items)
|
if (!in_free_unref_items)
|
||||||
{
|
{
|
||||||
channel_free_contents(channel);
|
if (safe_to_invoke_callback == 0)
|
||||||
channel_free_channel(channel);
|
{
|
||||||
|
channel->ch_to_be_freed = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
channel_free_contents(channel);
|
||||||
|
channel_free_channel(channel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,6 +454,10 @@ free_unused_channels_contents(int copyID, int mask)
|
|||||||
int did_free = FALSE;
|
int did_free = FALSE;
|
||||||
channel_T *ch;
|
channel_T *ch;
|
||||||
|
|
||||||
|
/* This is invoked from the garbage collector, which only runs at a safe
|
||||||
|
* point. */
|
||||||
|
++safe_to_invoke_callback;
|
||||||
|
|
||||||
for (ch = first_channel; ch != NULL; ch = ch->ch_next)
|
for (ch = first_channel; ch != NULL; ch = ch->ch_next)
|
||||||
if (!channel_still_useful(ch)
|
if (!channel_still_useful(ch)
|
||||||
&& (ch->ch_copyID & mask) != (copyID & mask))
|
&& (ch->ch_copyID & mask) != (copyID & mask))
|
||||||
@@ -453,6 +467,8 @@ free_unused_channels_contents(int copyID, int mask)
|
|||||||
channel_free_contents(ch);
|
channel_free_contents(ch);
|
||||||
did_free = TRUE;
|
did_free = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--safe_to_invoke_callback;
|
||||||
return did_free;
|
return did_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1450,6 +1466,9 @@ invoke_callback(channel_T *channel, char_u *callback, partial_T *partial,
|
|||||||
typval_T rettv;
|
typval_T rettv;
|
||||||
int dummy;
|
int dummy;
|
||||||
|
|
||||||
|
if (safe_to_invoke_callback == 0)
|
||||||
|
EMSG("INTERNAL: Invoking callback when it is not safe");
|
||||||
|
|
||||||
argv[0].v_type = VAR_CHANNEL;
|
argv[0].v_type = VAR_CHANNEL;
|
||||||
argv[0].vval.v_channel = channel;
|
argv[0].vval.v_channel = channel;
|
||||||
|
|
||||||
@@ -3515,6 +3534,8 @@ channel_parse_messages(void)
|
|||||||
int r;
|
int r;
|
||||||
int part = PART_SOCK;
|
int part = PART_SOCK;
|
||||||
|
|
||||||
|
++safe_to_invoke_callback;
|
||||||
|
|
||||||
/* Only do this message when another message was given, otherwise we get
|
/* Only do this message when another message was given, otherwise we get
|
||||||
* lots of them. */
|
* lots of them. */
|
||||||
if (did_log_msg)
|
if (did_log_msg)
|
||||||
@@ -3532,6 +3553,13 @@ channel_parse_messages(void)
|
|||||||
channel = first_channel;
|
channel = first_channel;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (channel->ch_to_be_freed)
|
||||||
|
{
|
||||||
|
channel_free(channel);
|
||||||
|
/* channel has 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 */
|
||||||
@@ -3572,6 +3600,8 @@ channel_parse_messages(void)
|
|||||||
redraw_after_callback();
|
redraw_after_callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--safe_to_invoke_callback;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1419,6 +1419,8 @@ struct channel_S {
|
|||||||
int ch_to_be_closed; /* When TRUE reading or writing failed and
|
int ch_to_be_closed; /* When TRUE reading or writing failed and
|
||||||
* the channel must be closed when it's safe
|
* the channel must be closed when it's safe
|
||||||
* to invoke callbacks. */
|
* to invoke callbacks. */
|
||||||
|
int ch_to_be_freed; /* When TRUE channel must be freed 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 */
|
||||||
|
/**/
|
||||||
|
1827,
|
||||||
/**/
|
/**/
|
||||||
1826,
|
1826,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user