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

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

Re: non-blocking connect()


From: Kim F. Storm
Subject: Re: non-blocking connect()
Date: Mon, 01 Nov 2004 12:09:46 +0100
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/21.3.50 (gnu/linux)

Kazu Yamamoto (山本和彦) <address@hidden> writes:

> [description]
>
> Due to implementation flaw of src/process.c/make_network_process(),
> open-network-stream() occasionally fails to make a TCP connection on
> BSD variants.
>
> [analysis]
>
> I don't know why but connect(2) in make_network_process() on Emacs
> 21.3.50 is occasionally interrupted by signals. (Some friends and I
> met this phenomenon on Emacs 21.3.5 but we did not experience this on
> Emacs 21.3).

That's strange, indeed.  Maybe SIGIO is used on *BSD now.

>
> When connect(2) is interrupted, it retunrs EINTR. In this case,
> make_network_process() tries connect(2) again with the same socket
> (retry_connect:).
>
> In many cases, this results in EADDRINUSE on FreeBSD and in EALREADY
> on NetBSD. If EADDRINUSE is returned, make_network_process() sleeps
> one second and goes to retry_connect:.
>
> Since the current make_network_process() does not handle EALREADY, a
> TCP connection cannot be established on NetBSD if connect(2) is
> interrupted.
>
> Even on FreeBSD, it takes several seconds to make a TCP connection.

Here is a different patch which uses a new socket when retrying.

AFAICS, that should avoid the EADDRINUSE and EALREADY error codes ever
occurring on BSD.


*** process.c   01 Nov 2004 11:55:50 +0100      1.443
--- process.c   01 Nov 2004 12:07:52 +0100      
***************
*** 3023,3028 ****
--- 3023,3030 ----
      {
        int optn, optbits;
  
+     retry_connect:
+ 
        s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol);
        if (s < 0)
        {
***************
*** 3101,3108 ****
          break;
        }
  
-     retry_connect:
- 
        immediate_quit = 1;
        QUIT;
  
--- 3103,3108 ----
***************
*** 3144,3151 ****
--- 3144,3157 ----
  
        immediate_quit = 0;
  
+       /* Discard the unwind protect closing S.  */
+       specpdl_ptr = specpdl + count1;
+       emacs_close (s);
+       s = -1;
+ 
        if (xerrno == EINTR)
        goto retry_connect;
+ #if 0
        if (xerrno == EADDRINUSE && retry < 20)
        {
          /* A delay here is needed on some FreeBSD systems,
***************
*** 3155,3165 ****
          retry++;
          goto retry_connect;
        }
! 
!       /* Discard the unwind protect closing S.  */
!       specpdl_ptr = specpdl + count1;
!       emacs_close (s);
!       s = -1;
      }
  
    if (s >= 0)
--- 3161,3167 ----
          retry++;
          goto retry_connect;
        }
! #endif
      }
  
    if (s >= 0)


--
Kim F. Storm  http://www.cua.dk





reply via email to

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