summaryrefslogtreecommitdiff
path: root/vio
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2017-12-04 18:53:19 +0000
committerVladislav Vaintroub <wlad@mariadb.com>2017-12-11 14:54:17 +0000
commit70d6c944cbc1a71c386db6eaaddc4b10cd8ee99b (patch)
treeb7e445f1ca00c4d62abfe75cb818f3c2a66c44bc /vio
parent8f581e8bf1d400be08995b1cf8c11e3b0f7ae283 (diff)
downloadmariadb-git-70d6c944cbc1a71c386db6eaaddc4b10cd8ee99b.tar.gz
MDEV-14113 Use abortive TCP close, in case server closes the connection
first, and we do not not care whether client has received all data. This is a TCP optimization to avoid TIME_WAIT in TCP connection teardown. This patch would abort connection on timeout, which usually happens when client reads a large result set, at slower pace then the server can write. The patch also cleans up socket timeout handling, so that Windows is consistent with another platforms (using nonblocking socket IO + waiting in poll/select on single socket, rather than setsockopt). This makes identifying timeouts easier. Also removed the superficial shutdown() before closesocket() in a few places where it was used, because it was never needed , and reportedly breaks SO_LINGER on Windows.
Diffstat (limited to 'vio')
-rw-r--r--vio/viosocket.c51
1 files changed, 11 insertions, 40 deletions
diff --git a/vio/viosocket.c b/vio/viosocket.c
index 6be830fee9e..14362625e57 100644
--- a/vio/viosocket.c
+++ b/vio/viosocket.c
@@ -83,6 +83,16 @@ int vio_errno(Vio *vio __attribute__((unused)))
return socket_errno;
}
+static int vio_set_linger(my_socket s, unsigned short timeout_sec)
+{
+ struct linger s_linger;
+ int ret;
+ s_linger.l_onoff = 1;
+ s_linger.l_linger = timeout_sec;
+ ret = setsockopt(s, SOL_SOCKET, SO_LINGER, (const char *)&s_linger, (int)sizeof(s_linger));
+ return ret;
+}
+
/**
Attempt to wait for an I/O event on a socket.
@@ -115,6 +125,7 @@ int vio_socket_io_wait(Vio *vio, enum enum_vio_io_event event)
case 0:
/* The wait timed out. */
ret= -1;
+ vio_set_linger(vio->mysql_socket.fd, 0);
break;
default:
/* A positive value indicates an I/O event. */
@@ -400,43 +411,6 @@ int vio_socket_timeout(Vio *vio,
{
int ret= 0;
DBUG_ENTER("vio_socket_timeout");
-
-#if defined(_WIN32)
- {
- int optname;
- DWORD timeout= 0;
- const char *optval= (const char *) &timeout;
-
- /*
- The default socket timeout value is zero, which means an infinite
- timeout. Values less than 500 milliseconds are interpreted to be of
- 500 milliseconds. Hence, the VIO behavior for zero timeout, which is
- intended to cause the send or receive operation to fail immediately
- if no data is available, is not supported on WIN32 and neither is
- necessary as it's not possible to set the VIO timeout value to zero.
-
- Assert that the VIO timeout is either positive or set to infinite.
- */
- DBUG_ASSERT(which || vio->read_timeout);
- DBUG_ASSERT(!which || vio->write_timeout);
-
- if (which)
- {
- optname= SO_SNDTIMEO;
- if (vio->write_timeout > 0)
- timeout= vio->write_timeout;
- }
- else
- {
- optname= SO_RCVTIMEO;
- if (vio->read_timeout > 0)
- timeout= vio->read_timeout;
- }
-
- ret= mysql_socket_setsockopt(vio->mysql_socket, SOL_SOCKET, optname,
- optval, sizeof(timeout));
- }
-#else
/*
The MSG_DONTWAIT trick is not used with SSL sockets as the send and
receive I/O operations are wrapped through SSL-specific functions
@@ -457,7 +431,6 @@ int vio_socket_timeout(Vio *vio,
if (new_mode != old_mode)
ret= vio_blocking(vio, new_mode, &not_used);
}
-#endif
DBUG_RETURN(ret);
}
@@ -630,8 +603,6 @@ int vio_close(Vio *vio)
vio->type == VIO_TYPE_SSL);
DBUG_ASSERT(mysql_socket_getfd(vio->mysql_socket) >= 0);
- if (mysql_socket_shutdown(vio->mysql_socket, SHUT_RDWR))
- r= -1;
if (mysql_socket_close(vio->mysql_socket))
r= -1;
}