Merge pull request #17687 from zeertzjq/fix-channel-consistency

fix(channel): fix channel consistency
This commit is contained in:
zeertzjq
2022-03-13 05:44:50 +08:00
committed by GitHub
6 changed files with 112 additions and 26 deletions

View File

@@ -1140,6 +1140,7 @@ Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err)
TerminalOptions topts;
Channel *chan = channel_alloc(kChannelStreamInternal);
chan->stream.internal.cb = cb;
chan->stream.internal.closed = false;
topts.data = chan;
// NB: overridden in terminal_check_size if a window is already
// displaying the buffer

View File

@@ -138,8 +138,14 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
*error = (const char *)e_invstream;
return false;
}
api_free_luaref(chan->stream.internal.cb);
chan->stream.internal.cb = LUA_NOREF;
if (chan->term) {
api_free_luaref(chan->stream.internal.cb);
chan->stream.internal.cb = LUA_NOREF;
chan->stream.internal.closed = true;
terminal_close(chan->term, 0);
} else {
channel_decref(chan);
}
break;
default:
@@ -536,7 +542,11 @@ size_t channel_send(uint64_t id, char *data, size_t len, bool data_owned, const
}
if (chan->streamtype == kChannelStreamInternal) {
if (!chan->term) {
if (chan->is_rpc) {
*error = _("Can't send raw data to rpc channel");
goto retfree;
}
if (!chan->term || chan->stream.internal.closed) {
*error = _("Can't send data to closed stream");
goto retfree;
}

View File

@@ -44,6 +44,7 @@ typedef struct {
typedef struct {
LuaRef cb;
bool closed;
} InternalState;
typedef struct {

View File

@@ -317,10 +317,14 @@ void terminal_close(Terminal *term, int status)
term->opts.close_cb(term->opts.data);
}
} else if (!only_destroy) {
// This was called by channel_process_exit_cb() not in process_teardown().
// Associated channel has been closed and the editor is not exiting.
// Do not call the close callback now. Wait for the user to press a key.
char msg[sizeof("\r\n[Process exited ]") + NUMBUFLEN];
snprintf(msg, sizeof msg, "\r\n[Process exited %d]", status);
if (((Channel *)term->opts.data)->streamtype == kChannelStreamInternal) {
snprintf(msg, sizeof msg, "\r\n[Terminal closed]");
} else {
snprintf(msg, sizeof msg, "\r\n[Process exited %d]", status);
}
terminal_receive(term, msg, strlen(msg));
}