summaryrefslogtreecommitdiff
path: root/vio
diff options
context:
space:
mode:
authorDavi Arnaut <Davi.Arnaut@Sun.COM>2009-11-10 17:09:27 -0200
committerDavi Arnaut <Davi.Arnaut@Sun.COM>2009-11-10 17:09:27 -0200
commit58706b3f7d73b1b1c5fce40b1296670d4e6d3ddf (patch)
tree7d7b2c23c7122f5a51de6981e2668f74529dce21 /vio
parent40c127eb441955eac2a32da22c3485570a11a872 (diff)
downloadmariadb-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.c49
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)