Patch 7.4.1483
Problem:    A one-time callback is not used for a raw channel.
Solution:   Use a one-time callback when it exists.
Files:      src/channel.c, src/testdir/test_channel.vim,
            src/testdir/test_channel.py


*** ../vim-7.4.1482/src/channel.c       2016-03-02 21:16:56.025809799 +0100
--- src/channel.c       2016-03-03 18:49:48.409042489 +0100
***************
*** 1390,1395 ****
--- 1390,1412 ----
      }
  }
  
+     static void
+ invoke_one_time_callback(
+       channel_T   *channel,
+       cbq_T       *cbhead,
+       cbq_T       *item,
+       typval_T    *argv)
+ {
+     ch_logs(channel, "Invoking one-time callback %s",
+                                                  (char *)item->cq_callback);
+     /* Remove the item from the list first, if the callback
+      * invokes ch_close() the list will be cleared. */
+     remove_cb_node(cbhead, item);
+     invoke_callback(channel, item->cq_callback, argv);
+     vim_free(item->cq_callback);
+     vim_free(item);
+ }
+ 
  /*
   * Invoke a callback for "channel"/"part" if needed.
   * Return TRUE when a message was handled, there might be another one.
***************
*** 1402,1407 ****
--- 1419,1426 ----
      typval_T  argv[CH_JSON_MAX_ARGS];
      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;
      char_u    *callback = NULL;
      buf_T     *buffer = NULL;
  
***************
*** 1409,1415 ****
        /* this channel is handled elsewhere (netbeans) */
        return FALSE;
  
!     if (channel->ch_part[part].ch_callback != NULL)
        callback = channel->ch_part[part].ch_callback;
      else
        callback = channel->ch_callback;
--- 1428,1437 ----
        /* this channel is handled elsewhere (netbeans) */
        return FALSE;
  
!     /* use a message-specific callback, part callback or channel callback */
!     if (cbitem != NULL)
!       callback = cbitem->cq_callback;
!     else if (channel->ch_part[part].ch_callback != NULL)
        callback = channel->ch_part[part].ch_callback;
      else
        callback = channel->ch_callback;
***************
*** 1525,1551 ****
  
      if (seq_nr > 0)
      {
-       cbq_T   *head = &channel->ch_part[part].ch_cb_head;
-       cbq_T   *item = head->cq_next;
        int     done = FALSE;
  
        /* invoke the one-time callback with the matching nr */
!       while (item != NULL)
        {
!           if (item->cq_seq_nr == seq_nr)
            {
!               ch_logs(channel, "Invoking one-time callback %s",
!                                                  (char *)item->cq_callback);
!               /* Remove the item from the list first, if the callback
!                * invokes ch_close() the list will be cleared. */
!               remove_cb_node(head, item);
!               invoke_callback(channel, item->cq_callback, argv);
!               vim_free(item->cq_callback);
!               vim_free(item);
                done = TRUE;
                break;
            }
!           item = item->cq_next;
        }
        if (!done)
            ch_logn(channel, "Dropping message %d without callback", seq_nr);
--- 1547,1564 ----
  
      if (seq_nr > 0)
      {
        int     done = FALSE;
  
        /* invoke the one-time callback with the matching nr */
!       while (cbitem != NULL)
        {
!           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);
***************
*** 1599,1609 ****
                }
            }
        }
        if (callback != NULL)
        {
!           /* invoke the channel callback */
!           ch_logs(channel, "Invoking channel callback %s", (char *)callback);
!           invoke_callback(channel, callback, argv);
        }
      }
      else
--- 1612,1629 ----
                }
            }
        }
+ 
        if (callback != NULL)
        {
!           if (cbitem != NULL)
!               invoke_one_time_callback(channel, cbhead, cbitem, argv);
!           else
!           {
!               /* invoke the channel callback */
!               ch_logs(channel, "Invoking channel callback %s",
!                                                           (char *)callback);
!               invoke_callback(channel, callback, argv);
!           }
        }
      }
      else
*** ../vim-7.4.1482/src/testdir/test_channel.vim        2016-03-03 
18:09:06.013997633 +0100
--- src/testdir/test_channel.vim        2016-03-03 19:21:06.045874189 +0100
***************
*** 257,262 ****
--- 257,264 ----
    call s:run_server('s:server_crash')
  endfunc
  
+ """""""""
+ 
  let s:reply = ""
  func s:Handler(chan, msg)
    unlet s:reply
***************
*** 290,295 ****
--- 292,352 ----
    unlet s:chopt.callback
  endfunc
  
+ """""""""
+ 
+ let s:reply1 = ""
+ func s:HandleRaw1(chan, msg)
+   unlet s:reply1
+   let s:reply1 = a:msg
+ endfunc
+ 
+ let s:reply2 = ""
+ func s:HandleRaw2(chan, msg)
+   unlet s:reply2
+   let s:reply2 = a:msg
+ endfunc
+ 
+ let s:reply3 = ""
+ func s:HandleRaw3(chan, msg)
+   unlet s:reply3
+   let s:reply3 = a:msg
+ endfunc
+ 
+ func s:raw_one_time_callback(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
+   call ch_setoptions(handle, {'mode': 'raw'})
+ 
+   " The message are sent raw, we do our own JSON strings here.
+   call ch_sendraw(handle, "[1, \"hello!\"]", {'callback': 's:HandleRaw1'})
+   sleep 10m
+   call assert_equal("[1, \"got it\"]", s:reply1)
+   call ch_sendraw(handle, "[2, \"echo something\"]", {'callback': 
's:HandleRaw2'})
+   call ch_sendraw(handle, "[3, \"wait a bit\"]", {'callback': 's:HandleRaw3'})
+   sleep 10m
+   call assert_equal("[2, \"something\"]", s:reply2)
+   " wait for up to 500 msec for the 200 msec delayed reply
+   for i in range(50)
+     sleep 10m
+     if s:reply3 != ''
+       break
+     endif
+   endfor
+   call assert_equal("[3, \"waited\"]", s:reply3)
+ endfunc
+ 
+ func Test_raw_one_time_callback()
+   call ch_logfile('channellog', 'w')
+   call ch_log('Test_raw_one_time_callback()')
+   call s:run_server('s:raw_one_time_callback')
+   call ch_logfile('')
+ endfunc
+ 
+ """""""""
+ 
  " Test that trying to connect to a non-existing port fails quickly.
  func Test_connect_waittime()
    call ch_log('Test_connect_waittime()')
***************
*** 325,330 ****
--- 382,389 ----
    endtry
  endfunc
  
+ """""""""
+ 
  func Test_raw_pipe()
    if !has('job')
      return
*** ../vim-7.4.1482/src/testdir/test_channel.py 2016-02-23 13:20:18.466462173 
+0100
--- src/testdir/test_channel.py 2016-03-03 19:19:11.183057626 +0100
***************
*** 62,67 ****
--- 62,70 ----
                      if decoded[1] == 'hello!':
                          # simply send back a string
                          response = "got it"
+                     elif decoded[1].startswith("echo "):
+                         # send back the argument
+                         response = decoded[1][5:]
                      elif decoded[1] == 'make change':
                          # Send two ex commands at the same time, before
                          # replying to the request.
*** ../vim-7.4.1482/src/version.c       2016-03-03 18:09:06.013997633 +0100
--- src/version.c       2016-03-03 18:48:10.190033280 +0100
***************
*** 745,746 ****
--- 745,748 ----
  {   /* Add new patch number below this line */
+ /**/
+     1483,
  /**/

-- 
   A village.  Sound of chanting of Latin canon, punctuated by short, sharp
   cracks.  It comes nearer.  We see it is a line of MONKS ala SEVENTH SEAL
   flagellation scene, chanting and banging themselves on the foreheads with
   wooden boards.
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui