bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Emacs - cannot connect to X server


From: Muggeridge, Matt
Subject: RE: Emacs - cannot connect to X server
Date: Fri, 11 Oct 2002 15:01:55 +1000

Hi Richard,

I believe I have uncovered the source of a bug I reported back in June.
I am not certain of the best fix here and would refer the problem to the
code author.  

The overview:
-------------
XtOpenDisplay() attempts to connect() to the Xserver.  However, the
connect() call would be interrupted with errno=EINTR due to a SIGALRM.
The SIGALRM was generated by a call to setitimer().  

Proposed Solutions:
-------------------
Either (1) the timeout period has to be extended to account for slow
links, or (2) the call to setitimer() must be postponed until after the
call to XtOpenDisplay().  I prefer option (2) since it doesn't have a
dependency on the speed of a WAN link.  The code diffs are shown below.
I have tested both scenarios.

The code diffs for option (1):

  # diff atimer.c atimer.c.DIST 
  325d324
  < #if 0
  328,331d326
  < #else
  <         EMACS_SET_SECS (time, 3);
  <         EMACS_SET_USECS (time, 0);
  < #endif

The code diffs for option (2):

  # diff xterm.c xterm-DIST.c
  14231,14241d14230
  <   /* Install an asynchronous timer that processes Xt timeout events
  <      every 0.1s.  This is necessary because some widget sets use
  <      timeouts internally, for example the LessTif menu bar, or the
  <      Xaw3d scroll bar.  When Xt timouts aren't processed, these
  <      widgets don't behave normally.  */
  <   {
  <     EMACS_TIME interval;
  <     EMACS_SET_SECS_USECS (interval, 0, 100000);
  <     start_atimer (ATIMER_CONTINUOUS, interval, x_process_timeouts,
0);
  <   }
  < 
  14691a14681,14691
  > 
  >   /* Install an asynchronous timer that processes Xt timeout events
  >      every 0.1s.  This is necessary because some widget sets use
  >      timeouts internally, for example the LessTif menu bar, or the
  >      Xaw3d scroll bar.  When Xt timouts aren't processed, these
  >      widgets don't behave normally.  */
  >   {
  >     EMACS_TIME interval;
  >     EMACS_SET_SECS_USECS (interval, 0, 100000);
  >     start_atimer (ATIMER_CONTINUOUS, interval, x_process_timeouts,
0);
  >   }


The problem call-tree is:

 x_term_init() -> x_initialize() -> start_atimer() -> setitimer()
               -> XtOpenDisplay() -> connect() -> EINTR due to SIGALRM

Comments in x_initialize() suggest that calling start_atimer() is
necessary.  Viz.

  >   /* Install an asynchronous timer that processes Xt timeout events
  >      every 0.1s.  This is necessary because some widget sets use
  >      timeouts internally, for example the LessTif menu bar, or the
  >      Xaw3d scroll bar.  When Xt timouts aren't processed, these
  >      widgets don't behave normally.  */

If the 0.1s timer is needed for the correct functioning of X, then
option (2) is the only viable option.  I don't know if option (2) has
other unintended side-effects.  I am not an X-pert.

I have attached two traces.  The first trace (Xlib_trace.txt) shows how
the call to XtOpenDisplay() fails due to connect() returning EINTR.  The
second trace file (Signal Trace.txt) shows that the SIGALRM is
responsible for EINTR  I have annotated the second trace with:

        "--- INTERESTING STUFF BELOW ---"

You may like to scan for that to see where the signal interruption is
occurring.

Furthter Analysis:

If I understand the trace output, I think the most interesting code
fragment is the call to setitimer() which will generate a SIGALRM when
the timer expires.  The interval initially used is 98047 microseconds.
Subsequent intervals are then 1000us, which seems way to brief.  On
links where the round-trip-time exceeds this will result in the
behaviour I am seeing.

The trace snippets:

Setup a timer to expire in approx. 98ms...

  setitimer (ITIMER_REAL, 0x11fffa808={{0,0}, {0,98047}}, 0x0) = 0
  sigaction (SIGWINCH, {{0x0,0x0,SA_RESTART}}, 0x11fffa828) = 0, [ , ,
{{0x0,0x0,0}} ]
  sigaction (SIGPIPE, {{0x1200d40a0,0x0,SA_RESTART}}, 0x11fffa828) = 0,
[ , , {{0x0,0x0,0}} ]
  obreak (0x140535000) = 0
  socket (AF_INET, SOCK_STREAM, PF_UNSPEC) = 5
  setsockopt (5, IPPROTO_TCP, TCP_NODELAY, 0x11fffa4b8=1, 4) = 0
  setsockopt (5, SOL_SOCKET, SO_KEEPALIVE, 0x11fffa4b8=1, 4) = 0
  connect (5, 0x11fff7c10=<2/INET, 6000, 16.176.234.79>, 16) = SIGNAL
[14 SIGALRM]
  -1, Errno 4 (Interrupted system call)

Subsequent calls to setitimer() use a 1ms interval.  This seems way too
short for it to be practical.

  setitimer (ITIMER_REAL, 0x11fffa208={{0,0}, {0,1000}}, 0x0) = 0
  sigreturn (0x11fffa278) = -1
  gettimeofday (0x11fffa4e8, 0x0) = 0, [ {1034300109, 135631}, {} ]
  socket (AF_INET, SOCK_STREAM, PF_UNSPEC) = 5
  setsockopt (5, IPPROTO_TCP, TCP_NODELAY, 0x11fffa4b8=1, 4) = 0
  setsockopt (5, SOL_SOCKET, SO_KEEPALIVE, 0x11fffa4b8=1, 4) = 0
  connect (5, 0x11fff7c10=<2/INET, 6000, 16.176.234.79>, 16) = SIGNAL
[14 SIGALRM]
  -1, Errno 4 (Interrupted system call)

I modified the emacs distribution by setting the timer to 3 seconds and
this has fixed my problem.  I also tested an option where setitimer() is
called after XtOpenDisplay() and this also fixed the problem.

Cheers,
Matt.

Attachment: Xlib trace.txt
Description: Xlib trace.txt

Attachment: Signal Trace.txt
Description: Signal Trace.txt


reply via email to

[Prev in Thread] Current Thread [Next in Thread]