comparison src/channel.c @ 8382:3dbe93a240d8 v7.4.1483

commit https://github.com/vim/vim/commit/d6547fc6471d9084f942bdc4ae3aedb39361751d Author: Bram Moolenaar <Bram@vim.org> Date: Thu Mar 3 19:35:02 2016 +0100 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.
author Christian Brabandt <cb@256bit.org>
date Thu, 03 Mar 2016 19:45:05 +0100
parents 49d0e094cb93
children 3b9a306724ec
comparison
equal deleted inserted replaced
8381:74475e3eed32 8382:3dbe93a240d8
1388 ch_errors(channel, "Receved unknown command: %s", (char *)cmd); 1388 ch_errors(channel, "Receved unknown command: %s", (char *)cmd);
1389 EMSG2("E905: received unknown command: %s", cmd); 1389 EMSG2("E905: received unknown command: %s", cmd);
1390 } 1390 }
1391 } 1391 }
1392 1392
1393 static void
1394 invoke_one_time_callback(
1395 channel_T *channel,
1396 cbq_T *cbhead,
1397 cbq_T *item,
1398 typval_T *argv)
1399 {
1400 ch_logs(channel, "Invoking one-time callback %s",
1401 (char *)item->cq_callback);
1402 /* Remove the item from the list first, if the callback
1403 * invokes ch_close() the list will be cleared. */
1404 remove_cb_node(cbhead, item);
1405 invoke_callback(channel, item->cq_callback, argv);
1406 vim_free(item->cq_callback);
1407 vim_free(item);
1408 }
1409
1393 /* 1410 /*
1394 * Invoke a callback for "channel"/"part" if needed. 1411 * Invoke a callback for "channel"/"part" if needed.
1395 * Return TRUE when a message was handled, there might be another one. 1412 * Return TRUE when a message was handled, there might be another one.
1396 */ 1413 */
1397 static int 1414 static int
1400 char_u *msg = NULL; 1417 char_u *msg = NULL;
1401 typval_T *listtv = NULL; 1418 typval_T *listtv = NULL;
1402 typval_T argv[CH_JSON_MAX_ARGS]; 1419 typval_T argv[CH_JSON_MAX_ARGS];
1403 int seq_nr = -1; 1420 int seq_nr = -1;
1404 ch_mode_T ch_mode = channel->ch_part[part].ch_mode; 1421 ch_mode_T ch_mode = channel->ch_part[part].ch_mode;
1422 cbq_T *cbhead = &channel->ch_part[part].ch_cb_head;
1423 cbq_T *cbitem = cbhead->cq_next;
1405 char_u *callback = NULL; 1424 char_u *callback = NULL;
1406 buf_T *buffer = NULL; 1425 buf_T *buffer = NULL;
1407 1426
1408 if (channel->ch_nb_close_cb != NULL) 1427 if (channel->ch_nb_close_cb != NULL)
1409 /* this channel is handled elsewhere (netbeans) */ 1428 /* this channel is handled elsewhere (netbeans) */
1410 return FALSE; 1429 return FALSE;
1411 1430
1412 if (channel->ch_part[part].ch_callback != NULL) 1431 /* use a message-specific callback, part callback or channel callback */
1432 if (cbitem != NULL)
1433 callback = cbitem->cq_callback;
1434 else if (channel->ch_part[part].ch_callback != NULL)
1413 callback = channel->ch_part[part].ch_callback; 1435 callback = channel->ch_part[part].ch_callback;
1414 else 1436 else
1415 callback = channel->ch_callback; 1437 callback = channel->ch_callback;
1416 1438
1417 buffer = channel->ch_part[part].ch_buffer; 1439 buffer = channel->ch_part[part].ch_buffer;
1523 argv[1].vval.v_string = msg; 1545 argv[1].vval.v_string = msg;
1524 } 1546 }
1525 1547
1526 if (seq_nr > 0) 1548 if (seq_nr > 0)
1527 { 1549 {
1528 cbq_T *head = &channel->ch_part[part].ch_cb_head;
1529 cbq_T *item = head->cq_next;
1530 int done = FALSE; 1550 int done = FALSE;
1531 1551
1532 /* invoke the one-time callback with the matching nr */ 1552 /* invoke the one-time callback with the matching nr */
1533 while (item != NULL) 1553 while (cbitem != NULL)
1534 { 1554 {
1535 if (item->cq_seq_nr == seq_nr) 1555 if (cbitem->cq_seq_nr == seq_nr)
1536 { 1556 {
1537 ch_logs(channel, "Invoking one-time callback %s", 1557 invoke_one_time_callback(channel, cbhead, cbitem, argv);
1538 (char *)item->cq_callback);
1539 /* Remove the item from the list first, if the callback
1540 * invokes ch_close() the list will be cleared. */
1541 remove_cb_node(head, item);
1542 invoke_callback(channel, item->cq_callback, argv);
1543 vim_free(item->cq_callback);
1544 vim_free(item);
1545 done = TRUE; 1558 done = TRUE;
1546 break; 1559 break;
1547 } 1560 }
1548 item = item->cq_next; 1561 cbitem = cbitem->cq_next;
1549 } 1562 }
1550 if (!done) 1563 if (!done)
1551 ch_logn(channel, "Dropping message %d without callback", seq_nr); 1564 ch_logn(channel, "Dropping message %d without callback", seq_nr);
1552 } 1565 }
1553 else if (callback != NULL || buffer != NULL) 1566 else if (callback != NULL || buffer != NULL)
1597 redraw_buf_later(buffer, VALID); 1610 redraw_buf_later(buffer, VALID);
1598 channel_need_redraw = TRUE; 1611 channel_need_redraw = TRUE;
1599 } 1612 }
1600 } 1613 }
1601 } 1614 }
1615
1602 if (callback != NULL) 1616 if (callback != NULL)
1603 { 1617 {
1604 /* invoke the channel callback */ 1618 if (cbitem != NULL)
1605 ch_logs(channel, "Invoking channel callback %s", (char *)callback); 1619 invoke_one_time_callback(channel, cbhead, cbitem, argv);
1606 invoke_callback(channel, callback, argv); 1620 else
1621 {
1622 /* invoke the channel callback */
1623 ch_logs(channel, "Invoking channel callback %s",
1624 (char *)callback);
1625 invoke_callback(channel, callback, argv);
1626 }
1607 } 1627 }
1608 } 1628 }
1609 else 1629 else
1610 ch_log(channel, "Dropping message"); 1630 ch_log(channel, "Dropping message");
1611 1631