aboutsummaryrefslogtreecommitdiff
path: root/test/functional
Commit message (Collapse)AuthorAge
...
* | Merge #7081 from justinmk/rpcstopJustin M. Keyes2017-08-26
|\ \ | | | | | | rpc: close channel if stream was closed
| * | rpc: close channel if stream was closedJustin M. Keyes2017-08-21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | f_jobstop()/f_rpcstop() .. process_stop() .. process_close_in(proc) closes the write-stream of a RPC channel. But there might be a pending RPC notification on the queue, which may get processed just before the channel is closed. To handle that case, check the Stream.closed in channel.c:receive_msgpack(). Before this change, the above scenario could trigger this assert(!stream->closed) in wstream_write(): 0x00007f96e1cd3428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54 0x00007f96e1cd502a in __GI_abort () at abort.c:89 0x00007f96e1ccbbd7 in __assert_fail_base (fmt=<optimized out>, assertion=assertion@entry=0x768f9b "!stream->closed", file=file@entry=0x768f70 "../src/nvim/event/wstream.c", line=line@entry=77, function=function@entry=0x768fb0 <__PRETTY_FUNCTION__.13735> "wstream_write") at assert.c:92 0x00007f96e1ccbc82 in __GI___assert_fail (assertion=0x768f9b "!stream->closed", file=0x768f70 "../src/nvim/event/wstream.c", line=77, function=0x768fb0 <__PRETTY_FUNCTION__.13735> "wstream_write") at assert.c:101 0x00000000004d2c1f in wstream_write (stream=0x7f96e0a35078, buffer=0x7f96e09f9b40) at ../src/nvim/event/wstream.c:77 0x00000000005857b2 in channel_write (channel=0x7f96e0ae5800, buffer=0x7f96e09f9b40) at ../src/nvim/msgpack_rpc/channel.c:551 0x000000000058567d in on_request_event (argv=0x7ffed792efa0) at ../src/nvim/msgpack_rpc/channel.c:523 0x00000000005854c8 in handle_request (channel=0x7f96e0ae5800, request=0x7ffed792f1b8) at ../src/nvim/msgpack_rpc/channel.c:503 0x00000000005850cb in parse_msgpack (channel=0x7f96e0ae5800) at ../src/nvim/msgpack_rpc/channel.c:423 0x0000000000584f90 in receive_msgpack (stream=0x7f96e0a35218, rbuf=0x7f96e0d1d4c0, c=22, data=0x7f96e0ae5800, eof=false) at ../src/nvim/msgpack_rpc/channel.c:389 0x00000000004d0b20 in read_event (argv=0x7ffed792f4a8) at ../src/nvim/event/rstream.c:190 0x00000000004ce462 in multiqueue_process_events (this=0x7f96e18172d0) at ../src/nvim/event/multiqueue.c:150 0x000000000059b630 in nv_event (cap=0x7ffed792f620) at ../src/nvim/normal.c:7908 0x000000000058be69 in normal_execute (state=0x7ffed792f580, key=-25341) at ../src/nvim/normal.c:1137 0x0000000000652463 in state_enter (s=0x7ffed792f580) at ../src/nvim/state.c:61 0x000000000058a1fe in normal_enter (cmdwin=false, noexmode=false) at ../src/nvim/normal.c:467 0x00000000005500c2 in main (argc=2, argv=0x7ffed792f8d8) at ../src/nvim/main.c:554 Alternative approach suggested by bfredl is to use close_cb of the process. My unsuccessful attempt is below. (It seems close_cb is queued too late, which is the similar problem addressed by this commit): commit 75fc12c6ab15711bdb7b18c6d42ec9d157f5145e Author: Justin M. Keyes <justinkz@gmail.com> Date: Fri Aug 18 01:30:41 2017 +0200 rpc: use Stream's close_cb instead of explicit check in receive_msgpack() diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index 8371d3cd482e..e52da23cdc40 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -416,6 +416,10 @@ static void on_process_exit(Process *proc) static void on_process_stream_close(Stream *stream, void *data) { Process *proc = data; + ILOG("on_process_stream_close"); + if (proc->stream_close_cb != NULL) { + proc->stream_close_cb(stream, proc->stream_close_data); + } decref(proc); } diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h index 5c00e8e7ecd5..34a8d54f6f8c 100644 --- a/src/nvim/event/process.h +++ b/src/nvim/event/process.h @@ -26,6 +26,11 @@ struct process { Stream *in, *out, *err; process_exit_cb cb; internal_process_cb internal_exit_cb, internal_close_cb; + + // Called when any of the process streams (in/out/err) closes. + stream_close_cb stream_close_cb; + void *stream_close_data; + bool closed, detach; MultiQueue *events; }; @@ -50,6 +55,8 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data) .closed = false, .internal_close_cb = NULL, .internal_exit_cb = NULL, + .stream_close_cb = NULL, + .stream_close_data = NULL, .detach = false }; } diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index 7c865bfe1e8c..c8720d1e45d9 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.c @@ -95,7 +95,11 @@ void stream_close(Stream *stream, stream_close_cb on_stream_close, void *data) void stream_close_handle(Stream *stream) FUNC_ATTR_NONNULL_ALL { + ILOG("stream=%d", stream); + // LOG_CALLSTACK(); if (stream->uvstream) { + // problem: this schedules on the queue, but channel.c:receive_msgpack may + // be processed before close_cb is called by libuv. uv_close((uv_handle_t *)stream->uvstream, close_cb); } else { uv_close((uv_handle_t *)&stream->uv.idle, close_cb); @@ -105,6 +109,7 @@ void stream_close_handle(Stream *stream) static void close_cb(uv_handle_t *handle) { Stream *stream = handle->data; + ILOG(">>>>>>>>>>>>>>>>>>>>>>> stream=%p stream->internal_close_cb=%p", stream, stream->internal_close_cb); if (stream->buffer) { rbuffer_free(stream->buffer); } diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 782eabe04e4a..dc2b794e366a 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -128,6 +128,8 @@ uint64_t channel_from_process(Process *proc, uint64_t id, char *source) source); incref(channel); // process channels are only closed by the exit_cb channel->data.proc = proc; + channel->data.proc->stream_close_cb = close_cb2; + channel->data.proc->stream_close_data = channel; wstream_init(proc->in, 0); rstream_init(proc->out, 0); @@ -387,17 +389,6 @@ static void receive_msgpack(Stream *stream, RBuffer *rbuf, size_t c, goto end; } - if ((chan_wstream(channel) != NULL && chan_wstream(channel)->closed) - || (chan_rstream(channel) != NULL && chan_rstream(channel)->closed)) { - char buf[256]; - snprintf(buf, sizeof(buf), - "ch %" PRIu64 ": stream closed unexpectedly. " - "closing channel", - channel->id); - call_set_error(channel, buf, WARN_LOG_LEVEL); - goto end; - } - size_t count = rbuffer_size(rbuf); DLOG("ch %" PRIu64 ": parsing %u bytes from msgpack Stream: %p", channel->id, count, stream); @@ -571,23 +562,6 @@ static Stream *chan_wstream(Channel *chan) abort(); } -/// Returns the Stream that a Channel reads from. -static Stream *chan_rstream(Channel *chan) -{ - switch (chan->type) { - case kChannelTypeSocket: - return &chan->data.stream; - case kChannelTypeProc: - return chan->data.proc->out; - case kChannelTypeStdio: - return &chan->data.std.in; - case kChannelTypeInternal: - return NULL; - } - abort(); -} - - static bool channel_write(Channel *channel, WBuffer *buffer) { bool success = false; @@ -799,6 +773,12 @@ static void close_cb(Stream *stream, void *data) decref(data); } +static void close_cb2(Stream *stream, void *data) +{ + ILOG("close_cb2"); + close_channel(data); +} + /// @param source description of source function, rplugin name, TCP addr, etc static Channel *register_channel(ChannelType type, uint64_t id, MultiQueue *events, char *source)
* | | Merge pull request #7192 from llorens/vim-8.0.0092James McCoy2017-08-25
|\ \ \ | | | | | | | | vim-patch:8.0.0092
| * | | vim-patch:8.0.0092Lech Lorens2017-08-21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: C indenting does not support nested namespaces that C++ 17 has. Solution: Add check that passes double colon inside a name. (Pauli, closes vim/vim#1214) https://github.com/vim/vim/commit/ca8b8d6956dd881de6446fc32c38e817a364a6cc
* | | | clipboard: disallow recursion; show hint only once (#7203)Justin M. Keyes2017-08-22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - Show hint only once per session. - provider#clipboard#Call(): prevent recursion - provider#clear_stderr(): use has_key(), because :silent! is still captured by :redir. closes #7184
* | | | Merge #6973 from teto/normal_hlJustin M. Keyes2017-08-22
|\ \ \ \
| * | | | syntax.c: register 'Normal' highlight groupMatthieu Coudron2017-08-22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - :hi Normal works with -u NONE - Makes HL_TABLE and ATTR_ENTYRY a function instead of a macro so that in can be used in gdb. - Introduces ATTRENTRY_INIT to init attrentry_t
* | | | | vim-patch:8.0.0437James McCoy2017-08-21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: The packadd test does not create the symlink correctly and does not test the right thing. Solution: Create the directory and symlink correctly. https://github.com/vim/vim/commit/644df41c44cbdfacdedbba55ef77a6c6031eccd8
* | | | | vim-patch:8.0.0326James McCoy2017-08-21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Packadd test uses wrong directory name. Solution: Use the variable name value. (Hirohito Higashi) https://github.com/vim/vim/commit/24f8f543d4036c5d2ce4ea6973a174cf2176cb72
* | | | | vim-patch:8.0.0325James McCoy2017-08-21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Packadd test does not clean up symlink. Solution: Delete the link. (Hirohito Higashi) https://github.com/vim/vim/commit/913727e56761d57aaba61197c2d3485418dea7eb
* | | | | vim-patch:8.0.0308James McCoy2017-08-21
|/ / / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: When using a symbolic link, the package path will not be inserted at the right position in 'runtimepath'. (Dugan Chen, Norio Takagi) Solution: Resolve symbolic links when finding the right position in 'runtimepath'. (Hirohito Higashi) https://github.com/vim/vim/commit/2f9e575583c2ad3978ee3d0f790eeff7df56bd6c
* | | | Repair tui_spec functional testsDrew Neil2017-08-21
| | | |
* | | | Repair job_spec functional testsDrew Neil2017-08-21
| | | |
* | | | Repair ex_terminal_spec functional testsDrew Neil2017-08-21
| |/ / |/| |
* | | clipboard: test g:clipboard validation, fix a bugJustin M. Keyes2017-08-20
| | | | | | | | | | | | Also fix `:help foo` highlighting in health.vim
* | | clipboard: remove start_batch_changes() in redir_write()Justin M. Keyes2017-08-20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | start_batch_changes() doesn't avoid invoking the clipboard once-per-line, because the loop is actually in ex_echo(), which calls redir_write() for each message. But we've already entered start_batch_changes() by then, so that was never the problem. redir_write at /home/vagrant/old.neovim/build/../src/nvim/message.c:2523 msg_puts_attr_len at /home/vagrant/old.neovim/build/../src/nvim/message.c:1600 msg_outtrans_len_attr at /home/vagrant/old.neovim/build/../src/nvim/message.c:1221 ex_echo at /home/vagrant/old.neovim/build/../src/nvim/eval.c:19433 do_one_cmd at /home/vagrant/old.neovim/build/../src/nvim/ex_docmd.c:2242 Trying to defer _explicit_ clipboard updates is difficult. :redir @+ | silent echo system('cat foo') | redir END is essentially equivalent to: for l in readfile('foo') let @+ .= l endfor We cannot make judgements about when to ignore a script's bad decisions. start_batch_changes() only works around the case of clipboard=unnamed, i.e. _implicit_ clipboard updates (`:g/foo/d`). Not explicit assignment.
* | | clipboard: avoid error flood during :redirJustin M. Keyes2017-08-20
|/ / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | redir_write(): - This is a "batch" operation which was not yet covered by start_batch_changes() adjust_clipboard_name(): - msg() and friends during :redir will, of course, cause redir_write() to try to capture that message, which causes recursion. - EMSG() here is trouble: if it interrupts :redir it is a mess. Rather than deal with the mess, show a non-error message. closes #7182 closes #7184 closes #7183 ref #6048 ref #7032
* | test/win: give up on this oneJustin M. Keyes2017-08-16
| |
* | test/win: place cursor at edge to tickle SIGWINCHJustin M. Keyes2017-08-16
| |
* | test: tty-test.c: keep `tty_out` handle aroundJustin M. Keyes2017-08-16
| | | | | | | | | | Now the window_split_tab_spec.lua test seems to work. Also do some cleanup.
* | win/test: enable more :terminal testsJustin M. Keyes2017-08-16
| | | | | | | | | | | | To deal with SIGWINCH limitations on Windows, change some resize tests to _shrink_ the screen width. ... But this didn't work, so still ignoring those tests on Windows.
* | test: tty-test.c: restore win32 SIGWINCH handlerJustin M. Keyes2017-08-16
| |
* | test: cleanupJustin M. Keyes2017-08-16
| |
* | win/pty: log errorserw72017-08-16
| |
* | win/test: tty-test: print screen size explicitly with CTRL-Qerw72017-08-16
| | | | | | | | | | tty-test.exe causes abnormal termination with low repeatability, try changing it so as not to use SIGWINCH.
* | win: support :terminalerw72017-08-16
| |
* | Merge #6364 'command-line color hook'Justin M. Keyes2017-08-16
|\ \ | |/ |/|
| * ex_getln: Make error messages look betterZyX2017-08-14
| |
| * functests: Alter commentZyX2017-08-14
| |
| * functests: Check that input is correctly silencedZyX2017-08-14
| |
| * Merge branch 'master' into colored-cmdlineZyX2017-08-06
| |\
| * | functests: Remove wait() from input_specZyX2017-08-06
| | |
| * | Merge branch 'master' into colored-cmdlineZyX2017-07-31
| |\ \
| * | | Revert "functests: Replace wait() with nvim_async"ZyX2017-07-27
| | | | | | | | | | | | | | | | | | | | | | | | This reverts commit e129607988b88719935bc4af517e7ee2689f5871. Tests stopped working in CI.
| * | | ex_getln: Cache highlight callback calling resultsZyX2017-07-26
| | | |
| * | | functests: Replace wait() with nvim_asyncZyX2017-07-26
| | | |
| * | | functests: Remove unneeded wait()sZyX2017-07-26
| | | |
| * | | functests: Add sleep to <C-c> testZyX2017-07-18
| | | |
| * | | functests: Test input() nesting supportZyX2017-07-18
| | | |
| * | | functests: Check for previously unchecked errorsZyX2017-07-18
| | | |
| * | | ex_getln: Check prev_prompt_errors before running redrawcmdlineZyX2017-07-18
| | | | | | | | | | | | | | | | Otherwise there will be infinite recursion and shortly a crash. Running redrawcmdline recursively occurs under color_cmdline_error label.
| * | | api helpers: Also save and restore did_emsgZyX2017-07-18
| | | |
| * | | ex_getln: Do not goto color_cmdline_end without first cleaning upZyX2017-07-17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The issue with debug mode was actually not cleaning up after `try_enter`: location `&tstate` was pointing to got invalidated and received some “garbage” (actually, values that got stored on the stack afterwards). But pointer to that garbage was still stored in `msg_list`, so next attempt to check it resulted in a crash.
| * | | Merge branch 'master' into colored-cmdlineZyX2017-07-15
| |\ \ \
| * | | | ex_getln: Save and restore try stateZyX2017-07-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: when processing cycle such as :for pat in [' \ze*', ' \zs*'] : try : let l = matchlist('x x', pat) : $put ='E888 NOT detected for ' . pat : catch : $put ='E888 detected for ' . pat : endtry :endfor `:let l = …` throwing an error causes this error to be caught after color_cmdline attempts to get callback for highlighting next line (the one with `$put = 'E888 NOT…`). Saving/restoring state prevents this from happening.
| * | | | ex_getln: Do not make <C-c> interrupt input() after interrupting hl cbZyX2017-06-28
| | | | |
| * | | | ex_getln: Fix “echoerr msg not shown” problemZyX2017-06-28
| | | | | | | | | | | | | | | | | | | | | | | | | This also attempted to fix problem with cancelling input() on error by avoiding standard error printing facilities (assumed thrown error message is the problem), but with no luck so far.
| * | | | functests: Uncomment `{REDRAW}` part of “works” testZyX2017-06-28
| | | | |
| * | | | functests: Partially uncomment <C-c> testZyX2017-06-28
| | | | |
| * | | | ex_getln: Call highlight callback inside :tryZyX2017-06-28
| | | | |