summaryrefslogtreecommitdiff
path: root/vio
diff options
context:
space:
mode:
authorTatjana Azundris Nuernberg <tatjana.nuernberg@oracle.com>2012-02-19 09:00:52 +0000
committerTatjana Azundris Nuernberg <tatjana.nuernberg@oracle.com>2012-02-19 09:00:52 +0000
commit9965af5c6a13d3c0ab87529f8168b4b1b2473f0c (patch)
tree0025bc00c07e133e19f181fe8986af401208fcc5 /vio
parentdf2263533724a3dcefd7ce64f1afc87b83419faa (diff)
parent108445549bf0f9428ae714cfe41266f34adf12f8 (diff)
downloadmariadb-git-9965af5c6a13d3c0ab87529f8168b4b1b2473f0c.tar.gz
BUG#13431369 - MAIN.VARIABLES-NOTEMBEDDED CRASHES THE SERVER SPORADICALLY ON WINDOWS
On shutdown(), Windows can drop traffic still queued for sending even if that wasn't specifically requested. As a result, fatal errors (those after signaling which the server will drop the connection) were sometimes only seen as "connection lost" on the client side, because the server-side shutdown() erraneously discarded the correct error message before sending it. If on Windows, we now use the Windows API to access the (non-broken) equivalent of shutdown(). Backport from trunk
Diffstat (limited to 'vio')
-rw-r--r--vio/viosocket.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/vio/viosocket.c b/vio/viosocket.c
index 6031cf6a795..f209e056caf 100644
--- a/vio/viosocket.c
+++ b/vio/viosocket.c
@@ -23,6 +23,11 @@
the file descriptior.
*/
+#ifdef __WIN__
+ #include <winsock2.h>
+ #include <MSWSock.h>
+ #pragma comment(lib, "ws2_32.lib")
+#endif
#include "vio_priv.h"
#ifdef FIONREAD_IN_SYS_FILIO
@@ -277,6 +282,37 @@ vio_was_interrupted(Vio *vio __attribute__((unused)))
}
+int
+mysql_socket_shutdown(my_socket mysql_socket, int how)
+{
+ int result;
+
+#ifdef __WIN__
+ static LPFN_DISCONNECTEX DisconnectEx = NULL;
+ if (DisconnectEx == NULL)
+ {
+ DWORD dwBytesReturned;
+ GUID guidDisconnectEx = WSAID_DISCONNECTEX;
+ WSAIoctl(mysql_socket, SIO_GET_EXTENSION_FUNCTION_POINTER,
+ &guidDisconnectEx, sizeof(GUID),
+ &DisconnectEx, sizeof(DisconnectEx),
+ &dwBytesReturned, NULL, NULL);
+ }
+#endif
+
+ /* Non instrumented code */
+#ifdef __WIN__
+ if (DisconnectEx)
+ result= (DisconnectEx(mysql_socket, (LPOVERLAPPED) NULL,
+ (DWORD) 0, (DWORD) 0) == TRUE) ? 0 : -1;
+ else
+#endif
+ result= shutdown(mysql_socket, how);
+
+ return result;
+}
+
+
int vio_close(Vio * vio)
{
int r=0;
@@ -289,7 +325,7 @@ int vio_close(Vio * vio)
vio->type == VIO_TYPE_SSL);
DBUG_ASSERT(vio->sd >= 0);
- if (shutdown(vio->sd, SHUT_RDWR))
+ if (mysql_socket_shutdown(vio->sd, SHUT_RDWR))
r= -1;
if (closesocket(vio->sd))
r= -1;