Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vim+screen: X11 server change disables X11 copy/paste #3649

Closed
OSS542 opened this issue Nov 30, 2018 · 51 comments

Comments

Projects
None yet
5 participants
@OSS542
Copy link

commented Nov 30, 2018

Vim cached X11 primary selection ownership information is obsolete when using vim with GNU screen and changing the connected X server instance.
ex. if local machine is rebooted, local X server is restarted, ssh X11 forwarding is restarted, or connecting from a different local machine

Unable to access X11 primary selection unless vim is restarted
ex. can't copy to primary X11 clipboard

To recreate:

at local xterm

rmt=raspberrypi
DISPLAY=:0 ssh -fYp 13887 $rmt 'xterm -T remote_vim -e screen -m -S remote_vim vim'

at remote_vim

:.!echo -e "echo one one one\necho two two two\necho three three three"

at local xterm

kill ssh X11 forwarding, screen session survives

kill -INT $(ps ax | grep remote_vim | grep -vw grep | cut -d " " -f 1)
DISPLAY=:0 ssh -fYp 13887 $rmt 'xterm -T remote_vim -e screen -r remote_vim'
vi # in local terminal, not at remote_vim
enter insert mode

at remote_vim

select line

at local xterm

paste line from remote_vim, this will fail to work correctly

@chrisbra

This comment has been minimized.

Copy link
Member

commented Nov 30, 2018

duplicate of #844

@nuko8

This comment has been minimized.

Copy link

commented Nov 30, 2018

Vim cached X11 primary selection ownership information is obsolete when using vim with GNU screen and changing the connected X server instance.

Vim caches neither primary nor pasteboard selection ownership; it only asks the X11 server which is known to Vim at startup for selection ownership every time it needs it, which implies that Vim has to establish and keep connection with the server before and when Vim's copy and paste through X11 selection mechanism is carried out. Therefore, Vim won't be able to work as you expected when the server is restarted since the established connection between those particular instances of Vim and the X11 server has already lost then.

As another side of the same coin, by restarting Vim after rebooting the local system and restarting the X11 server, Vim works as you reported since a new connection between the new instance of Vim and that of the X11 server is established at the startup of the Vim.

@OSS542

This comment has been minimized.

Copy link
Author

commented Nov 30, 2018

:xrestore

E492: not an editor command

has this command been removed or renamed ?

@chrisbra

This comment has been minimized.

Copy link
Member

commented Nov 30, 2018

it hasn't been merged yet.

@chrisbra

This comment has been minimized.

Copy link
Member

commented Nov 30, 2018

@nuko8 I believe Vim tries to reset the clipboard connection if it notices that the X-Connection wen't down. See #203 and patch 7.4.523

@OSS542

This comment has been minimized.

Copy link
Author

commented Nov 30, 2018

So....... what do I do with this ?

@nuko8

This comment has been minimized.

Copy link

commented Nov 30, 2018

@chrisbra Ah, I was wrong. Somehow I forgot that difference between primary and pasteboard. Sorry about missing that and thank you for correcting me.

@OSS542

This comment has been minimized.

Copy link
Author

commented Nov 30, 2018

Let me try again. What's the best way to handle this ?

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 1, 2018

Please do not trouble yourselves further. I've used the commits referenced in #844 and prepared an equivalent patch for vim-8.1.1 to add the xrestore facility. It seems to be working well.

@brammool

This comment has been minimized.

Copy link
Contributor

commented Dec 1, 2018

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 1, 2018

As far as I know, there is no such mechanism, at least not in the release versions up to 8.1.1. I have always had to restart it if the X server was restarted or changed for whatever reason. There have been patches and reports involving this going back several years, but to my understanding none have been merged as of 8.1.1. I know there has never been any functioning reconnect, neither manual nor automatic in releases from 7.1 onwards.

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 1, 2018

The entry for #844 mentions conflicts which need to be resolved, which may explain something about why a fix for X reconnection was not available.

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 2, 2018

I also note the following regarding the commits in #844 as they are :

  1. Using xrestore in .vimrc without a display specified causes a seg fault in Vim.
    It would appear that the default display for xrestore is not initialized until after .vimrc is run

  2. Any change in display caused by xrestore pauses startup with the following prompt if xrestore is used in .vimrc :

Press ENTER or type command to continue

It continues only when manually responded to

I'll need to do some further patching to fix these two.

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 3, 2018

I've found the automatic reconnection mechanism code, or what appears to be it. The ex_xrestore() function (from the #844 commits) doesn't seem to actually do much more than provide a new display name and set a display reset flag (xterm_dpy_was_reset=1). It looks like all the rest of the code except for the X error handler "x_IOerror_handler()" would have to be working in order for the xrestore command to be working, which it is (when patched in). It would seem that the x_IOerror_handler() function is not being called for some reason, but I have yet to verify this. If that turns out to be the case, it would explain the issues I'm seeing.

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 3, 2018

And of course, as I should have noted more clearly earlier, the xrestore command is useless in .vimrc anyway, but I should patch it further so it becomes a nop if called from .vimrc. I really need to get the automatic X reconnection to work properly though.

@chrisbra

This comment has been minimized.

Copy link
Member

commented Dec 3, 2018

yeah, it would be good to find out, why the x error handler is not called.

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 3, 2018

It turns out that the error handler x_IOerror_handler() is in fact being invoked, but the XtOpenDisplay() display reopening (which is called from setup_term_clip, from may_restore_clipboard) fails after the x_IOerror_handler() is invoked, but not before. Enabling app_context destruction in may_restore_clipboard() does not prevent this failure.

I am now trying to find out why the XtOpenDisplay() display reopen fails.

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 4, 2018

Finally found it. The problem seems to lie with Xt and the associated software. There is a certain very short period after a X11 disconnect during which XtOpenDisplay() will fail. A very simple two line patch triggers a retry which quickly succeeds after that period. All works well after that.
Thank you very much for your very kind assistance in this.

@brammool

This comment has been minimized.

Copy link
Contributor

commented Dec 4, 2018

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 4, 2018

diff -ru vim81/src/os_unix.c vim81.new/src/os_unix.c
--- vim81/src/os_unix.c	2018-05-12 11:42:33.000000000 -0400
+++ vim81.new/src/os_unix.c	2018-12-03 21:28:06.119161750 -0500
@@ -7468,6 +7468,8 @@
 	{
 	    xterm_dpy = XtOpenDisplay(app_context, xterm_display,
 		    "vim_xterm", "Vim_xterm", NULL, 0, &z, &strp);
+            if(!xterm_dpy)
+		xterm_dpy_was_reset = TRUE;
 #if defined(HAVE_SETJMP_H)
 	    mch_endjmp();
 #endif

@OSS542 OSS542 closed this Dec 4, 2018

@OSS542 OSS542 reopened this Dec 4, 2018

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 4, 2018

That should do it.

@brammool

This comment has been minimized.

Copy link
Contributor

commented Dec 5, 2018

Doesn't this mean that if the XtOpenDisplay() always fails, we keep trying?
That is not good, because it may be a slow operation.
Perhaps we should add a flag that it once worked, instead of just a flag to remember it failed.

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 5, 2018

As far as I can tell, XtOpenDisplay() only fails for an extremely short timeout period immediately following a server disconnection. I'm using that patch extensively now, and am no longer having any difficulties changing servers at all. I don't get any noticeable delays whatsoever.

@brammool

This comment has been minimized.

Copy link
Contributor

commented Dec 6, 2018

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 7, 2018

There is that consideration. I'm afraid I'm not a member of the project though....:-) That said, what would you like to see done with this ?

@chrisbra

This comment has been minimized.

Copy link
Member

commented Dec 7, 2018

For the record, I tried the patch in my local installation. I usually run Vim without an available X-Server inside a putty terminal. The patch makes Vim unresponsive.

How about something along this:

diff --git a/src/os_unix.c b/src/os_unix.c
index 4d902d939..1537ed951 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -1704,9 +1704,12 @@ x_IOerror_handler(Display *dpy UNUSED)
     static void
 may_restore_clipboard(void)
 {
-    if (xterm_dpy_was_reset)
+    static int count = 0;
+
+    if (xterm_dpy_was_reset && ++count % 100 == 0)
     {
        xterm_dpy_was_reset = FALSE;
+       count = 0;

 # ifndef LESSTIF_VERSION
        /* This has been reported to avoid Vim getting stuck. */
@@ -7498,6 +7501,12 @@ setup_term_clip(void)
        {
            xterm_dpy = XtOpenDisplay(app_context, xterm_display,
                    "vim_xterm", "Vim_xterm", NULL, 0, &z, &strp);
+           if(!xterm_dpy)
+           {
+               xterm_dpy_was_reset = TRUE;
+               if (p_verbose > 0)
+                   verb_msg((char_u *)_("Failed to open X Display"));
+           }
 #if defined(HAVE_SETJMP_H)
            mch_endjmp();
 #endif
@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 7, 2018

I just gave this next patch a try by running it under screen, killing the X server, and restarting it. The first several copy/paste attempts fail. Eventually one succeeds, and the rest work properly after that. I'll need to see why that might be. I tried the earlier "two-line" patch from the console with no X server running, and did not see any lack of response. I don't know for sure if that has any bearing on what you experience running inside a putty terminal without an X server. I don't have putty installed, but I'm thinking of installing it and trying to use vim from a putty terminal as you did to see what happens with the "two line" patch there..

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 7, 2018

Can you give me an example of what you are doing with putty so I can try to recreate it ?

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 7, 2018

I am also thinking that changing 100 to a smaller number might help with this larger patch.

@chrisbra

This comment has been minimized.

Copy link
Member

commented Dec 7, 2018

I am just using putty to ssh to my linux vmware for developing Vim. And just starting Vim with your patch caused it to become unresponsive. I couldn't even enter :q<cr>. I assumed this was because Vim was constantly trying to reconnect to the X-Server.

I am also thinking that changing 100 to a smaller number might help with this larger patch.

Yeah, not sure what a good compromise would be. Perhaps 50?

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 7, 2018

Seems to work perfectly for me at 50. Here is the latest:

diff -ru vim81/src/os_unix.c vim81.new/src/os_unix.c
--- vim81/src/os_unix.c	2018-05-12 11:42:33.000000000 -0400
+++ vim81.new/src/os_unix.c	2018-12-07 17:50:41.570243632 -0500
@@ -1712,9 +1712,12 @@
     static void
 may_restore_clipboard(void)
 {
-    if (xterm_dpy_was_reset)
+    static int count = 0;
+
+    if (xterm_dpy_was_reset && ++count % 50 == 0)
     {
 	xterm_dpy_was_reset = FALSE;
+	count = 0;
 
 # ifndef LESSTIF_VERSION
 	/* This has been reported to avoid Vim getting stuck. */
@@ -7468,6 +7471,12 @@
 	{
 	    xterm_dpy = XtOpenDisplay(app_context, xterm_display,
 		    "vim_xterm", "Vim_xterm", NULL, 0, &z, &strp);
+	    if(!xterm_dpy)
+	    {
+		xterm_dpy_was_reset = TRUE;
+		if (p_verbose > 0)
+		    verb_msg((char_u *)_("Failed to open X Display"));
+	    }
 #if defined(HAVE_SETJMP_H)
 	    mch_endjmp();
 #endif
@brammool

This comment has been minimized.

Copy link
Contributor

commented Dec 8, 2018

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 8, 2018

This one fails with xterm_dpy_retry_count=5, but works well with xterm_dpy_retry_count=10.
Here is the latest:

diff -ru vim81/src/os_unix.c vim81.new/src/os_unix.c
--- vim81/src/os_unix.c	2018-05-12 11:42:33.000000000 -0400
+++ vim81.new/src/os_unix.c	2018-12-08 12:25:03.195929759 -0500
@@ -1686,13 +1686,13 @@
  */
 static int x_IOerror_handler(Display *dpy);
 static void may_restore_clipboard(void);
-static int xterm_dpy_was_reset = FALSE;
+static int xterm_dpy_retry_count = 0;
 
     static int
 x_IOerror_handler(Display *dpy UNUSED)
 {
     xterm_dpy = NULL;
-    xterm_dpy_was_reset = TRUE;
+    xterm_dpy_retry_count = 10; // Try reconnecting 10 times
     x11_window = 0;
     x11_display = NULL;
     xterm_Shell = (Widget)0;
@@ -1712,9 +1712,9 @@
     static void
 may_restore_clipboard(void)
 {
-    if (xterm_dpy_was_reset)
+    if (xterm_dpy_retry_count > 0)
     {
-	xterm_dpy_was_reset = FALSE;
+	--xterm_dpy_retry_count;
 
 # ifndef LESSTIF_VERSION
 	/* This has been reported to avoid Vim getting stuck. */
@@ -7468,6 +7468,8 @@
 	{
 	    xterm_dpy = XtOpenDisplay(app_context, xterm_display,
 		    "vim_xterm", "Vim_xterm", NULL, 0, &z, &strp);
+	    if (xterm_dpy != NULL)
+		xterm_dpy_retry_count = 0;
 #if defined(HAVE_SETJMP_H)
 	    mch_endjmp();
 #endif
@brammool

This comment has been minimized.

Copy link
Contributor

commented Dec 8, 2018

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 8, 2018

I'm suspecting a timeout, since as far as I know it only happens with a broken connection between a client and the X server. I'll see what more I can find out.

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 8, 2018

I've got a bit more information. It appears that XtOpenDisplay() is unable to obtain an authorized connection to the X server for some period of time following a connection break. The following list was taken using vim with the most recent patch I have, and setting xterm_dpy_retry_count=10. Each entry gives the result of a single XtOpenDisplay() attempt to connect to the server. There are several different things that fail internally to XtOpenDisplay() as follows:

01 - ok    startup, before connection break
02 - fail  bad authorization data, connection reset by peer

03 - fail  /tmp/.X11-unix/X0 connection refused, 
           /tmp/.X11-unix/X0, No such file
           does DNS lookup
           127.0.0.1:6000 connection refused

04 - fail  /tmp/.X11-unix/X0 connection refused, 
           /tmp/.X11-unix/X0, No such file
           does dns lookup
           127.0.0.1:6000 connection refused

05 - fail  bad authorization data, connection shut down by client
06 - fail  bad authorization data, connection shut down by client
07 - fail  bad authorization data, connection shut down by client
08 - fail  bad authorization data, connection shut down by client

09 - ok

I can send you the details from strace if you'd like to see them.

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 9, 2018

I have also prepared a very short example program using Xlib which calls XOpenDisplay() directly (note: not XtOpenDisplay()....). XtOpenDisplay() is a convenience function which, according to the documentation, calls XOpenDisplay().
The example program appears to show the same sort of refusal to open the X display until some time has passed following a connection break.

/* utl1.c */
#include <X11/Xlib.h>
#include <stdio.h>
#include <unistd.h>
#include <setjmp.h>
#include <stdlib.h>

#define RETRYLIM 5
#define USLPTME  1

jmp_buf env;
int xioerr=0;

int main(int argc, char **argv)
{
    Display *display;
    int fun1(Display *display), i, (*prvxioerrhndlr)(), j, retrylim;

    if(argc>1)
        retrylim=(argc>1)?atoi(argv[1]):RETRYLIM;
    prvxioerrhndlr=XSetIOErrorHandler(&fun1);

    fprintf(stderr, "jfh1:pt1\n");
    fprintf(stderr, "jfh1:pt2\n");
    display=XOpenDisplay(NULL);
    fprintf(stderr, "jfh1:pt3\n");
    if(display)
    {
        setjmp(env);
        if(xioerr)
        {
            xioerr=0;
            XSetIOErrorHandler(prvxioerrhndlr);
            XCloseDisplay(display);

            for(j=0;j<retrylim;j++)
            {
                display=XOpenDisplay(NULL);
                fprintf(stderr, "retry #%d : display=%p\n", j, display);
                if(display)
                {
                    XSetIOErrorHandler(&fun1);
                    break;
                }
                else sleep(USLPTME);
            }
            if(!display)
                fprintf(stderr,"%s:%d\n", __FUNCTION__, __LINE__);
        }
        if(display)
        {
            for(i=0;;++i)
            {
                fprintf(stderr, "%d\n",i);
                XFlush(display);
                sleep(1);
            }
            XCloseDisplay(display);
        }
    } else fprintf(stderr,"%s:%d\n", __FUNCTION__, __LINE__);
    return 0;
};

int fun1(Display *display)
{
    fprintf(stderr, "fun1\n");
    xioerr=1;
    longjmp(env,1);
    return 0;
}

Here is a Makefile for it:

CFLAGS1 = -Wall
CFLAGS = $(CFLAGS1) -g -O0
LDLIBS = -L /usr/X11R6/lib -lX11
utl1:
clean:;rm -f utl1 $(foreach i,utl1 ,$i.o $i.d)
%.d: %.c;$(CC) -M $(CFLAGS1) $< > $@
ifneq ($(MAKECMDGOALS),clean)
-include $(addsuffix .d,utl1)
endif

The program is run like this:
./utl1 50 2>&1 | tee utl1.log

The single argument is a maximum number of XOpenDisplay() retries. It will sleep 1 second between retries.

Here is output from a sample run:

jfh1:pt1
jfh1:pt2
jfh1:pt3
0
1
2
3
4
5
6
7
8
9
fun1
No protocol specified
No protocol specified
No protocol specified
No protocol specified
No protocol specified
No protocol specified
No protocol specified
No protocol specified
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

The "No protocol specified" messages appear to be coming from the XOpenDisplay() call when the retries are attempted

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 9, 2018

My apologies for that rather lengthy previous comment.

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 9, 2018

Two quick additional notes:

  1. the example program should be saved as utl1.c
  2. if you use a smaller wait between retries (ex using usleep() instead of sleep()...) many more retries are required.
@brammool

This comment has been minimized.

Copy link
Contributor

commented Dec 9, 2018

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 9, 2018

I will try this with vim. From working with utl1.c, it looks like it's about 8 to 10 seconds here. I see what it turns out to be with vim.

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 10, 2018

I have prepared a new patch to vim-8.1 with the changes you have suggested. In testing this, I find that the individual XtOpenDisplay() connection attempts can vary greatly in the time required. If XtOpenDisplay() encounters a significant number of "No protocol specified" errors, (apparently from XDisplay() which it calls), the time required for an individual XtOpenDisplay() connection attempt can be over 30 seconds. I have not seen this happen more than once per X server connection break, though it usually happens once per connection break.

Accordingly, I have set the following in the patch:

#define XTERM_DPY_RETRY_TME_LIM 60
#define XTERM_DPY_RETRY_CNT_LIM 50
@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 10, 2018

Here is the latest patch to vim-8.1:

diff -ru vim81/src/os_unix.c vim81.new/src/os_unix.c
--- vim81/src/os_unix.c	2018-05-12 11:42:33.000000000 -0400
+++ vim81.new/src/os_unix.c	2018-12-10 10:19:27.416400966 -0500
@@ -1686,13 +1686,18 @@
  */
 static int x_IOerror_handler(Display *dpy);
 static void may_restore_clipboard(void);
-static int xterm_dpy_was_reset = FALSE;
+static int xterm_dpy_retry_count = 0;
+static time_t xterm_dpy_retry_start_time;
+
+#define XTERM_DPY_RETRY_TME_LIM 60
+#define XTERM_DPY_RETRY_CNT_LIM 50
 
     static int
 x_IOerror_handler(Display *dpy UNUSED)
 {
     xterm_dpy = NULL;
-    xterm_dpy_was_reset = TRUE;
+    xterm_dpy_retry_count = XTERM_DPY_RETRY_CNT_LIM;
+    xterm_dpy_retry_start_time=time(NULL);
     x11_window = 0;
     x11_display = NULL;
     xterm_Shell = (Widget)0;
@@ -1712,22 +1717,30 @@
     static void
 may_restore_clipboard(void)
 {
-    if (xterm_dpy_was_reset)
+    time_t elapsed;
+
+    if(xterm_dpy_retry_count > 0)
     {
-	xterm_dpy_was_reset = FALSE;
+	elapsed=time(NULL)-xterm_dpy_retry_start_time;
+	if(elapsed < XTERM_DPY_RETRY_TME_LIM)
+	{
+	    --xterm_dpy_retry_count;
 
 # ifndef LESSTIF_VERSION
-	/* This has been reported to avoid Vim getting stuck. */
-	if (app_context != (XtAppContext)NULL)
-	{
-	    XtDestroyApplicationContext(app_context);
-	    app_context = (XtAppContext)NULL;
-	    x11_display = NULL; /* freed by XtDestroyApplicationContext() */
-	}
+	    /* This has been reported to avoid Vim getting stuck. */
+	    if (app_context != (XtAppContext)NULL)
+	    {
+		XtDestroyApplicationContext(app_context);
+		app_context = (XtAppContext)NULL;
+		x11_display = NULL; /* freed by XtDestroyApplicationContext() */
+	    }
 # endif
 
-	setup_term_clip();
-	get_x11_title(FALSE);
+	    setup_term_clip();
+	    get_x11_title(FALSE);
+	}
+	else
+	    xterm_dpy_retry_count = 0;
     }
 }
 #endif
@@ -7468,6 +7481,9 @@
 	{
 	    xterm_dpy = XtOpenDisplay(app_context, xterm_display,
 		    "vim_xterm", "Vim_xterm", NULL, 0, &z, &strp);
+	    if (xterm_dpy != NULL)
+		xterm_dpy_retry_count = 0;
+
 #if defined(HAVE_SETJMP_H)
 	    mch_endjmp();
 #endif
@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 10, 2018

I should further note that I have not seen it require more than 10 retries to re-establish the X server connection. The individual attempts are usually very quick initially, but eventually a "No protocol specified" condition occurs and involves a longer duration attempt. It generally succeeds in re-establishing the connection shortly afterwards.

@nuko8

This comment has been minimized.

Copy link

commented Dec 11, 2018

As "No protocol specified" error sometimes indicates that ~/.Xauthority is no longer valid for the current X session, it appears to me that the first thing we should do after the X server restarts is to correct/update it using xauth(1) in accordance with the new instance of the X server which was restarted, so that new connections will be granted with the very first attempt at establishing connection. If so, then with that corrected/updated ~/.Xauthority, we could be free from a shaky combination of retry and timeout.

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 11, 2018

As far as I know, ~/.Xauthority is updated with the correct information at login by programs that start the X server such as xdm or startx. The XOpenDisplay() call done by XtOpenDisplay() as called from a client causes ~/.Xauthority to be read to obtain the requisite authorization for the particular display to be opened. In checking the connection dialog between the client and the X server, the actual connection request generated by the XOpenDisplay() call appears to be incorrect for some period of time. It appears as though the authorization protocol identification and data is omitted during that period. There were a few other issues as well, such as unix socket file entries missing or otherwise unavailable.

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 12, 2018

nuko8's comment led me on to something that seems important.

In the cases I am testing, I am running vim from a shell in a GNU screen instance.

I have found that what is happening with the retries is that the X server connection infrastructure and authentication data is being rebuilt by the act of starting up a new instance of the X server (actually done by xdm, startx, or similar). This seems to take somewhat more than 30 seconds as the new server instance is being started up. When vim attempts to reconnect initially, the X server connection infrastructure and authentication data is either obsolete, absent altogether, or incomplete.

A remote vim session accessed via ssh with X forwarding appears to experience similar circumstances.

If a timeout is used as part of our patches as they are now, I am thinking that a connection would need to be re-established before the timeout expires, or the X11 cut/paste will remain disabled until the connection is rebroken and re-established before the timeout expires again.

I should note further that the timeout in our latest patch begins when the X server connection break has been detected. It will still be trying to reconnect until the timeout expires, even though the connection is broken, as long as the GNU screen instance is still in effect.

@OSS542

This comment has been minimized.

Copy link
Author

commented Dec 12, 2018

Testing with "top" on a machine with 24 vim processes active while disconnected from an X server shows little or no cpu usage by them.

@puremourning

This comment has been minimized.

Copy link

commented Dec 12, 2018

Or because you intentionally want to connect to another X server?

This is a real use-case as well, if it is indeed possible to solve, that would be delightful:

Use case:

  • The X server runs on a Windows (or other remote) PC, using ssh X forwarding.
  • The Vim instance runs inside a tmux or screen session
  • The Windows PC is rebooted, destroying the x server and/or tunnel
  • A new server/tunnel is created and connected to the tmux session.

For example:

  • start X server on host1
  • ssh -Y host2 nohup xterm &
  • in that xterm: tmux
  • in that tmux: vim
  • on host1: shutdown -r now
  • start another X server on host1
  • ssh -Y host2 nohup xterm &
  • in that xterm: tmux attach
  • in the vim: you want to re-connect to the (new) DISPLAY created by the (new) ssh tunnel.

I think, if i understand correctly, the existing reconnect logic does not cater for this, but I could be wrong (it might be possible to do :let $DISPLAY=<new display> within the Vim.

@brammool

This comment has been minimized.

Copy link
Contributor

commented Dec 22, 2018

The unfinished fix was accidentally included in patch 8.1.0615 (big patch was touching the same file).
I assume this won't completely fix the problem, as the retry count is low. But it might help in some situations.

@chrisbra

This comment has been minimized.

Copy link
Member

commented Dec 24, 2018

closing this for now. Please let us know if the "fix" is working or not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.