MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
viopipe.c
1 /* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 #include "vio_priv.h"
17 
18 #ifdef _WIN32
19 
20 static size_t wait_overlapped_result(Vio *vio, int timeout)
21 {
22  size_t ret= (size_t) -1;
23  DWORD transferred, wait_status, timeout_ms;
24 
25  timeout_ms= timeout >= 0 ? timeout : INFINITE;
26 
27  /* Wait for the overlapped operation to be completed. */
28  wait_status= WaitForSingleObject(vio->overlapped.hEvent, timeout_ms);
29 
30  /* The operation might have completed, attempt to retrieve the result. */
31  if (wait_status == WAIT_OBJECT_0)
32  {
33  /* If retrieval fails, a error code will have been set. */
34  if (GetOverlappedResult(vio->hPipe, &vio->overlapped, &transferred, FALSE))
35  ret= transferred;
36  }
37  else
38  {
39  /* Error or timeout, cancel the pending I/O operation. */
40  CancelIo(vio->hPipe);
41 
42  /*
43  If the wait timed out, set error code to indicate a
44  timeout error. Otherwise, wait_status is WAIT_FAILED
45  and extended error information was already set.
46  */
47  if (wait_status == WAIT_TIMEOUT)
48  SetLastError(SOCKET_ETIMEDOUT);
49  }
50 
51  return ret;
52 }
53 
54 
55 size_t vio_read_pipe(Vio *vio, uchar *buf, size_t count)
56 {
57  DWORD transferred;
58  size_t ret= (size_t) -1;
59  DBUG_ENTER("vio_read_pipe");
60 
61  /* Attempt to read from the pipe (overlapped I/O). */
62  if (ReadFile(vio->hPipe, buf, count, &transferred, &vio->overlapped))
63  {
64  /* The operation completed immediately. */
65  ret= transferred;
66  }
67  /* Read operation is pending completion asynchronously? */
68  else if (GetLastError() == ERROR_IO_PENDING)
69  ret= wait_overlapped_result(vio, vio->read_timeout);
70 
71  DBUG_RETURN(ret);
72 }
73 
74 
75 size_t vio_write_pipe(Vio *vio, const uchar *buf, size_t count)
76 {
77  DWORD transferred;
78  size_t ret= (size_t) -1;
79  DBUG_ENTER("vio_write_pipe");
80 
81  /* Attempt to write to the pipe (overlapped I/O). */
82  if (WriteFile(vio->hPipe, buf, count, &transferred, &vio->overlapped))
83  {
84  /* The operation completed immediately. */
85  ret= transferred;
86  }
87  /* Write operation is pending completion asynchronously? */
88  else if (GetLastError() == ERROR_IO_PENDING)
89  ret= wait_overlapped_result(vio, vio->write_timeout);
90 
91  DBUG_RETURN(ret);
92 }
93 
94 
95 my_bool vio_is_connected_pipe(Vio *vio)
96 {
97  if (PeekNamedPipe(vio->hPipe, NULL, 0, NULL, NULL, NULL))
98  return TRUE;
99  else
100  return (GetLastError() != ERROR_BROKEN_PIPE);
101 }
102 
103 
104 int vio_shutdown_pipe(Vio *vio)
105 {
106  BOOL ret;
107  DBUG_ENTER("vio_shutdown_pipe");
108 
109  CancelIo(vio->hPipe);
110  CloseHandle(vio->overlapped.hEvent);
111  DisconnectNamedPipe(vio->hPipe);
112  ret= CloseHandle(vio->hPipe);
113 
114  vio->inactive= TRUE;
115  vio->hPipe= NULL;
116  vio->mysql_socket= MYSQL_INVALID_SOCKET;
117 
118  DBUG_RETURN(ret);
119 }
120 
121 #endif
122