Skip to content

Commit e56bf15

Browse files
committed
patch 7.4.1293
Problem: Sometimes a channel may hang waiting for a message that was already discarded. (Ken Takata) Solution: Store the ID of the message blocking on in the channel.
1 parent 2fc83fc commit e56bf15

2 files changed

Lines changed: 20 additions & 8 deletions

File tree

src/channel.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ typedef struct {
116116

117117
void (*ch_close_cb)(void); /* callback for when channel is closed */
118118

119+
int ch_block_id; /* ID that channel_read_json_block() is
120+
waiting for */
119121
char_u *ch_callback; /* function to call when a msg is not handled */
120122
cbq_T ch_cb_head; /* dummy node for pre-request callbacks */
121123

@@ -765,23 +767,26 @@ remove_json_node(jsonq_T *node)
765767
/*
766768
* Get a message from the JSON queue for channel "ch_idx".
767769
* When "id" is positive it must match the first number in the list.
768-
* When "id" is zero or negative jut get the first message.
770+
* When "id" is zero or negative jut get the first message. But not the one
771+
* with id ch_block_id.
769772
* Return OK when found and return the value in "rettv".
770773
* Return FAIL otherwise.
771774
*/
772775
static int
773776
channel_get_json(int ch_idx, int id, typval_T **rettv)
774777
{
775-
jsonq_T *head = &channels[ch_idx].ch_json_head;
776-
jsonq_T *item = head->next;
778+
channel_T *channel = &channels[ch_idx];
779+
jsonq_T *head = &channel->ch_json_head;
780+
jsonq_T *item = head->next;
777781

778782
while (item != head)
779783
{
780784
list_T *l = item->value->vval.v_list;
781785
typval_T *tv = &l->lv_first->li_tv;
782786

783787
if ((id > 0 && tv->v_type == VAR_NUMBER && tv->vval.v_number == id)
784-
|| id <= 0)
788+
|| (id <= 0 && (tv->v_type != VAR_NUMBER
789+
|| tv->vval.v_number != channel->ch_block_id)))
785790
{
786791
*rettv = item->value;
787792
remove_json_node(item);
@@ -1291,15 +1296,20 @@ channel_read_block(int idx)
12911296
int
12921297
channel_read_json_block(int ch_idx, int id, typval_T **rettv)
12931298
{
1294-
int more;
1299+
int more;
1300+
channel_T *channel = &channels[ch_idx];
12951301

1302+
channel->ch_block_id = id;
12961303
for (;;)
12971304
{
12981305
more = channel_parse_json(ch_idx);
12991306

13001307
/* search for messsage "id" */
13011308
if (channel_get_json(ch_idx, id, rettv) == OK)
1309+
{
1310+
channel->ch_block_id = 0;
13021311
return OK;
1312+
}
13031313

13041314
if (!more)
13051315
{
@@ -1309,13 +1319,13 @@ channel_read_json_block(int ch_idx, int id, typval_T **rettv)
13091319
continue;
13101320

13111321
/* Wait for up to the channel timeout. */
1312-
if (channels[ch_idx].ch_fd < 0
1313-
|| channel_wait(channels[ch_idx].ch_fd,
1314-
channels[ch_idx].ch_timeout) == FAIL)
1322+
if (channel->ch_fd < 0 || channel_wait(channel->ch_fd,
1323+
channel->ch_timeout) == FAIL)
13151324
break;
13161325
channel_read(ch_idx);
13171326
}
13181327
}
1328+
channel->ch_block_id = 0;
13191329
return FAIL;
13201330
}
13211331

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,8 @@ static char *(features[]) =
747747

748748
static int included_patches[] =
749749
{ /* Add new patch number below this line */
750+
/**/
751+
1293,
750752
/**/
751753
1292,
752754
/**/

0 commit comments

Comments
 (0)