From 71015d844e3f25a0c4eada9827a1dad464a4fdce Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 28 Jul 2020 15:59:38 +0200 Subject: MDEV-21101 unexpected wait_timeout with pool-of-threads Due to restricted size of the threadpool, execution of client queries can be delayed (queued) for a while. This delay was interpreted as client inactivity, and connection is closed, if client idle time + queue time exceeds wait_timeout. But users did not expect queue time to be included into wait_timeout. This patch changes the behavior. We don't close connection anymore, if there is some unread data present on connection, even if wait_timeout is exceeded. Unread data means that client was not idle, it sent a query, which we did not have time to process yet. --- vio/vio_priv.h | 1 + vio/viopipe.c | 6 ++++++ vio/viosocket.c | 29 ++++++++++++++++++++--------- 3 files changed, 27 insertions(+), 9 deletions(-) (limited to 'vio') diff --git a/vio/vio_priv.h b/vio/vio_priv.h index 71a0468e226..6780ec5664a 100644 --- a/vio/vio_priv.h +++ b/vio/vio_priv.h @@ -33,6 +33,7 @@ my_bool vio_is_connected_pipe(Vio *vio); int vio_close_pipe(Vio * vio); int cancel_io(HANDLE handle, DWORD thread_id); int vio_shutdown_pipe(Vio *vio,int how); +uint vio_pending_pipe(Vio* vio); #endif #ifdef HAVE_SMEM diff --git a/vio/viopipe.c b/vio/viopipe.c index 84643935c13..5007599aa17 100644 --- a/vio/viopipe.c +++ b/vio/viopipe.c @@ -141,5 +141,11 @@ int vio_close_pipe(Vio *vio) DBUG_RETURN(ret); } +/* return number of bytes readable from pipe.*/ +uint vio_pending_pipe(Vio *vio) +{ + DWORD bytes; + return PeekNamedPipe(vio->hPipe, NULL, 0, NULL, &bytes, NULL) ? bytes : 0; +} #endif diff --git a/vio/viosocket.c b/vio/viosocket.c index d1a3eeb5c0d..6409aeb9899 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -1214,7 +1214,6 @@ my_bool vio_is_connected(Vio *vio) DBUG_RETURN(bytes ? TRUE : FALSE); } -#ifndef DBUG_OFF /** Number of bytes in the read or socket buffer @@ -1233,22 +1232,34 @@ ssize_t vio_pending(Vio *vio) return vio->read_end - vio->read_pos; /* Skip non-socket based transport types. */ - if (vio->type == VIO_TYPE_TCPIP || vio->type == VIO_TYPE_SOCKET) + switch (vio->type) { + case VIO_TYPE_TCPIP: + /* fallthrough */ + case VIO_TYPE_SOCKET: /* Obtain number of readable bytes in the socket buffer. */ if (socket_peek_read(vio, &bytes)) return -1; - } + return bytes; - /* - SSL not checked due to a yaSSL bug in SSL_pending that - causes it to attempt to read from the socket. - */ + case VIO_TYPE_SSL: + bytes= (uint) SSL_pending(vio->ssl_arg); + if (bytes) + return bytes; + if (socket_peek_read(vio, &bytes)) + return -1; + return bytes; - return (ssize_t) bytes; +#ifdef _WIN32 + case VIO_TYPE_NAMEDPIPE: + bytes= vio_pending_pipe(vio); + return bytes; +#endif + default: + return -1; + } } -#endif /* DBUG_OFF */ /** Checks if the error code, returned by vio_getnameinfo(), means it was the -- cgit v1.2.1