diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-03-05 20:54:36 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-03-05 20:54:36 +0100 |
commit | 5983ad0b038fa689653246cb304fd43e8ae39a78 (patch) | |
tree | a1065749450fdcfa5490cd0ad683a7ee33f9a6ed | |
parent | 35ca0e7a1cb6e6daef8e0052a8437801226cef19 (diff) | |
download | vim-git-5983ad0b038fa689653246cb304fd43e8ae39a78.tar.gz |
patch 7.4.1493v7.4.1493
Problem: Wrong callback invoked for zero-id messages.
Solution: Don't use the first one-time callback when the sequence number
doesn't match.
-rw-r--r-- | src/channel.c | 12 | ||||
-rw-r--r-- | src/testdir/test_channel.py | 5 | ||||
-rw-r--r-- | src/testdir/test_channel.vim | 66 | ||||
-rw-r--r-- | src/version.c | 2 |
4 files changed, 79 insertions, 6 deletions
diff --git a/src/channel.c b/src/channel.c index 74cbd14d8..da13f962c 100644 --- a/src/channel.c +++ b/src/channel.c @@ -1480,7 +1480,7 @@ may_invoke_callback(channel_T *channel, int part) int seq_nr = -1; ch_mode_T ch_mode = channel->ch_part[part].ch_mode; cbq_T *cbhead = &channel->ch_part[part].ch_cb_head; - cbq_T *cbitem = cbhead->cq_next; + cbq_T *cbitem; char_u *callback = NULL; buf_T *buffer = NULL; @@ -1488,7 +1488,10 @@ may_invoke_callback(channel_T *channel, int part) /* this channel is handled elsewhere (netbeans) */ return FALSE; - /* use a message-specific callback, part callback or channel callback */ + /* Use a message-specific callback, part callback or channel callback */ + for (cbitem = cbhead->cq_next; cbitem != NULL; cbitem = cbitem->cq_next) + if (cbitem->cq_seq_nr == 0) + break; if (cbitem != NULL) callback = cbitem->cq_callback; else if (channel->ch_part[part].ch_callback != NULL) @@ -1610,16 +1613,13 @@ may_invoke_callback(channel_T *channel, int part) int done = FALSE; /* invoke the one-time callback with the matching nr */ - while (cbitem != NULL) - { + for (cbitem = cbhead->cq_next; cbitem != NULL; cbitem = cbitem->cq_next) if (cbitem->cq_seq_nr == seq_nr) { invoke_one_time_callback(channel, cbhead, cbitem, argv); done = TRUE; break; } - cbitem = cbitem->cq_next; - } if (!done) ch_logn(channel, "Dropping message %d without callback", seq_nr); } diff --git a/src/testdir/test_channel.py b/src/testdir/test_channel.py index 02e6ba3ec..a465d65d2 100644 --- a/src/testdir/test_channel.py +++ b/src/testdir/test_channel.py @@ -143,6 +143,11 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler): print("sending: {}".format(cmd)) self.request.sendall(cmd.encode('utf-8')) response = "" + elif decoded[1] == 'send zero': + cmd = '[0,"zero index"]' + print("sending: {}".format(cmd)) + self.request.sendall(cmd.encode('utf-8')) + response = "sent zero" elif decoded[1] == 'close me': print("closing") self.request.close() diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index faa89f3e8..3bdfd4cbf 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -294,6 +294,72 @@ endfunc """"""""" +let s:ch_reply = '' +func s:ChHandler(chan, msg) + unlet s:ch_reply + let s:ch_reply = a:msg +endfunc + +let s:zero_reply = '' +func s:OneHandler(chan, msg) + unlet s:zero_reply + let s:zero_reply = a:msg +endfunc + +func s:channel_zero(port) + let handle = ch_open('localhost:' . a:port, s:chopt) + if ch_status(handle) == "fail" + call assert_false(1, "Can't open channel") + return + endif + + " Check that eval works. + call assert_equal('got it', ch_evalexpr(handle, 'hello!')) + + " Check that eval works if a zero id message is sent back. + let s:ch_reply = '' + call assert_equal('sent zero', ch_evalexpr(handle, 'send zero')) + sleep 10m + if s:has_handler + call assert_equal('zero index', s:ch_reply) + else + call assert_equal('', s:ch_reply) + endif + + " Check that handler works if a zero id message is sent back. + let s:ch_reply = '' + let s:zero_reply = '' + call ch_sendexpr(handle, 'send zero', {'callback': 's:OneHandler'}) + " Somehow the second message takes a bit of time. + for i in range(50) + if s:zero_reply == 'sent zero' + break + endif + sleep 10m + endfor + if s:has_handler + call assert_equal('zero index', s:ch_reply) + else + call assert_equal('', s:ch_reply) + endif + call assert_equal('sent zero', s:zero_reply) +endfunc + +func Test_zero_reply() + call ch_log('Test_zero_reply()') + " Run with channel handler + let s:has_handler = 1 + let s:chopt.callback = 's:ChHandler' + call s:run_server('s:channel_zero') + unlet s:chopt.callback + + " Run without channel handler + let s:has_handler = 0 + call s:run_server('s:channel_zero') +endfunc + +""""""""" + let s:reply1 = "" func s:HandleRaw1(chan, msg) unlet s:reply1 diff --git a/src/version.c b/src/version.c index 51c2b810e..fe5d00eda 100644 --- a/src/version.c +++ b/src/version.c @@ -744,6 +744,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1493, +/**/ 1492, /**/ 1491, |