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. */
|
||||
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
|
||||
static int
|
||||
@@ -403,8 +406,15 @@ channel_free(channel_T *channel)
|
||||
{
|
||||
if (!in_free_unref_items)
|
||||
{
|
||||
channel_free_contents(channel);
|
||||
channel_free_channel(channel);
|
||||
if (safe_to_invoke_callback == 0)
|
||||
{
|
||||
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;
|
||||
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)
|
||||
if (!channel_still_useful(ch)
|
||||
&& (ch->ch_copyID & mask) != (copyID & mask))
|
||||
@@ -453,6 +467,8 @@ free_unused_channels_contents(int copyID, int mask)
|
||||
channel_free_contents(ch);
|
||||
did_free = TRUE;
|
||||
}
|
||||
|
||||
--safe_to_invoke_callback;
|
||||
return did_free;
|
||||
}
|
||||
|
||||
@@ -1450,6 +1466,9 @@ invoke_callback(channel_T *channel, char_u *callback, partial_T *partial,
|
||||
typval_T rettv;
|
||||
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].vval.v_channel = channel;
|
||||
|
||||
@@ -3515,6 +3534,8 @@ channel_parse_messages(void)
|
||||
int r;
|
||||
int part = PART_SOCK;
|
||||
|
||||
++safe_to_invoke_callback;
|
||||
|
||||
/* Only do this message when another message was given, otherwise we get
|
||||
* lots of them. */
|
||||
if (did_log_msg)
|
||||
@@ -3532,6 +3553,13 @@ channel_parse_messages(void)
|
||||
channel = first_channel;
|
||||
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))
|
||||
{
|
||||
/* channel is no longer useful, free it */
|
||||
@@ -3572,6 +3600,8 @@ channel_parse_messages(void)
|
||||
redraw_after_callback();
|
||||
}
|
||||
|
||||
--safe_to_invoke_callback;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -1419,6 +1419,8 @@ struct channel_S {
|
||||
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_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
|
||||
* giving pages full of error messages when
|
||||
* the other side has exited, only mention the
|
||||
|
@@ -753,6 +753,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1827,
|
||||
/**/
|
||||
1826,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user