mirror of
https://github.com/MariaDB/server.git
synced 2025-01-30 18:41:56 +01:00
Better fix for connect timeout problem.
This commit is contained in:
parent
9277579c96
commit
1101613414
1 changed files with 37 additions and 34 deletions
|
@ -121,15 +121,16 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
|
||||||
#if defined(__WIN__) || defined(OS2)
|
#if defined(__WIN__) || defined(OS2)
|
||||||
return connect(s, (struct sockaddr*) name, namelen);
|
return connect(s, (struct sockaddr*) name, namelen);
|
||||||
#else
|
#else
|
||||||
int flags, res, s_err, result=0;
|
int flags, res, s_err;
|
||||||
SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
|
SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
|
||||||
fd_set sfds;
|
fd_set sfds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
time_t start_time, now_time;
|
time_t start_time, now_time;
|
||||||
|
|
||||||
/* If they passed us a timeout of zero, we should behave
|
/*
|
||||||
* exactly like the normal connect() call does.
|
If they passed us a timeout of zero, we should behave
|
||||||
*/
|
exactly like the normal connect() call does.
|
||||||
|
*/
|
||||||
|
|
||||||
if (timeout == 0)
|
if (timeout == 0)
|
||||||
return connect(s, (struct sockaddr*) name, namelen);
|
return connect(s, (struct sockaddr*) name, namelen);
|
||||||
|
@ -150,30 +151,31 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
|
||||||
if (res == 0) /* Connected quickly! */
|
if (res == 0) /* Connected quickly! */
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
/* Otherwise, our connection is "in progress." We can use
|
/*
|
||||||
* the select() call to wait up to a specified period of time
|
Otherwise, our connection is "in progress." We can use
|
||||||
* for the connection to suceed. If select() returns 0
|
the select() call to wait up to a specified period of time
|
||||||
* (after waiting howevermany seconds), our socket never became
|
for the connection to suceed. If select() returns 0
|
||||||
* writable (host is probably unreachable.) Otherwise, if
|
(after waiting howevermany seconds), our socket never became
|
||||||
* select() returns 1, then one of two conditions exist:
|
writable (host is probably unreachable.) Otherwise, if
|
||||||
*
|
select() returns 1, then one of two conditions exist:
|
||||||
* 1. An error occured. We use getsockopt() to check for this.
|
|
||||||
* 2. The connection was set up sucessfully: getsockopt() will
|
1. An error occured. We use getsockopt() to check for this.
|
||||||
* return 0 as an error.
|
2. The connection was set up sucessfully: getsockopt() will
|
||||||
*
|
return 0 as an error.
|
||||||
* Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
|
|
||||||
* who posted this method of timing out a connect() in
|
Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
|
||||||
* comp.unix.programmer on August 15th, 1997.
|
who posted this method of timing out a connect() in
|
||||||
*/
|
comp.unix.programmer on August 15th, 1997.
|
||||||
|
*/
|
||||||
|
|
||||||
FD_ZERO(&sfds);
|
FD_ZERO(&sfds);
|
||||||
FD_SET(s, &sfds);
|
FD_SET(s, &sfds);
|
||||||
/*
|
/*
|
||||||
* select could be interrupted by a signal, and if it is,
|
select could be interrupted by a signal, and if it is,
|
||||||
* the timeout should be adjusted and the select restarted
|
the timeout should be adjusted and the select restarted
|
||||||
* to work around OSes that don't restart select and
|
to work around OSes that don't restart select and
|
||||||
* implementations of select that don't adjust tv upon
|
implementations of select that don't adjust tv upon
|
||||||
* failure to reflect the time remaining
|
failure to reflect the time remaining
|
||||||
*/
|
*/
|
||||||
start_time = time(NULL);
|
start_time = time(NULL);
|
||||||
for (;;)
|
for (;;)
|
||||||
|
@ -181,22 +183,25 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
|
||||||
tv.tv_sec = (long) timeout;
|
tv.tv_sec = (long) timeout;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
#if defined(HPUX) && defined(THREAD)
|
#if defined(HPUX) && defined(THREAD)
|
||||||
if ((result = select(s+1, NULL, (int*) &sfds, NULL, &tv)) >= 0)
|
if ((res = select(s+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
if ((result = select(s+1, NULL, &sfds, NULL, &tv)) >= 0)
|
if ((res = select(s+1, NULL, &sfds, NULL, &tv)) > 0)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
if (res == 0) /* timeout */
|
||||||
|
return -1;
|
||||||
now_time=time(NULL);
|
now_time=time(NULL);
|
||||||
timeout-= (uint) (now_time - start_time);
|
timeout-= (uint) (now_time - start_time);
|
||||||
if (errno != EINTR || (int) timeout <= 0)
|
if (errno != EINTR || (int) timeout <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* select() returned something more interesting than zero, let's
|
/*
|
||||||
* see if we have any errors. If the next two statements pass,
|
select() returned something more interesting than zero, let's
|
||||||
* we've got an open socket!
|
see if we have any errors. If the next two statements pass,
|
||||||
*/
|
we've got an open socket!
|
||||||
|
*/
|
||||||
|
|
||||||
s_err=0;
|
s_err=0;
|
||||||
if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
|
if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
|
||||||
|
@ -207,10 +212,8 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
|
||||||
errno = s_err;
|
errno = s_err;
|
||||||
return(-1); /* but return an error... */
|
return(-1); /* but return an error... */
|
||||||
}
|
}
|
||||||
if (res && result > 0)
|
return (0); /* ok */
|
||||||
result=res=0; // We did it in select() !!!
|
|
||||||
|
|
||||||
return((res) ? res : result); /* It's all good! */
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue