To: vim_dev@googlegroups.com Subject: Patch 8.2.5118 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.5118 Problem: MS-Windows: sending a message to another Vim may hang if that Vim is halted. Solution: Add a timeout to serverSendToVim(). (Ken Takata, closes #10585) Files: runtime/pack/dist/opt/editexisting/plugin/editexisting.vim, src/os_mswin.c *** ../vim-8.2.5117/runtime/pack/dist/opt/editexisting/plugin/editexisting.vim 2016-03-28 20:00:36.000000000 +0100 --- runtime/pack/dist/opt/editexisting/plugin/editexisting.vim 2022-06-17 19:59:58.925020820 +0100 *************** *** 1,6 **** " Vim Plugin: Edit the file with an existing Vim if possible " Maintainer: Bram Moolenaar ! " Last Change: 2016 Mar 28 " To use add ":packadd! editexisting" in your vimrc file. --- 1,6 ---- " Vim Plugin: Edit the file with an existing Vim if possible " Maintainer: Bram Moolenaar ! " Last Change: 2022 Jun 17 " To use add ":packadd! editexisting" in your vimrc file. *************** *** 35,66 **** endif " Check if this server is editing our file. ! if remote_expr(servername, "bufloaded('" . fname_esc . "')") ! " Yes, bring it to the foreground. ! if has("win32") ! call remote_foreground(servername) ! endif ! call remote_expr(servername, "foreground()") ! if remote_expr(servername, "exists('*EditExisting')") ! " Make sure the file is visible in a window (not hidden). ! " If v:swapcommand exists and is set, send it to the server. ! if exists("v:swapcommand") ! let c = substitute(v:swapcommand, "'", "''", "g") ! call remote_expr(servername, "EditExisting('" . fname_esc . "', '" . c . "')") ! else ! call remote_expr(servername, "EditExisting('" . fname_esc . "', '')") endif - endif ! if !(has('vim_starting') && has('gui_running') && has('gui_win32')) ! " Tell the user what is happening. Not when the GUI is starting ! " though, it would result in a message box. ! echomsg "File is being edited by " . servername ! sleep 2 endif ! return 'q' ! endif endwhile return '' endfunc --- 35,70 ---- endif " Check if this server is editing our file. ! try ! if remote_expr(servername, "bufloaded('" . fname_esc . "')") ! " Yes, bring it to the foreground. ! if has("win32") ! call remote_foreground(servername) ! endif ! call remote_expr(servername, "foreground()") ! if remote_expr(servername, "exists('*EditExisting')") ! " Make sure the file is visible in a window (not hidden). ! " If v:swapcommand exists and is set, send it to the server. ! if exists("v:swapcommand") ! let c = substitute(v:swapcommand, "'", "''", "g") ! call remote_expr(servername, "EditExisting('" . fname_esc . "', '" . c . "')") ! else ! call remote_expr(servername, "EditExisting('" . fname_esc . "', '')") ! endif endif ! if !(has('vim_starting') && has('gui_running') && has('gui_win32')) ! " Tell the user what is happening. Not when the GUI is starting ! " though, it would result in a message box. ! echomsg "File is being edited by " . servername ! sleep 2 ! endif ! return 'q' endif ! catch /^Vim\%((\a\+)\)\=:E241:/ ! " Unable to send to this server, ignore it. ! endtry endwhile return '' endfunc *** ../vim-8.2.5117/src/os_mswin.c 2022-06-13 22:34:10.588709648 +0100 --- src/os_mswin.c 2022-06-17 20:04:23.801747786 +0100 *************** *** 1971,1976 **** --- 1971,1980 ---- # define VIM_CLASSNAME "VIM_MESSAGES" # define VIM_CLASSNAME_LEN (sizeof(VIM_CLASSNAME) - 1) + // Timeout for sending a message to another Vim instance. Normally this works + // instantly, but it may hang when the other Vim instance is halted. + # define SENDMESSAGE_TIMEOUT (5 * 1000) + // Communication is via WM_COPYDATA messages. The message type is sent in // the dwData parameter. Types are defined here. # define COPYDATA_KEYS 0 *************** *** 1992,2000 **** /* * Tell the other side what encoding we are using. ! * Errors are ignored. */ ! static void serverSendEnc(HWND target) { COPYDATASTRUCT data; --- 1996,2004 ---- /* * Tell the other side what encoding we are using. ! * Return -1 if timeout happens. Other errors are ignored. */ ! static int serverSendEnc(HWND target) { COPYDATASTRUCT data; *************** *** 2002,2009 **** data.dwData = COPYDATA_ENCODING; data.cbData = (DWORD)STRLEN(p_enc) + 1; data.lpData = p_enc; ! (void)SendMessage(target, WM_COPYDATA, (WPARAM)message_window, ! (LPARAM)(&data)); } /* --- 2006,2016 ---- data.dwData = COPYDATA_ENCODING; data.cbData = (DWORD)STRLEN(p_enc) + 1; data.lpData = p_enc; ! if (SendMessageTimeout(target, WM_COPYDATA, ! (WPARAM)message_window, (LPARAM)&data, ! SMTO_ABORTIFHUNG, SENDMESSAGE_TIMEOUT, NULL) == 0) ! return -1; ! return 0; } /* *************** *** 2061,2066 **** --- 2068,2074 ---- COPYDATASTRUCT reply; char_u *res; int retval; + DWORD_PTR dwret = 0; char_u *str; char_u *tofree; *************** *** 2114,2122 **** reply.lpData = res; reply.cbData = (DWORD)STRLEN(res) + 1; ! serverSendEnc(sender); ! retval = (int)SendMessage(sender, WM_COPYDATA, ! (WPARAM)message_window, (LPARAM)(&reply)); vim_free(tofree); vim_free(res); return retval; --- 2122,2138 ---- reply.lpData = res; reply.cbData = (DWORD)STRLEN(res) + 1; ! if (serverSendEnc(sender) < 0) ! retval = -1; ! else ! { ! if (SendMessageTimeout(sender, WM_COPYDATA, ! (WPARAM)message_window, (LPARAM)&reply, ! SMTO_ABORTIFHUNG, SENDMESSAGE_TIMEOUT, &dwret) == 0) ! retval = -1; ! else ! retval = (int)dwret; ! } vim_free(tofree); vim_free(res); return retval; *************** *** 2394,2399 **** --- 2410,2416 ---- HWND target; COPYDATASTRUCT data; long_u n = 0; + DWORD_PTR dwret = 0; // The "name" argument is a magic cookie obtained from expand(""). // It should be of the form 0xXXXXX - i.e. a C hex literal, which is the *************** *** 2410,2421 **** data.cbData = (DWORD)STRLEN(reply) + 1; data.lpData = reply; ! serverSendEnc(target); ! if (SendMessage(target, WM_COPYDATA, (WPARAM)message_window, ! (LPARAM)(&data))) ! return 0; ! ! return -1; } int --- 2427,2439 ---- data.cbData = (DWORD)STRLEN(reply) + 1; data.lpData = reply; ! if (serverSendEnc(target) < 0) ! return -1; ! if (SendMessageTimeout(target, WM_COPYDATA, ! (WPARAM)message_window, (LPARAM)&data, ! SMTO_ABORTIFHUNG, SENDMESSAGE_TIMEOUT, &dwret) == 0) ! return -1; ! return dwret ? 0 : -1; } int *************** *** 2432,2437 **** --- 2450,2456 ---- COPYDATASTRUCT data; char_u *retval = NULL; int retcode = 0; + DWORD_PTR dwret = 0; char_u altname_buf[MAX_PATH]; // Execute locally if no display or target is ourselves *************** *** 2463,2471 **** data.cbData = (DWORD)STRLEN(cmd) + 1; data.lpData = cmd; ! serverSendEnc(target); ! if (SendMessage(target, WM_COPYDATA, (WPARAM)message_window, ! (LPARAM)(&data)) == 0) return -1; if (asExpr) --- 2482,2494 ---- data.cbData = (DWORD)STRLEN(cmd) + 1; data.lpData = cmd; ! if (serverSendEnc(target) < 0) ! return -1; ! if (SendMessageTimeout(target, WM_COPYDATA, ! (WPARAM)message_window, (LPARAM)&data, ! SMTO_ABORTIFHUNG, SENDMESSAGE_TIMEOUT, &dwret) == 0) ! return -1; ! if (dwret == 0) return -1; if (asExpr) *** ../vim-8.2.5117/src/version.c 2022-06-17 19:23:28.807228775 +0100 --- src/version.c 2022-06-17 19:56:35.256046192 +0100 *************** *** 736,737 **** --- 736,739 ---- { /* Add new patch number below this line */ + /**/ + 5118, /**/ -- There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. The other way is to make it so complicated that there are no obvious deficiencies. -C.A.R. Hoare /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///