summaryrefslogtreecommitdiff
path: root/vio
diff options
context:
space:
mode:
authorTatjana Azundris Nuernberg <tatjana.nuernberg@oracle.com>2012-02-17 19:02:17 +0000
committerTatjana Azundris Nuernberg <tatjana.nuernberg@oracle.com>2012-02-17 19:02:17 +0000
commitda2cc0cdf6ea9b1e689f41307ec118cf05579fc7 (patch)
treeb79a216e0f89da10e47a28ebeda751d7714a878b /vio
parentad72fff9b0efcd772be1fed6fde5e8e357a5f58e (diff)
downloadmariadb-git-da2cc0cdf6ea9b1e689f41307ec118cf05579fc7.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.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/vio/viosocket.c b/vio/viosocket.c
index 024aacc5db2..9633a01f689 100644
--- a/vio/viosocket.c
+++ b/vio/viosocket.c
@@ -23,8 +23,15 @@
the file descriptior.
*/
+#ifdef __WIN__
+ #include <winsock2.h>
+ #include <MSWSock.h>
+ #pragma comment(lib, "ws2_32.lib")
+#endif
#include "vio_priv.h"
+
+
int vio_errno(Vio *vio __attribute__((unused)))
{
return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
@@ -260,6 +267,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;
@@ -272,7 +310,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;