]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 7.4.1493 v7.4.1493
authorBram Moolenaar <Bram@vim.org>
Sat, 5 Mar 2016 19:54:36 +0000 (20:54 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 5 Mar 2016 19:54:36 +0000 (20:54 +0100)
Problem:    Wrong callback invoked for zero-id messages.
Solution:   Don't use the first one-time callback when the sequence number
            doesn't match.

src/channel.c
src/testdir/test_channel.py
src/testdir/test_channel.vim
src/version.c

index 74cbd14d8b0881cbdfa3433dcbe06cf2cdd30471..da13f962c4093963fae2f813493d93a154d56d32 100644 (file)
@@ -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);
     }
index 02e6ba3ecdd3af4a2c38ea115549ed3f61d72932..a465d65d2fad853fe1b146c4caa1a70a3c13ba80 100644 (file)
@@ -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()
index faa89f3e84bcdd1ebe952a9267dfbf5b342e69a7..3bdfd4cbf8cdc8a298b55db7c617788fa1cc5eb9 100644 (file)
@@ -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
index 51c2b810eb7765ff9a1d1a1b577d9abdb5164f4a..fe5d00edadf212b1b62bfa94f4b33f982c35a80f 100644 (file)
@@ -743,6 +743,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1493,
 /**/
     1492,
 /**/