comparison src/channel.c @ 9083:69bb7b230094 v7.4.1826

commit https://github.com/vim/vim/commit/cf7ff70ca73218d618e7c00ab785bcf5f9120a94 Author: Bram Moolenaar <Bram@vim.org> Date: Mon May 9 17:20:14 2016 +0200 patch 7.4.1826 Problem: Callbacks are invoked when it's not safe. (Andrew Stewart) Solution: When a channel is to be closed don't invoke callbacks right away, wait for a safe moment.
author Christian Brabandt <cb@256bit.org>
date Mon, 09 May 2016 17:30:06 +0200
parents b2b915c1d311
children d362e6df1deb
comparison
equal deleted inserted replaced
9082:ed95e35d74bd 9083:69bb7b230094
2780 2780
2781 static void 2781 static void
2782 channel_close_on_error(channel_T *channel, char *func) 2782 channel_close_on_error(channel_T *channel, char *func)
2783 { 2783 {
2784 /* Do not call emsg(), most likely the other end just exited. */ 2784 /* Do not call emsg(), most likely the other end just exited. */
2785 ch_errors(channel, "%s(): Cannot read from channel", func); 2785 ch_errors(channel, "%s(): Cannot read from channel, will close it soon",
2786 func);
2786 2787
2787 /* Queue a "DETACH" netbeans message in the command queue in order to 2788 /* Queue a "DETACH" netbeans message in the command queue in order to
2788 * terminate the netbeans session later. Do not end the session here 2789 * terminate the netbeans session later. Do not end the session here
2789 * directly as we may be running in the context of a call to 2790 * directly as we may be running in the context of a call to
2790 * netbeans_parse_messages(): 2791 * netbeans_parse_messages():
2798 if (channel->ch_nb_close_cb != NULL) 2799 if (channel->ch_nb_close_cb != NULL)
2799 channel_save(channel, PART_OUT, (char_u *)DETACH_MSG_RAW, 2800 channel_save(channel, PART_OUT, (char_u *)DETACH_MSG_RAW,
2800 (int)STRLEN(DETACH_MSG_RAW), FALSE, "PUT "); 2801 (int)STRLEN(DETACH_MSG_RAW), FALSE, "PUT ");
2801 2802
2802 /* When reading from stdout is not possible, assume the other side has 2803 /* When reading from stdout is not possible, assume the other side has
2803 * died. */ 2804 * died. Don't close the channel right away, it may be the wrong moment
2805 * to invoke callbacks. */
2806 channel->ch_to_be_closed = TRUE;
2807 }
2808
2809 static void
2810 channel_close_now(channel_T *channel)
2811 {
2812 ch_log(channel, "Closing channel because of previous read error");
2804 channel_close(channel, TRUE); 2813 channel_close(channel, TRUE);
2805 if (channel->ch_nb_close_cb != NULL) 2814 if (channel->ch_nb_close_cb != NULL)
2806 (*channel->ch_nb_close_cb)(); 2815 (*channel->ch_nb_close_cb)();
2807 } 2816 }
2808 2817
3513 ch_log(NULL, "looking for messages on channels"); 3522 ch_log(NULL, "looking for messages on channels");
3514 did_log_msg = FALSE; 3523 did_log_msg = FALSE;
3515 } 3524 }
3516 while (channel != NULL) 3525 while (channel != NULL)
3517 { 3526 {
3527 if (channel->ch_to_be_closed)
3528 {
3529 channel->ch_to_be_closed = FALSE;
3530 channel_close_now(channel);
3531 /* channel may have been freed, start over */
3532 channel = first_channel;
3533 continue;
3534 }
3518 if (channel->ch_refcount == 0 && !channel_still_useful(channel)) 3535 if (channel->ch_refcount == 0 && !channel_still_useful(channel))
3519 { 3536 {
3520 /* channel is no longer useful, free it */ 3537 /* channel is no longer useful, free it */
3521 channel_free(channel); 3538 channel_free(channel);
3522 channel = first_channel; 3539 channel = first_channel;