comparison src/channel.c @ 7997:c1c9ab17e197 v7.4.1293

commit https://github.com/vim/vim/commit/e56bf15c163a921ce9e1c09c0d5b3a03efc63324 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Feb 8 23:23:42 2016 +0100 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.
author Christian Brabandt <cb@256bit.org>
date Mon, 08 Feb 2016 23:30:05 +0100
parents d3fed9a639db
children b2cfa3416ba0
comparison
equal deleted inserted replaced
7996:996b03ef584a 7997:c1c9ab17e197
114 int ch_inputHandler; /* simply ret.value of WSAAsyncSelect() */ 114 int ch_inputHandler; /* simply ret.value of WSAAsyncSelect() */
115 #endif 115 #endif
116 116
117 void (*ch_close_cb)(void); /* callback for when channel is closed */ 117 void (*ch_close_cb)(void); /* callback for when channel is closed */
118 118
119 int ch_block_id; /* ID that channel_read_json_block() is
120 waiting for */
119 char_u *ch_callback; /* function to call when a msg is not handled */ 121 char_u *ch_callback; /* function to call when a msg is not handled */
120 cbq_T ch_cb_head; /* dummy node for pre-request callbacks */ 122 cbq_T ch_cb_head; /* dummy node for pre-request callbacks */
121 123
122 ch_mode_T ch_mode; 124 ch_mode_T ch_mode;
123 jsonq_T ch_json_head; /* dummy node, header for circular queue */ 125 jsonq_T ch_json_head; /* dummy node, header for circular queue */
763 } 765 }
764 766
765 /* 767 /*
766 * Get a message from the JSON queue for channel "ch_idx". 768 * Get a message from the JSON queue for channel "ch_idx".
767 * When "id" is positive it must match the first number in the list. 769 * 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.
769 * Return OK when found and return the value in "rettv". 772 * Return OK when found and return the value in "rettv".
770 * Return FAIL otherwise. 773 * Return FAIL otherwise.
771 */ 774 */
772 static int 775 static int
773 channel_get_json(int ch_idx, int id, typval_T **rettv) 776 channel_get_json(int ch_idx, int id, typval_T **rettv)
774 { 777 {
775 jsonq_T *head = &channels[ch_idx].ch_json_head; 778 channel_T *channel = &channels[ch_idx];
776 jsonq_T *item = head->next; 779 jsonq_T *head = &channel->ch_json_head;
780 jsonq_T *item = head->next;
777 781
778 while (item != head) 782 while (item != head)
779 { 783 {
780 list_T *l = item->value->vval.v_list; 784 list_T *l = item->value->vval.v_list;
781 typval_T *tv = &l->lv_first->li_tv; 785 typval_T *tv = &l->lv_first->li_tv;
782 786
783 if ((id > 0 && tv->v_type == VAR_NUMBER && tv->vval.v_number == id) 787 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)))
785 { 790 {
786 *rettv = item->value; 791 *rettv = item->value;
787 remove_json_node(item); 792 remove_json_node(item);
788 return OK; 793 return OK;
789 } 794 }
1289 * Blocks until the message is received or the timeout is reached. 1294 * Blocks until the message is received or the timeout is reached.
1290 */ 1295 */
1291 int 1296 int
1292 channel_read_json_block(int ch_idx, int id, typval_T **rettv) 1297 channel_read_json_block(int ch_idx, int id, typval_T **rettv)
1293 { 1298 {
1294 int more; 1299 int more;
1295 1300 channel_T *channel = &channels[ch_idx];
1301
1302 channel->ch_block_id = id;
1296 for (;;) 1303 for (;;)
1297 { 1304 {
1298 more = channel_parse_json(ch_idx); 1305 more = channel_parse_json(ch_idx);
1299 1306
1300 /* search for messsage "id" */ 1307 /* search for messsage "id" */
1301 if (channel_get_json(ch_idx, id, rettv) == OK) 1308 if (channel_get_json(ch_idx, id, rettv) == OK)
1309 {
1310 channel->ch_block_id = 0;
1302 return OK; 1311 return OK;
1312 }
1303 1313
1304 if (!more) 1314 if (!more)
1305 { 1315 {
1306 /* Handle any other messages in the queue. If done some more 1316 /* Handle any other messages in the queue. If done some more
1307 * messages may have arrived. */ 1317 * messages may have arrived. */
1308 if (channel_parse_messages()) 1318 if (channel_parse_messages())
1309 continue; 1319 continue;
1310 1320
1311 /* Wait for up to the channel timeout. */ 1321 /* Wait for up to the channel timeout. */
1312 if (channels[ch_idx].ch_fd < 0 1322 if (channel->ch_fd < 0 || channel_wait(channel->ch_fd,
1313 || channel_wait(channels[ch_idx].ch_fd, 1323 channel->ch_timeout) == FAIL)
1314 channels[ch_idx].ch_timeout) == FAIL)
1315 break; 1324 break;
1316 channel_read(ch_idx); 1325 channel_read(ch_idx);
1317 } 1326 }
1318 } 1327 }
1328 channel->ch_block_id = 0;
1319 return FAIL; 1329 return FAIL;
1320 } 1330 }
1321 1331
1322 # if defined(WIN32) || defined(PROTO) 1332 # if defined(WIN32) || defined(PROTO)
1323 /* 1333 /*