To: vim_dev@googlegroups.com Subject: Patch 7.4.1319 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1319 (after 7.4.1318) Problem: Tests fail on MS-Windows and on Unix with GUI. Solution: Fix unregistering. Files: src/structs.h, src/channel.c, src/os_unix.c, src/os_win32.c, src/proto/channel.pro *** ../vim-7.4.1318/src/structs.h 2016-02-14 19:13:37.314808670 +0100 --- src/structs.h 2016-02-14 21:48:58.429255434 +0100 *************** *** 1301,1308 **** MODE_JS } ch_mode_T; ! /* Ordering matters: IN is last, only SOCK/OUT/ERR are polled */ ! #define CHAN_SOCK 0 #define CH_SOCK ch_pfd[CHAN_SOCK].ch_fd --- 1301,1308 ---- MODE_JS } ch_mode_T; ! /* Ordering matters, it is used in for loops: IN is last, only SOCK/OUT/ERR ! * are polled. */ #define CHAN_SOCK 0 #define CH_SOCK ch_pfd[CHAN_SOCK].ch_fd *************** *** 1342,1348 **** int ch_id; /* ID of the channel */ ! chan_fd_T ch_pfd[4]; /* info for socket, in, out and err */ readq_T ch_head; /* dummy node, header for circular queue */ --- 1342,1348 ---- int ch_id; /* ID of the channel */ ! chan_fd_T ch_pfd[4]; /* info for socket, out, err and in */ readq_T ch_head; /* dummy node, header for circular queue */ *************** *** 1351,1356 **** --- 1351,1357 ---- * the other side has exited, only mention the * first error until the connection works * again. */ + void (*ch_close_cb)(void); /* callback for when channel is closed */ int ch_block_id; /* ID that channel_read_json_block() is *** ../vim-7.4.1318/src/channel.c 2016-02-14 19:13:37.318808628 +0100 --- src/channel.c 2016-02-14 22:52:14.204212504 +0100 *************** *** 339,346 **** * is input on the editor connection socket. */ if (channel->ch_pfd[which].ch_inputHandler == 0) channel->ch_pfd[which].ch_inputHandler = gdk_input_add( ! (gint)channel->ch_pfd[which].ch_fd, (GdkInputCondition) ! ((int)GDK_INPUT_READ + (int)GDK_INPUT_EXCEPTION), messageFromNetbeans, (gpointer)(long)channel->ch_id); # else --- 339,347 ---- * is input on the editor connection socket. */ if (channel->ch_pfd[which].ch_inputHandler == 0) channel->ch_pfd[which].ch_inputHandler = gdk_input_add( ! (gint)channel->ch_pfd[which].ch_fd, ! (GdkInputCondition) ! ((int)GDK_INPUT_READ + (int)GDK_INPUT_EXCEPTION), messageFromNetbeans, (gpointer)(long)channel->ch_id); # else *************** *** 362,373 **** if (!CH_HAS_GUI) return; ! if (channel->ch_pfd[CHAN_SOCK].ch_fd >= 0) channel_gui_register_one(channel, CHAN_SOCK); # ifdef CHANNEL_PIPES ! if (channel->ch_pfd[CHAN_OUT].ch_fd >= 0) channel_gui_register_one(channel, CHAN_OUT); ! if (channel->ch_pfd[CHAN_ERR].ch_fd >= 0) channel_gui_register_one(channel, CHAN_ERR); # endif } --- 363,374 ---- if (!CH_HAS_GUI) return; ! if (channel->CH_SOCK >= 0) channel_gui_register_one(channel, CHAN_SOCK); # ifdef CHANNEL_PIPES ! if (channel->CH_OUT >= 0) channel_gui_register_one(channel, CHAN_OUT); ! if (channel->CH_ERR >= 0) channel_gui_register_one(channel, CHAN_ERR); # endif } *************** *** 386,429 **** } static void ! channel_gui_unregister_one(channel_T *channel, int which) { ! # ifdef FEAT_GUI_X11 ! if (channel->ch_pfd[which].ch_inputHandler != (XtInputId)NULL) { ! XtRemoveInput(channel->ch_pfd[which].ch_inputHandler); ! channel->ch_pfd[which].ch_inputHandler = (XtInputId)NULL; ! } # else # ifdef FEAT_GUI_GTK ! if (channel->ch_pfd[which].ch_inputHandler != 0) ! { ! gdk_input_remove(channel->ch_pfd[which].ch_inputHandler); ! channel->ch_pfd[which].ch_inputHandler = 0; ! } # else # ifdef FEAT_GUI_W32 ! if (channel->ch_pfd[which].ch_inputHandler == 0) ! { ! WSAAsyncSelect(channel->ch_pfd[which].ch_fd, s_hwnd, 0, 0); ! channel->ch_pfd[which].ch_inputHandler = -1; ! } # endif # endif # endif ! } ! ! static void ! channel_gui_unregister(channel_T *channel) ! { ! if (channel->ch_pfd[CHAN_SOCK].ch_fd >= 0) ! channel_gui_unregister_one(channel, CHAN_SOCK); ! # ifdef CHANNEL_PIPES ! if (channel->ch_pfd[CHAN_OUT].ch_fd >= 0) ! channel_gui_unregister_one(channel, CHAN_OUT); ! if (channel->ch_pfd[CHAN_ERR].ch_fd >= 0) ! channel_gui_unregister_one(channel, CHAN_ERR); ! # endif } #endif --- 387,426 ---- } static void ! channel_gui_unregister(channel_T *channel) { ! int which; ! ! #ifdef CHANNEL_PIPES ! for (which = CHAN_SOCK; which < CHAN_IN; ++which) ! #else ! which = CHAN_SOCK; ! #endif { ! # ifdef FEAT_GUI_X11 ! if (channel->ch_pfd[which].ch_inputHandler != (XtInputId)NULL) ! { ! XtRemoveInput(channel->ch_pfd[which].ch_inputHandler); ! channel->ch_pfd[which].ch_inputHandler = (XtInputId)NULL; ! } # else # ifdef FEAT_GUI_GTK ! if (channel->ch_pfd[which].ch_inputHandler != 0) ! { ! gdk_input_remove(channel->ch_pfd[which].ch_inputHandler); ! channel->ch_pfd[which].ch_inputHandler = 0; ! } # else # ifdef FEAT_GUI_W32 ! if (channel->ch_pfd[which].ch_inputHandler == 0) ! { ! WSAAsyncSelect(channel->ch_pfd[which].ch_fd, s_hwnd, 0, 0); ! channel->ch_pfd[which].ch_inputHandler = -1; ! } # endif # endif # endif ! } } #endif *************** *** 1192,1207 **** { ch_log(channel, "Closing channel"); if (channel->CH_SOCK >= 0) { sock_close(channel->CH_SOCK); channel->CH_SOCK = -1; - channel->ch_close_cb = NULL; - #ifdef FEAT_GUI - channel_gui_unregister(channel); - #endif - vim_free(channel->ch_callback); - channel->ch_callback = NULL; } #if defined(CHANNEL_PIPES) if (channel->CH_IN >= 0) --- 1189,1202 ---- { ch_log(channel, "Closing channel"); + #ifdef FEAT_GUI + channel_gui_unregister(channel); + #endif + if (channel->CH_SOCK >= 0) { sock_close(channel->CH_SOCK); channel->CH_SOCK = -1; } #if defined(CHANNEL_PIPES) if (channel->CH_IN >= 0) *************** *** 1220,1225 **** --- 1215,1224 ---- channel->CH_ERR = -1; } #endif + + channel->ch_close_cb = NULL; + vim_free(channel->ch_callback); + channel->ch_callback = NULL; channel_clear(channel); } *************** *** 1383,1389 **** /* * Get the file descriptor to read from, either the socket or stdout. ! * TODO: never gets stderr. */ static int get_read_fd(channel_T *channel) --- 1382,1388 ---- /* * Get the file descriptor to read from, either the socket or stdout. ! * TODO: should have a way to read stderr. */ static int get_read_fd(channel_T *channel) *************** *** 1400,1406 **** /* * Read from channel "channel" for as long as there is something to read. ! * "which" is CHAN_SOCK, CHAN_OUT or CHAN_ERR. When -1 guess. * The data is put in the read queue. */ void --- 1399,1406 ---- /* * Read from channel "channel" for as long as there is something to read. ! * "which" is CHAN_SOCK, CHAN_OUT or CHAN_ERR. When -1 use CHAN_SOCK or ! * CHAN_OUT, the one that is open. * The data is put in the read queue. */ void *************** *** 1475,1493 **** ch_errors(channel, "%s(): Cannot read\n", func); channel_save(channel, (char_u *)DETACH_MSG, (int)STRLEN(DETACH_MSG)); ! if (use_socket) ! { ! channel_close(channel); ! if (channel->ch_close_cb != NULL) ! (*channel->ch_close_cb)(); ! } ! #if defined(CHANNEL_PIPES) ! else ! { ! close(fd); ! channel->CH_OUT = -1; ! } ! #endif if (len < 0) { --- 1475,1486 ---- ch_errors(channel, "%s(): Cannot read\n", func); channel_save(channel, (char_u *)DETACH_MSG, (int)STRLEN(DETACH_MSG)); ! /* TODO: When reading from stdout is not possible, should we try to ! * keep stdin and stderr open? Probably not, assume the other side ! * has died. */ ! channel_close(channel); ! if (channel->ch_close_cb != NULL) ! (*channel->ch_close_cb)(); if (len < 0) { *************** *** 1587,1592 **** --- 1580,1586 ---- if (fd >= 0) for (channel = first_channel; channel != NULL; channel = channel->ch_next) + { # ifdef CHANNEL_PIPES for (i = CHAN_SOCK; i < CHAN_IN; ++i) # else *************** *** 1595,1602 **** if (channel->ch_pfd[i].ch_fd == fd) { *whichp = i; ! return channel } return NULL; } # endif --- 1589,1597 ---- if (channel->ch_pfd[i].ch_fd == fd) { *whichp = i; ! return channel; } + } return NULL; } # endif *************** *** 1638,1644 **** { ch_log_lead("SEND ", channel); fprintf(log_fd, "'"); ! ignored = fwrite(buf, len, 1, log_fd); fprintf(log_fd, "'\n"); fflush(log_fd); } --- 1633,1639 ---- { ch_log_lead("SEND ", channel); fprintf(log_fd, "'"); ! ignored = (int)fwrite(buf, len, 1, log_fd); fprintf(log_fd, "'\n"); fflush(log_fd); } *************** *** 1677,1687 **** --- 1672,1684 ---- int which; for (channel = first_channel; channel != NULL; channel = channel->ch_next) + { # ifdef CHANNEL_PIPES for (which = CHAN_SOCK; which < CHAN_IN; ++which) # else which = CHAN_SOCK; # endif + { if (channel->ch_pfd[which].ch_fd >= 0) { channel->ch_pfd[which].ch_poll_idx = nfd; *************** *** 1691,1696 **** --- 1688,1695 ---- } else channel->ch_pfd[which].ch_poll_idx = -1; + } + } return nfd; } *************** *** 1707,1714 **** int which; for (channel = first_channel; channel != NULL; channel = channel->ch_next) # ifdef CHANNEL_PIPES ! for (which = CHAN_SOCK; which < CHAN_IN; ++which) # else which = CHAN_SOCK; # endif --- 1706,1714 ---- int which; for (channel = first_channel; channel != NULL; channel = channel->ch_next) + { # ifdef CHANNEL_PIPES ! for (which = CHAN_SOCK; which < CH_IN; ++which) # else which = CHAN_SOCK; # endif *************** *** 1721,1726 **** --- 1721,1727 ---- --ret; } } + } return ret; } *************** *** 1739,1744 **** --- 1740,1746 ---- int which; for (channel = first_channel; channel != NULL; channel = channel->ch_next) + { # ifdef CHANNEL_PIPES for (which = CHAN_SOCK; which < CHAN_IN; ++which) # else *************** *** 1754,1759 **** --- 1756,1762 ---- maxfd = fd; } } + } return maxfd; } *************** *** 1770,1775 **** --- 1773,1779 ---- int which; for (channel = first_channel; channel != NULL; channel = channel->ch_next) + { # ifdef CHANNEL_PIPES for (which = CHAN_SOCK; which < CHAN_IN; ++which) # else *************** *** 1784,1789 **** --- 1788,1794 ---- --ret; } } + } return ret; } *** ../vim-7.4.1318/src/os_unix.c 2016-02-14 19:13:37.322808585 +0100 --- src/os_unix.c 2016-02-14 22:10:26.847671765 +0100 *************** *** 5043,5049 **** int fd_in[2]; /* for stdin */ int fd_out[2]; /* for stdout */ int fd_err[2]; /* for stderr */ ! channel_T *channel; /* default is to fail */ job->jv_status = JOB_FAILED; --- 5043,5049 ---- int fd_in[2]; /* for stdin */ int fd_out[2]; /* for stdout */ int fd_err[2]; /* for stderr */ ! channel_T *channel = NULL; /* default is to fail */ job->jv_status = JOB_FAILED; *** ../vim-7.4.1318/src/os_win32.c 2016-02-14 19:13:37.322808585 +0100 --- src/os_win32.c 2016-02-14 22:58:57.824939391 +0100 *************** *** 5039,5051 **** STARTUPINFO si; PROCESS_INFORMATION pi; HANDLE jo; ! #ifdef FEAT_CHANNEL ! channel_T *channel; channel = add_channel(); if (channel == NULL) return; ! #endif jo = CreateJobObject(NULL, NULL); if (jo == NULL) --- 5039,5051 ---- STARTUPINFO si; PROCESS_INFORMATION pi; HANDLE jo; ! # ifdef FEAT_CHANNEL ! channel_T *channel; channel = add_channel(); if (channel == NULL) return; ! # endif jo = CreateJobObject(NULL, NULL); if (jo == NULL) *************** *** 5085,5108 **** job->jv_job_object = jo; job->jv_status = JOB_STARTED; ! #ifdef FEAT_CHANNEL ! # if 0 /* TODO: connect stdin/stdout/stderr */ job->jv_channel = channel; channel_set_pipes(channel, fd_in[1], fd_out[0], fd_err[0]); channel_set_job(channel, job); ! # ifdef FEAT_GUI channel_gui_register(channel); # endif # endif - #endif return; failed: ! #ifdef FEAT_CHANNEL channel_free(channel); ! #endif } char * --- 5085,5108 ---- job->jv_job_object = jo; job->jv_status = JOB_STARTED; ! # ifdef FEAT_CHANNEL ! # if 0 /* TODO: connect stdin/stdout/stderr */ job->jv_channel = channel; channel_set_pipes(channel, fd_in[1], fd_out[0], fd_err[0]); channel_set_job(channel, job); ! # ifdef FEAT_GUI channel_gui_register(channel); + # endif # endif # endif return; failed: ! # ifdef FEAT_CHANNEL channel_free(channel); ! # endif } char * *** ../vim-7.4.1318/src/proto/channel.pro 2016-02-14 19:13:37.326808543 +0100 --- src/proto/channel.pro 2016-02-14 22:46:13.605009553 +0100 *************** *** 22,31 **** void channel_clear(channel_T *channel); void channel_free_all(void); int channel_get_id(void); ! void channel_read(channel_T *channel, int what, char *func); char_u *channel_read_block(channel_T *channel); int channel_read_json_block(channel_T *channel, int id, typval_T **rettv); ! channel_T *channel_fd2channel(sock_T fd, int *what); int channel_send(channel_T *channel, char_u *buf, char *fun); int channel_poll_setup(int nfd_in, void *fds_in); int channel_poll_check(int ret_in, void *fds_in); --- 22,31 ---- void channel_clear(channel_T *channel); void channel_free_all(void); int channel_get_id(void); ! void channel_read(channel_T *channel, int which, char *func); char_u *channel_read_block(channel_T *channel); int channel_read_json_block(channel_T *channel, int id, typval_T **rettv); ! channel_T *channel_fd2channel(sock_T fd, int *whichp); int channel_send(channel_T *channel, char_u *buf, char *fun); int channel_poll_setup(int nfd_in, void *fds_in); int channel_poll_check(int ret_in, void *fds_in); *** ../vim-7.4.1318/src/version.c 2016-02-14 19:13:37.326808543 +0100 --- src/version.c 2016-02-14 20:45:01.705422355 +0100 *************** *** 749,750 **** --- 749,752 ---- { /* Add new patch number below this line */ + /**/ + 1319, /**/ -- hundred-and-one symptoms of being an internet addict: 255. You work for a newspaper and your editor asks you to write an article about Internet addiction...in the "first person." /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///