diff options
author | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2009-11-10 17:09:27 -0200 |
---|---|---|
committer | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2009-11-10 17:09:27 -0200 |
commit | 58706b3f7d73b1b1c5fce40b1296670d4e6d3ddf (patch) | |
tree | 7d7b2c23c7122f5a51de6981e2668f74529dce21 /vio | |
parent | 40c127eb441955eac2a32da22c3485570a11a872 (diff) | |
download | mariadb-git-58706b3f7d73b1b1c5fce40b1296670d4e6d3ddf.tar.gz |
Backport of Bug#10374 to mysql-next-mr
------------------------------------------------------------
revno: 2597.37.3
revision-id: sp1r-davi@mysql.com/endora.local-20080328123626-16430
parent: sp1r-anozdrin/alik@quad.opbmk-20080327125300-11290
committer: davi@mysql.com/endora.local
timestamp: Fri 2008-03-28 09:36:26 -0300
message:
Bug#10374 GET_LOCK does not let connection to close on the server side if it's aborted
The problem is that the server doesn't detect aborted connections which
are waiting on a lock or sleeping (user sleep), wasting system resources
for a connection that is already dead.
The solution is to peek at the connection every five seconds to verify if
the connection is not aborted. A aborted connection is detect by polling
the connection socket for available data to be read or end of file and in
case of eof, the wait is aborted and the connection killed.
Diffstat (limited to 'vio')
-rw-r--r-- | vio/viosocket.c | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/vio/viosocket.c b/vio/viosocket.c index 2a22f8c7c15..e83559729b9 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -360,9 +360,24 @@ void vio_in_addr(Vio *vio, struct in_addr *in) my_bool vio_poll_read(Vio *vio,uint timeout) { -#ifndef HAVE_POLL - return 0; -#else +#ifdef __WIN__ + int res, fd= vio->sd; + fd_set readfds, errorfds; + struct timeval tm; + DBUG_ENTER("vio_poll"); + tm.tv_sec= timeout; + tm.tv_usec= 0; + FD_ZERO(&readfds); + FD_ZERO(&errorfds); + FD_SET(fd, &readfds); + FD_SET(fd, &errorfds); + if ((res= select(fd, &readfds, NULL, &errorfds, &tm) <= 0)) + { + DBUG_RETURN(res < 0 ? 0 : 1); + } + res= FD_ISSET(fd, &readfds) || FD_ISSET(fd, &errorfds); + DBUG_RETURN(!res); +#elif defined(HAVE_POLL) struct pollfd fds; int res; DBUG_ENTER("vio_poll"); @@ -373,11 +388,37 @@ my_bool vio_poll_read(Vio *vio,uint timeout) { DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */ } - DBUG_RETURN(fds.revents & POLLIN ? 0 : 1); + DBUG_RETURN(fds.revents & (POLLIN | POLLERR | POLLHUP) ? 0 : 1); +#else + return 0; #endif } +my_bool vio_peek_read(Vio *vio, uint *bytes) +{ +#ifdef __WIN__ + int len; + if (ioctlsocket(vio->sd, FIONREAD, &len)) + return TRUE; + *bytes= len; + return FALSE; +#elif FIONREAD + int len; + if (ioctl(vio->sd, FIONREAD, &len) < 0) + return TRUE; + *bytes= len; + return FALSE; +#else + char buf[1024]; + ssize_t res= recv(vio->sd, &buf, sizeof(buf), MSG_PEEK); + if (res < 0) + return TRUE; + *bytes= res; + return FALSE; +#endif +} + void vio_timeout(Vio *vio, uint which, uint timeout) { #if defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO) |