[Top][All Lists]
[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
- Re: non-blocking connect(), Han Boetes, 2004/11/01
- Re: non-blocking connect(),
Kim F. Storm <=
- Re: non-blocking connect(), 山本和彦, 2004/11/01
- Re: non-blocking connect(), Kim F. Storm, 2004/11/01
- Re: non-blocking connect(), 山本和彦, 2004/11/01
- Re: non-blocking connect(), 山本和彦, 2004/11/02
- Re: non-blocking connect(), 山本和彦, 2004/11/08
- Re: non-blocking connect(), Kim F. Storm, 2004/11/09
- Re: non-blocking connect(), 山本和彦, 2004/11/10