comparison src/channel.c @ 18098:a2870e6f5b45 v8.1.2044

patch 8.1.2044: no easy way to process postponed work Commit: https://github.com/vim/vim/commit/8aeec40207b5adcd3a155277dc4f29189343b963 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Sep 15 23:02:04 2019 +0200 patch 8.1.2044: no easy way to process postponed work Problem: No easy way to process postponed work. (Paul Jolly) Solution: Add the SafeState autocommand event.
author Bram Moolenaar <Bram@vim.org>
date Sun, 15 Sep 2019 23:15:03 +0200
parents cf8e0c7e0cb9
children 0d9ec3a2821f
comparison
equal deleted inserted replaced
18097:1608410ff8f3 18098:a2870e6f5b45
3587 { 3587 {
3588 int more; 3588 int more;
3589 sock_T fd; 3589 sock_T fd;
3590 int timeout; 3590 int timeout;
3591 chanpart_T *chanpart = &channel->ch_part[part]; 3591 chanpart_T *chanpart = &channel->ch_part[part];
3592 int retval = FAIL;
3592 3593
3593 ch_log(channel, "Blocking read JSON for id %d", id); 3594 ch_log(channel, "Blocking read JSON for id %d", id);
3595
3596 // Not considered a safe state here, since we are processing a JSON message
3597 // and parsing other messages while waiting.
3598 enter_unsafe_state();
3599
3594 if (id >= 0) 3600 if (id >= 0)
3595 channel_add_block_id(chanpart, id); 3601 channel_add_block_id(chanpart, id);
3602
3596 for (;;) 3603 for (;;)
3597 { 3604 {
3598 more = channel_parse_json(channel, part); 3605 more = channel_parse_json(channel, part);
3599 3606
3600 // search for message "id" 3607 // search for message "id"
3601 if (channel_get_json(channel, part, id, TRUE, rettv) == OK) 3608 if (channel_get_json(channel, part, id, TRUE, rettv) == OK)
3602 { 3609 {
3603 if (id >= 0)
3604 channel_remove_block_id(chanpart, id);
3605 ch_log(channel, "Received JSON for id %d", id); 3610 ch_log(channel, "Received JSON for id %d", id);
3606 return OK; 3611 retval = OK;
3612 break;
3607 } 3613 }
3608 3614
3609 if (!more) 3615 if (!more)
3610 { 3616 {
3611 /* Handle any other messages in the queue. If done some more 3617 /* Handle any other messages in the queue. If done some more
3657 channel_read(channel, part, "channel_read_json_block"); 3663 channel_read(channel, part, "channel_read_json_block");
3658 } 3664 }
3659 } 3665 }
3660 if (id >= 0) 3666 if (id >= 0)
3661 channel_remove_block_id(chanpart, id); 3667 channel_remove_block_id(chanpart, id);
3662 return FAIL; 3668
3669 // This may trigger a SafeState autocommand.
3670 leave_unsafe_state();
3671
3672 return retval;
3663 } 3673 }
3664 3674
3665 /* 3675 /*
3666 * Get the channel from the argument. 3676 * Get the channel from the argument.
3667 * Returns NULL if the handle is invalid. 3677 * Returns NULL if the handle is invalid.
4193 timeout, TRUE, NULL); 4203 timeout, TRUE, NULL);
4194 } 4204 }
4195 free_job_options(&opt); 4205 free_job_options(&opt);
4196 } 4206 }
4197 4207
4198 # define KEEP_OPEN_TIME 20 /* msec */ 4208 #define KEEP_OPEN_TIME 20 /* msec */
4199 4209
4200 # if (defined(UNIX) && !defined(HAVE_SELECT)) || defined(PROTO) 4210 #if (defined(UNIX) && !defined(HAVE_SELECT)) || defined(PROTO)
4201 /* 4211 /*
4202 * Add open channels to the poll struct. 4212 * Add open channels to the poll struct.
4203 * Return the adjusted struct index. 4213 * Return the adjusted struct index.
4204 * The type of "fds" is hidden to avoid problems with the function proto. 4214 * The type of "fds" is hidden to avoid problems with the function proto.
4205 */ 4215 */
4286 } 4296 }
4287 } 4297 }
4288 4298
4289 return ret; 4299 return ret;
4290 } 4300 }
4291 # endif /* UNIX && !HAVE_SELECT */ 4301 #endif /* UNIX && !HAVE_SELECT */
4292 4302
4293 # if (!defined(MSWIN) && defined(HAVE_SELECT)) || defined(PROTO) 4303 #if (!defined(MSWIN) && defined(HAVE_SELECT)) || defined(PROTO)
4294 4304
4295 /* 4305 /*
4296 * The "fd_set" type is hidden to avoid problems with the function proto. 4306 * The "fd_set" type is hidden to avoid problems with the function proto.
4297 */ 4307 */
4298 int 4308 int
4379 4389
4380 in_part = &channel->ch_part[PART_IN]; 4390 in_part = &channel->ch_part[PART_IN];
4381 if (ret > 0 && in_part->ch_fd != INVALID_FD 4391 if (ret > 0 && in_part->ch_fd != INVALID_FD
4382 && FD_ISSET(in_part->ch_fd, wfds)) 4392 && FD_ISSET(in_part->ch_fd, wfds))
4383 { 4393 {
4384 /* Clear the flag first, ch_fd may change in channel_write_input(). */ 4394 // Clear the flag first, ch_fd may change in channel_write_input().
4385 FD_CLR(in_part->ch_fd, wfds); 4395 FD_CLR(in_part->ch_fd, wfds);
4386 channel_write_input(channel); 4396 channel_write_input(channel);
4387 --ret; 4397 --ret;
4388 } 4398 }
4389 } 4399 }
4390 4400
4391 return ret; 4401 return ret;
4392 } 4402 }
4393 # endif /* !MSWIN && HAVE_SELECT */ 4403 #endif // !MSWIN && HAVE_SELECT
4394 4404
4395 /* 4405 /*
4396 * Execute queued up commands. 4406 * Execute queued up commands.
4397 * Invoked from the main loop when it's safe to execute received commands. 4407 * Invoked from the main loop when it's safe to execute received commands,
4408 * and during a blocking wait for ch_evalexpr().
4398 * Return TRUE when something was done. 4409 * Return TRUE when something was done.
4399 */ 4410 */
4400 int 4411 int
4401 channel_parse_messages(void) 4412 channel_parse_messages(void)
4402 { 4413 {