Mercurial > vim
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 |