1 /* Copyright (c) 2010, 2021, Oracle and/or its affiliates.
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, version 2.0,
5 as published by the Free Software Foundation.
6 
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation.  The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License, version 2.0, for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 02110-1301  USA
23 */
24 
25 #ifndef MYSQL_SOCKET_H
26 #define MYSQL_SOCKET_H
27 
28 /* For strlen() */
29 #include <string.h>
30 /* For MY_STAT */
31 #include <my_dir.h>
32 /* For my_chsize */
33 #include <my_sys.h>
34 /* For socket api */
35 #ifdef _WIN32
36   #include <ws2def.h>
37   #include <winsock2.h>
38   #include <MSWSock.h>
39   #define SOCKBUF_T char
40 #else
41   #include <netinet/in.h>
42   #define SOCKBUF_T void
43 #endif
44 /**
45   @file mysql/psi/mysql_socket.h
46 [...]
47 */
48 
49 #include "mysql/psi/psi.h"
50 
51 #ifndef PSI_SOCKET_CALL
52 #define PSI_SOCKET_CALL(M) PSI_DYNAMIC_CALL(M)
53 #endif
54 
55 /**
56   @defgroup Socket_instrumentation Socket Instrumentation
57   @ingroup Instrumentation_interface
58   @{
59 */
60 
61 /**
62   @def mysql_socket_register(P1, P2, P3)
63   Socket registration.
64 */
65 #ifdef HAVE_PSI_SOCKET_INTERFACE
66   #define mysql_socket_register(P1, P2, P3) \
67     inline_mysql_socket_register(P1, P2, P3)
68 #else
69   #define mysql_socket_register(P1, P2, P3) \
70     do {} while (0)
71 #endif
72 
73 /** An instrumented socket. */
74 struct st_mysql_socket
75 {
76   /** The real socket descriptor. */
77   my_socket fd;
78 
79   /**
80     The instrumentation hook.
81     Note that this hook is not conditionally defined,
82     for binary compatibility of the @c MYSQL_SOCKET interface.
83   */
84   struct PSI_socket *m_psi;
85 };
86 
87 /**
88   An instrumented socket.
89   @c MYSQL_SOCKET is a replacement for @c my_socket.
90 */
91 typedef struct st_mysql_socket MYSQL_SOCKET;
92 
93 
94 /**
95   @def MYSQL_INVALID_SOCKET
96   MYSQL_SOCKET initial value.
97 */
98 //MYSQL_SOCKET MYSQL_INVALID_SOCKET= {INVALID_SOCKET, NULL};
99 #define MYSQL_INVALID_SOCKET mysql_socket_invalid()
100 
101 /**
102   MYSQL_SOCKET helper. Initialize instrumented socket.
103   @sa mysql_socket_getfd
104   @sa mysql_socket_setfd
105 */
106 static inline MYSQL_SOCKET
mysql_socket_invalid()107 mysql_socket_invalid()
108 {
109   MYSQL_SOCKET mysql_socket= {INVALID_SOCKET, NULL};
110   return mysql_socket;
111 }
112 
113 /**
114   Set socket descriptor and address.
115   @param socket nstrumented socket
116   @param addr unformatted socket address
117   @param addr_len length of socket addres
118 */
119 
120 static inline void
mysql_socket_set_address(MYSQL_SOCKET socket,const struct sockaddr * addr,socklen_t addr_len)121 mysql_socket_set_address(
122 #ifdef HAVE_PSI_SOCKET_INTERFACE
123   MYSQL_SOCKET socket,
124   const struct sockaddr *addr,
125   socklen_t addr_len
126 #else
127   MYSQL_SOCKET socket MY_ATTRIBUTE ((unused)),
128   const struct sockaddr *addr MY_ATTRIBUTE ((unused)),
129   socklen_t addr_len MY_ATTRIBUTE ((unused))
130 #endif
131 )
132 {
133 #ifdef HAVE_PSI_SOCKET_INTERFACE
134   if (socket.m_psi != NULL)
135     PSI_SOCKET_CALL(set_socket_info)(socket.m_psi, NULL, addr, addr_len);
136 #endif
137 }
138 
139 /**
140   Set socket descriptor and address.
141   @param socket instrumented socket
142 */
143 static inline void
mysql_socket_set_thread_owner(MYSQL_SOCKET socket)144 mysql_socket_set_thread_owner(
145 #ifdef HAVE_PSI_SOCKET_INTERFACE
146 MYSQL_SOCKET socket
147 #else
148 MYSQL_SOCKET socket MY_ATTRIBUTE ((unused))
149 #endif
150 )
151 {
152 #ifdef HAVE_PSI_SOCKET_INTERFACE
153   if (socket.m_psi != NULL)
154     PSI_SOCKET_CALL(set_socket_thread_owner)(socket.m_psi);
155 #endif
156 }
157 
158 /**
159   MYSQL_SOCKET helper. Get socket descriptor.
160   @param mysql_socket Instrumented socket
161   @sa mysql_socket_setfd
162 */
163 static inline my_socket
mysql_socket_getfd(MYSQL_SOCKET mysql_socket)164 mysql_socket_getfd(MYSQL_SOCKET mysql_socket)
165 {
166   return mysql_socket.fd;
167 }
168 
169 /**
170   MYSQL_SOCKET helper. Set socket descriptor.
171   @param mysql_socket Instrumented socket
172   @param fd Socket descriptor
173   @sa mysql_socket_getfd
174 */
175 static inline void
mysql_socket_setfd(MYSQL_SOCKET * mysql_socket,my_socket fd)176 mysql_socket_setfd(MYSQL_SOCKET *mysql_socket, my_socket fd)
177 {
178   if (likely(mysql_socket != NULL))
179     mysql_socket->fd= fd;
180 }
181 
182 /**
183   @def MYSQL_SOCKET_WAIT_VARIABLES
184   Instrumentation helper for socket waits.
185   This instrumentation declares local variables.
186   Do not use a ';' after this macro
187   @param LOCKER locker
188   @param STATE locker state
189   @sa MYSQL_START_SOCKET_WAIT.
190   @sa MYSQL_END_SOCKET_WAIT.
191 */
192 #ifdef HAVE_PSI_SOCKET_INTERFACE
193   #define MYSQL_SOCKET_WAIT_VARIABLES(LOCKER, STATE) \
194     struct PSI_socket_locker* LOCKER; \
195     PSI_socket_locker_state STATE;
196 #else
197   #define MYSQL_SOCKET_WAIT_VARIABLES(LOCKER, STATE)
198 #endif
199 
200 /**
201   @def MYSQL_START_SOCKET_WAIT
202   Instrumentation helper for socket waits.
203   This instrumentation marks the start of a wait event.
204   @param LOCKER locker
205   @param STATE locker state
206   @param SOCKET instrumented socket
207   @param OP The socket operation to be performed
208   @param COUNT bytes to be written/read
209   @sa MYSQL_END_SOCKET_WAIT.
210 */
211 #ifdef HAVE_PSI_SOCKET_INTERFACE
212   #define MYSQL_START_SOCKET_WAIT(LOCKER, STATE, SOCKET, OP, COUNT) \
213     LOCKER= inline_mysql_start_socket_wait(STATE, SOCKET, OP, COUNT,\
214                                            __FILE__, __LINE__)
215 #else
216   #define MYSQL_START_SOCKET_WAIT(LOCKER, STATE, SOCKET, OP, COUNT) \
217     do {} while (0)
218 #endif
219 
220 /**
221   @def MYSQL_END_SOCKET_WAIT
222   Instrumentation helper for socket waits.
223   This instrumentation marks the end of a wait event.
224   @param LOCKER locker
225   @param COUNT actual bytes written/read, or -1
226   @sa MYSQL_START_SOCKET_WAIT.
227 */
228 #ifdef HAVE_PSI_SOCKET_INTERFACE
229   #define MYSQL_END_SOCKET_WAIT(LOCKER, COUNT) \
230     inline_mysql_end_socket_wait(LOCKER, COUNT)
231 #else
232   #define MYSQL_END_SOCKET_WAIT(LOCKER, COUNT) \
233     do {} while (0)
234 #endif
235 
236 /**
237   @def MYSQL_SOCKET_SET_STATE
238   Set the state (IDLE, ACTIVE) of an instrumented socket.
239   @param SOCKET the instrumented socket
240   @param STATE the new state
241   @sa PSI_socket_state
242 */
243 #ifdef HAVE_PSI_SOCKET_INTERFACE
244   #define MYSQL_SOCKET_SET_STATE(SOCKET, STATE) \
245     inline_mysql_socket_set_state(SOCKET, STATE)
246 #else
247   #define MYSQL_SOCKET_SET_STATE(SOCKET, STATE) \
248     do {} while (0)
249 #endif
250 
251 #ifdef HAVE_PSI_SOCKET_INTERFACE
252 /**
253   Instrumentation calls for MYSQL_START_SOCKET_WAIT.
254   @sa MYSQL_START_SOCKET_WAIT.
255 */
256 static inline struct PSI_socket_locker*
inline_mysql_start_socket_wait(PSI_socket_locker_state * state,MYSQL_SOCKET mysql_socket,enum PSI_socket_operation op,size_t byte_count,const char * src_file,int src_line)257 inline_mysql_start_socket_wait(PSI_socket_locker_state *state,
258                                MYSQL_SOCKET mysql_socket,
259                                enum PSI_socket_operation op,
260                                size_t byte_count,
261                                const char *src_file, int src_line)
262 {
263   struct PSI_socket_locker *locker;
264   if (mysql_socket.m_psi != NULL)
265   {
266     locker= PSI_SOCKET_CALL(start_socket_wait)
267       (state, mysql_socket.m_psi, op, byte_count, src_file, src_line);
268   }
269   else
270     locker= NULL;
271   return locker;
272 }
273 
274 /**
275   Instrumentation calls for MYSQL_END_SOCKET_WAIT.
276   @sa MYSQL_END_SOCKET_WAIT.
277 */
278 static inline void
inline_mysql_end_socket_wait(struct PSI_socket_locker * locker,size_t byte_count)279 inline_mysql_end_socket_wait(struct PSI_socket_locker *locker, size_t byte_count)
280 {
281   if (locker != NULL)
282     PSI_SOCKET_CALL(end_socket_wait)(locker, byte_count);
283 }
284 
285 /**
286   Set the state (IDLE, ACTIVE) of an instrumented socket.
287   @param socket the instrumented socket
288   @param state the new state
289   @sa PSI_socket_state
290 */
291 static inline void
inline_mysql_socket_set_state(MYSQL_SOCKET socket,enum PSI_socket_state state)292 inline_mysql_socket_set_state(MYSQL_SOCKET socket, enum PSI_socket_state state)
293 {
294   if (socket.m_psi != NULL)
295     PSI_SOCKET_CALL(set_socket_state)(socket.m_psi, state);
296 }
297 #endif /* HAVE_PSI_SOCKET_INTERFACE */
298 
299 /**
300   @def mysql_socket_socket(K, D, T, P)
301   Create a socket.
302   @c mysql_socket_socket is a replacement for @c socket.
303   @param K PSI_socket_key for this instrumented socket
304   @param D Socket domain
305   @param T Protocol type
306   @param P Transport protocol
307 */
308 
309 #ifdef HAVE_PSI_SOCKET_INTERFACE
310   #define mysql_socket_socket(K, D, T, P) \
311     inline_mysql_socket_socket(K, D, T, P)
312 #else
313   #define mysql_socket_socket(K, D, T, P) \
314     inline_mysql_socket_socket(D, T, P)
315 #endif
316 
317 /**
318   @def mysql_socket_bind(FD, AP, L)
319   Bind a socket to a local port number and IP address
320   @c mysql_socket_bind is a replacement for @c bind.
321   @param FD Instrumented socket descriptor returned by socket()
322   @param AP Pointer to local port number and IP address in sockaddr structure
323   @param L  Length of sockaddr structure
324 */
325 #ifdef HAVE_PSI_SOCKET_INTERFACE
326   #define mysql_socket_bind(FD, AP, L) \
327     inline_mysql_socket_bind(__FILE__, __LINE__, FD, AP, L)
328 #else
329   #define mysql_socket_bind(FD, AP, L) \
330     inline_mysql_socket_bind(FD, AP, L)
331 #endif
332 
333 /**
334   @def mysql_socket_getsockname(FD, AP, LP)
335   Return port number and IP address of the local host
336   @c mysql_socket_getsockname is a replacement for @c getsockname.
337   @param FD Instrumented socket descriptor returned by socket()
338   @param AP  Pointer to returned address of local host in @c sockaddr structure
339   @param LP  Pointer to length of @c sockaddr structure
340 */
341 #ifdef HAVE_PSI_SOCKET_INTERFACE
342   #define mysql_socket_getsockname(FD, AP, LP) \
343     inline_mysql_socket_getsockname(__FILE__, __LINE__, FD, AP, LP)
344 #else
345   #define mysql_socket_getsockname(FD, AP, LP) \
346     inline_mysql_socket_getsockname(FD, AP, LP)
347 #endif
348 
349 /**
350   @def mysql_socket_connect(FD, AP, L)
351   Establish a connection to a remote host.
352   @c mysql_socket_connect is a replacement for @c connect.
353   @param FD Instrumented socket descriptor returned by socket()
354   @param AP Pointer to target address in sockaddr structure
355   @param L  Length of sockaddr structure
356 */
357 #ifdef HAVE_PSI_SOCKET_INTERFACE
358   #define mysql_socket_connect(FD, AP, L) \
359     inline_mysql_socket_connect(__FILE__, __LINE__, FD, AP, L)
360 #else
361   #define mysql_socket_connect(FD, AP, L) \
362     inline_mysql_socket_connect(FD, AP, L)
363 #endif
364 
365 /**
366   @def mysql_socket_getpeername(FD, AP, LP)
367   Get port number and IP address of remote host that a socket is connected to.
368   @c mysql_socket_getpeername is a replacement for @c getpeername.
369   @param FD Instrumented socket descriptor returned by socket() or accept()
370   @param AP Pointer to returned address of remote host in sockaddr structure
371   @param LP Pointer to length of sockaddr structure
372 */
373 #ifdef HAVE_PSI_SOCKET_INTERFACE
374   #define mysql_socket_getpeername(FD, AP, LP) \
375     inline_mysql_socket_getpeername(__FILE__, __LINE__, FD, AP, LP)
376 #else
377   #define mysql_socket_getpeername(FD, AP, LP) \
378     inline_mysql_socket_getpeername(FD, AP, LP)
379 #endif
380 
381 /**
382   @def mysql_socket_send(FD, B, N, FL)
383   Send data from the buffer, B, to a connected socket.
384   @c mysql_socket_send is a replacement for @c send.
385   @param FD Instrumented socket descriptor returned by socket() or accept()
386   @param B  Buffer to send
387   @param N  Number of bytes to send
388   @param FL Control flags
389 */
390 #ifdef HAVE_PSI_SOCKET_INTERFACE
391   #define mysql_socket_send(FD, B, N, FL) \
392     inline_mysql_socket_send(__FILE__, __LINE__, FD, B, N, FL)
393 #else
394   #define mysql_socket_send(FD, B, N, FL) \
395     inline_mysql_socket_send(FD, B, N, FL)
396 #endif
397 
398 /**
399   @def mysql_socket_recv(FD, B, N, FL)
400   Receive data from a connected socket.
401   @c mysql_socket_recv is a replacement for @c recv.
402   @param FD Instrumented socket descriptor returned by socket() or accept()
403   @param B  Buffer to receive to
404   @param N  Maximum bytes to receive
405   @param FL Control flags
406 */
407 #ifdef HAVE_PSI_SOCKET_INTERFACE
408   #define mysql_socket_recv(FD, B, N, FL) \
409     inline_mysql_socket_recv(__FILE__, __LINE__, FD, B, N, FL)
410 #else
411   #define mysql_socket_recv(FD, B, N, FL) \
412     inline_mysql_socket_recv(FD, B, N, FL)
413 #endif
414 
415 /**
416   @def mysql_socket_sendto(FD, B, N, FL, AP, L)
417   Send data to a socket at the specified address.
418   @c mysql_socket_sendto is a replacement for @c sendto.
419   @param FD Instrumented socket descriptor returned by socket()
420   @param B  Buffer to send
421   @param N  Number of bytes to send
422   @param FL Control flags
423   @param AP Pointer to destination sockaddr structure
424   @param L  Size of sockaddr structure
425 */
426 #ifdef HAVE_PSI_SOCKET_INTERFACE
427   #define mysql_socket_sendto(FD, B, N, FL, AP, L) \
428     inline_mysql_socket_sendto(__FILE__, __LINE__, FD, B, N, FL, AP, L)
429 #else
430   #define mysql_socket_sendto(FD, B, N, FL, AP, L) \
431     inline_mysql_socket_sendto(FD, B, N, FL, AP, L)
432 #endif
433 
434 /**
435   @def mysql_socket_recvfrom(FD, B, N, FL, AP, L)
436   Receive data from a socket and return source address information
437   @c mysql_socket_recvfrom is a replacement for @c recvfrom.
438   @param FD Instrumented socket descriptor returned by socket()
439   @param B  Buffer to receive to
440   @param N  Maximum bytes to receive
441   @param FL Control flags
442   @param AP Pointer to source address in sockaddr_storage structure
443   @param LP Size of sockaddr_storage structure
444 */
445 #ifdef HAVE_PSI_SOCKET_INTERFACE
446   #define mysql_socket_recvfrom(FD, B, N, FL, AP, LP) \
447     inline_mysql_socket_recvfrom(__FILE__, __LINE__, FD, B, N, FL, AP, LP)
448 #else
449   #define mysql_socket_recvfrom(FD, B, N, FL, AP, LP) \
450     inline_mysql_socket_recvfrom(FD, B, N, FL, AP, LP)
451 #endif
452 
453 /**
454   @def mysql_socket_getsockopt(FD, LV, ON, OP, OL)
455   Get a socket option for the specified socket.
456   @c mysql_socket_getsockopt is a replacement for @c getsockopt.
457   @param FD Instrumented socket descriptor returned by socket()
458   @param LV Protocol level
459   @param ON Option to query
460   @param OP Buffer which will contain the value for the requested option
461   @param OL Pointer to length of OP
462 */
463 #ifdef HAVE_PSI_SOCKET_INTERFACE
464   #define mysql_socket_getsockopt(FD, LV, ON, OP, OL) \
465     inline_mysql_socket_getsockopt(__FILE__, __LINE__, FD, LV, ON, OP, OL)
466 #else
467   #define mysql_socket_getsockopt(FD, LV, ON, OP, OL) \
468     inline_mysql_socket_getsockopt(FD, LV, ON, OP, OL)
469 #endif
470 
471 /**
472   @def mysql_socket_setsockopt(FD, LV, ON, OP, OL)
473   Set a socket option for the specified socket.
474   @c mysql_socket_setsockopt is a replacement for @c setsockopt.
475   @param FD Instrumented socket descriptor returned by socket()
476   @param LV Protocol level
477   @param ON Option to modify
478   @param OP Buffer containing the value for the specified option
479   @param OL Pointer to length of OP
480 */
481 #ifdef HAVE_PSI_SOCKET_INTERFACE
482   #define mysql_socket_setsockopt(FD, LV, ON, OP, OL) \
483     inline_mysql_socket_setsockopt(__FILE__, __LINE__, FD, LV, ON, OP, OL)
484 #else
485   #define mysql_socket_setsockopt(FD, LV, ON, OP, OL) \
486     inline_mysql_socket_setsockopt(FD, LV, ON, OP, OL)
487 #endif
488 
489 /**
490   @def mysql_sock_set_nonblocking
491   Set socket to non-blocking.
492   @param FD instrumented socket descriptor
493 */
494 #ifdef HAVE_PSI_SOCKET_INTERFACE
495   #define mysql_sock_set_nonblocking(FD) \
496     inline_mysql_sock_set_nonblocking(__FILE__, __LINE__, FD)
497 #else
498   #define mysql_sock_set_nonblocking(FD) \
499     inline_mysql_sock_set_nonblocking(FD)
500 #endif
501 
502 /**
503   @def mysql_socket_listen(FD, N)
504   Set socket state to listen for an incoming connection.
505   @c mysql_socket_listen is a replacement for @c listen.
506   @param FD Instrumented socket descriptor, bound and connected
507   @param N  Maximum number of pending connections allowed.
508 */
509 #ifdef HAVE_PSI_SOCKET_INTERFACE
510   #define mysql_socket_listen(FD, N) \
511     inline_mysql_socket_listen(__FILE__, __LINE__, FD, N)
512 #else
513   #define mysql_socket_listen(FD, N) \
514     inline_mysql_socket_listen(FD, N)
515 #endif
516 
517 /**
518   @def mysql_socket_accept(K, FD, AP, LP)
519   Accept a connection from any remote host; TCP only.
520   @c mysql_socket_accept is a replacement for @c accept.
521   @param K PSI_socket_key for this instrumented socket
522   @param FD Instrumented socket descriptor, bound and placed in a listen state
523   @param AP Pointer to sockaddr structure with returned IP address and port of connected host
524   @param LP Pointer to length of valid information in AP
525 */
526 #ifdef HAVE_PSI_SOCKET_INTERFACE
527   #define mysql_socket_accept(K, FD, AP, LP) \
528     inline_mysql_socket_accept(__FILE__, __LINE__, K, FD, AP, LP)
529 #else
530   #define mysql_socket_accept(K, FD, AP, LP) \
531     inline_mysql_socket_accept(FD, AP, LP)
532 #endif
533 
534 /**
535   @def mysql_socket_close(FD)
536   Close a socket and sever any connections.
537   @c mysql_socket_close is a replacement for @c close.
538   @param FD Instrumented socket descriptor returned by socket() or accept()
539 */
540 #ifdef HAVE_PSI_SOCKET_INTERFACE
541   #define mysql_socket_close(FD) \
542     inline_mysql_socket_close(__FILE__, __LINE__, FD)
543 #else
544   #define mysql_socket_close(FD) \
545     inline_mysql_socket_close(FD)
546 #endif
547 
548 /**
549   @def mysql_socket_shutdown(FD, H)
550   Disable receives and/or sends on a socket.
551   @c mysql_socket_shutdown is a replacement for @c shutdown.
552   @param FD Instrumented socket descriptor returned by socket() or accept()
553   @param H  Specifies which operations to shutdown
554 */
555 #ifdef HAVE_PSI_SOCKET_INTERFACE
556   #define mysql_socket_shutdown(FD, H) \
557     inline_mysql_socket_shutdown(__FILE__, __LINE__, FD, H)
558 #else
559   #define mysql_socket_shutdown(FD, H) \
560     inline_mysql_socket_shutdown(FD, H)
561 #endif
562 
563 #ifdef HAVE_PSI_SOCKET_INTERFACE
inline_mysql_socket_register(const char * category,PSI_socket_info * info,int count)564 static inline void inline_mysql_socket_register(
565   const char *category,
566   PSI_socket_info *info,
567   int count)
568 {
569   PSI_SOCKET_CALL(register_socket)(category, info, count);
570 }
571 #endif
572 
573 /** mysql_socket_socket */
574 
575 static inline MYSQL_SOCKET
inline_mysql_socket_socket(PSI_socket_key key,int domain,int type,int protocol)576 inline_mysql_socket_socket
577 (
578 #ifdef HAVE_PSI_SOCKET_INTERFACE
579   PSI_socket_key key,
580 #endif
581   int domain, int type, int protocol)
582 {
583   MYSQL_SOCKET mysql_socket= MYSQL_INVALID_SOCKET;
584   mysql_socket.fd= socket(domain, type, protocol);
585 
586 #ifdef HAVE_PSI_SOCKET_INTERFACE
587   if (likely(mysql_socket.fd != INVALID_SOCKET))
588   {
589     mysql_socket.m_psi= PSI_SOCKET_CALL(init_socket)
590       (key, (const my_socket*)&mysql_socket.fd, NULL, 0);
591   }
592 #endif
593   return mysql_socket;
594 }
595 
596 /** mysql_socket_bind */
597 
598 static inline int
inline_mysql_socket_bind(const char * src_file,uint src_line,MYSQL_SOCKET mysql_socket,const struct sockaddr * addr,socklen_t len)599 inline_mysql_socket_bind
600 (
601 #ifdef HAVE_PSI_SOCKET_INTERFACE
602   const char *src_file, uint src_line,
603 #endif
604   MYSQL_SOCKET mysql_socket, const struct sockaddr *addr, socklen_t len)
605 {
606   int result;
607 
608 #ifdef HAVE_PSI_SOCKET_INTERFACE
609   if (mysql_socket.m_psi != NULL)
610   {
611     /* Instrumentation start */
612     PSI_socket_locker_state state;
613     PSI_socket_locker *locker;
614     locker= PSI_SOCKET_CALL(start_socket_wait)
615       (&state, mysql_socket.m_psi, PSI_SOCKET_BIND, (size_t)0, src_file, src_line);
616 
617     /* Instrumented code */
618     result= bind(mysql_socket.fd, addr, len);
619 
620     /* Instrumentation end */
621     if (result == 0)
622       PSI_SOCKET_CALL(set_socket_info)(mysql_socket.m_psi, NULL, addr, len);
623 
624     if (locker != NULL)
625       PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
626 
627     return result;
628   }
629 #endif
630 
631   /* Non instrumented code */
632   result= bind(mysql_socket.fd, addr, len);
633   return result;
634 }
635 
636 /** mysql_socket_getsockname */
637 
638 static inline int
inline_mysql_socket_getsockname(const char * src_file,uint src_line,MYSQL_SOCKET mysql_socket,struct sockaddr * addr,socklen_t * len)639 inline_mysql_socket_getsockname
640 (
641 #ifdef HAVE_PSI_SOCKET_INTERFACE
642   const char *src_file, uint src_line,
643 #endif
644  MYSQL_SOCKET mysql_socket, struct sockaddr *addr, socklen_t *len)
645 {
646   int result;
647 
648 #ifdef HAVE_PSI_SOCKET_INTERFACE
649   if (mysql_socket.m_psi != NULL)
650   {
651     /* Instrumentation start */
652     PSI_socket_locker *locker;
653     PSI_socket_locker_state state;
654     locker= PSI_SOCKET_CALL(start_socket_wait)
655       (&state, mysql_socket.m_psi, PSI_SOCKET_BIND, (size_t)0, src_file, src_line);
656 
657     /* Instrumented code */
658     result= getsockname(mysql_socket.fd, addr, len);
659 
660     /* Instrumentation end */
661     if (locker != NULL)
662       PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
663 
664     return result;
665   }
666 #endif
667 
668   /* Non instrumented code */
669   result= getsockname(mysql_socket.fd, addr, len);
670 
671   return result;
672 }
673 
674 /** mysql_socket_connect */
675 
676 static inline int
inline_mysql_socket_connect(const char * src_file,uint src_line,MYSQL_SOCKET mysql_socket,const struct sockaddr * addr,socklen_t len)677 inline_mysql_socket_connect
678 (
679 #ifdef HAVE_PSI_SOCKET_INTERFACE
680   const char *src_file, uint src_line,
681 #endif
682  MYSQL_SOCKET mysql_socket, const struct sockaddr *addr, socklen_t len)
683 {
684   int result;
685 
686 #ifdef HAVE_PSI_SOCKET_INTERFACE
687   if (mysql_socket.m_psi != NULL)
688   {
689     /* Instrumentation start */
690     PSI_socket_locker *locker;
691     PSI_socket_locker_state state;
692     locker= PSI_SOCKET_CALL(start_socket_wait)
693       (&state, mysql_socket.m_psi, PSI_SOCKET_CONNECT, (size_t)0, src_file, src_line);
694 
695     /* Instrumented code */
696     result= connect(mysql_socket.fd, addr, len);
697 
698     /* Instrumentation end */
699     if (locker != NULL)
700       PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
701 
702     return result;
703   }
704 #endif
705 
706   /* Non instrumented code */
707   result= connect(mysql_socket.fd, addr, len);
708 
709   return result;
710 }
711 
712 /** mysql_socket_getpeername */
713 
714 static inline int
inline_mysql_socket_getpeername(const char * src_file,uint src_line,MYSQL_SOCKET mysql_socket,struct sockaddr * addr,socklen_t * len)715 inline_mysql_socket_getpeername
716 (
717 #ifdef HAVE_PSI_SOCKET_INTERFACE
718   const char *src_file, uint src_line,
719 #endif
720  MYSQL_SOCKET mysql_socket, struct sockaddr *addr, socklen_t *len)
721 {
722   int result;
723 
724 #ifdef HAVE_PSI_SOCKET_INTERFACE
725   if (mysql_socket.m_psi != NULL)
726   {
727     /* Instrumentation start */
728     PSI_socket_locker *locker;
729     PSI_socket_locker_state state;
730     locker= PSI_SOCKET_CALL(start_socket_wait)
731       (&state, mysql_socket.m_psi, PSI_SOCKET_BIND, (size_t)0, src_file, src_line);
732 
733     /* Instrumented code */
734     result= getpeername(mysql_socket.fd, addr, len);
735 
736     /* Instrumentation end */
737     if (locker != NULL)
738       PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
739 
740     return result;
741   }
742 #endif
743 
744   /* Non instrumented code */
745   result= getpeername(mysql_socket.fd, addr, len);
746 
747   return result;
748 }
749 
750 /** mysql_socket_send */
751 
752 static inline ssize_t
inline_mysql_socket_send(const char * src_file,uint src_line,MYSQL_SOCKET mysql_socket,const SOCKBUF_T * buf,size_t n,int flags)753 inline_mysql_socket_send
754 (
755 #ifdef HAVE_PSI_SOCKET_INTERFACE
756   const char *src_file, uint src_line,
757 #endif
758  MYSQL_SOCKET mysql_socket, const SOCKBUF_T *buf, size_t n, int flags)
759 {
760   ssize_t result;
761 
762 #ifdef HAVE_PSI_SOCKET_INTERFACE
763   if (mysql_socket.m_psi != NULL)
764   {
765     /* Instrumentation start */
766     PSI_socket_locker *locker;
767     PSI_socket_locker_state state;
768     locker= PSI_SOCKET_CALL(start_socket_wait)
769       (&state, mysql_socket.m_psi, PSI_SOCKET_SEND, n, src_file, src_line);
770 
771     /* Instrumented code */
772     result= send(mysql_socket.fd, buf, IF_WIN((int),) n, flags);
773 
774     /* Instrumentation end */
775     if (locker != NULL)
776     {
777       size_t bytes_written;
778       bytes_written= (result > -1) ? result : 0;
779       PSI_SOCKET_CALL(end_socket_wait)(locker, bytes_written);
780     }
781 
782     return result;
783   }
784 #endif
785 
786   /* Non instrumented code */
787   result= send(mysql_socket.fd, buf, IF_WIN((int),) n, flags);
788 
789   return result;
790 }
791 
792 /** mysql_socket_recv */
793 
794 static inline ssize_t
inline_mysql_socket_recv(const char * src_file,uint src_line,MYSQL_SOCKET mysql_socket,SOCKBUF_T * buf,size_t n,int flags)795 inline_mysql_socket_recv
796 (
797 #ifdef HAVE_PSI_SOCKET_INTERFACE
798   const char *src_file, uint src_line,
799 #endif
800  MYSQL_SOCKET mysql_socket,  SOCKBUF_T *buf, size_t n, int flags)
801 {
802   ssize_t result;
803 
804 #ifdef HAVE_PSI_SOCKET_INTERFACE
805   if (mysql_socket.m_psi != NULL)
806   {
807     /* Instrumentation start */
808     PSI_socket_locker *locker;
809     PSI_socket_locker_state state;
810     locker= PSI_SOCKET_CALL(start_socket_wait)
811       (&state, mysql_socket.m_psi, PSI_SOCKET_RECV, (size_t)0, src_file, src_line);
812 
813     /* Instrumented code */
814     result= recv(mysql_socket.fd, buf, IF_WIN((int),) n, flags);
815 
816     /* Instrumentation end */
817     if (locker != NULL)
818     {
819       size_t bytes_read;
820       bytes_read= (result > -1) ? result : 0;
821       PSI_SOCKET_CALL(end_socket_wait)(locker, bytes_read);
822     }
823 
824     return result;
825   }
826 #endif
827 
828   /* Non instrumented code */
829   result= recv(mysql_socket.fd, buf, IF_WIN((int),) n, flags);
830 
831   return result;
832 }
833 
834 /** mysql_socket_sendto */
835 
836 static inline ssize_t
inline_mysql_socket_sendto(const char * src_file,uint src_line,MYSQL_SOCKET mysql_socket,const SOCKBUF_T * buf,size_t n,int flags,const struct sockaddr * addr,socklen_t addr_len)837 inline_mysql_socket_sendto
838 (
839 #ifdef HAVE_PSI_SOCKET_INTERFACE
840   const char *src_file, uint src_line,
841 #endif
842  MYSQL_SOCKET mysql_socket, const SOCKBUF_T *buf, size_t n, int flags, const struct sockaddr *addr, socklen_t addr_len)
843 {
844   ssize_t result;
845 
846 #ifdef HAVE_PSI_SOCKET_INTERFACE
847   if (mysql_socket.m_psi != NULL)
848   {
849     /* Instrumentation start */
850     PSI_socket_locker *locker;
851     PSI_socket_locker_state state;
852     locker= PSI_SOCKET_CALL(start_socket_wait)
853       (&state, mysql_socket.m_psi, PSI_SOCKET_SEND, n, src_file, src_line);
854 
855     /* Instrumented code */
856     result= sendto(mysql_socket.fd, buf, IF_WIN((int),) n, flags, addr, addr_len);
857 
858     /* Instrumentation end */
859     if (locker != NULL)
860     {
861       size_t bytes_written;
862       bytes_written = (result > -1) ? result : 0;
863       PSI_SOCKET_CALL(end_socket_wait)(locker, bytes_written);
864     }
865 
866     return result;
867   }
868 #endif
869 
870   /* Non instrumented code */
871   result= sendto(mysql_socket.fd, buf, IF_WIN((int),) n, flags, addr, addr_len);
872 
873   return result;
874 }
875 
876 /** mysql_socket_recvfrom */
877 
878 static inline ssize_t
inline_mysql_socket_recvfrom(const char * src_file,uint src_line,MYSQL_SOCKET mysql_socket,SOCKBUF_T * buf,size_t n,int flags,struct sockaddr * addr,socklen_t * addr_len)879 inline_mysql_socket_recvfrom
880 (
881 #ifdef HAVE_PSI_SOCKET_INTERFACE
882   const char *src_file, uint src_line,
883 #endif
884  MYSQL_SOCKET mysql_socket, SOCKBUF_T *buf, size_t n, int flags,
885  struct sockaddr *addr, socklen_t *addr_len)
886 {
887   ssize_t result;
888 
889 #ifdef HAVE_PSI_SOCKET_INTERFACE
890   if (mysql_socket.m_psi != NULL)
891   {
892     /* Instrumentation start */
893     PSI_socket_locker *locker;
894     PSI_socket_locker_state state;
895     locker= PSI_SOCKET_CALL(start_socket_wait)
896       (&state, mysql_socket.m_psi, PSI_SOCKET_RECV, (size_t)0, src_file, src_line);
897 
898     /* Instrumented code */
899     result= recvfrom(mysql_socket.fd, buf, IF_WIN((int),) n, flags, addr, addr_len);
900 
901     /* Instrumentation end */
902     if (locker != NULL)
903     {
904       size_t bytes_read;
905       bytes_read = (result > -1) ? result : 0;
906       PSI_SOCKET_CALL(end_socket_wait)(locker, bytes_read);
907     }
908 
909     return result;
910   }
911 #endif
912 
913   /* Non instrumented code */
914   result= recvfrom(mysql_socket.fd, buf, IF_WIN((int),) n, flags, addr, addr_len);
915 
916   return result;
917 }
918 
919 /** mysql_socket_getsockopt */
920 
921 static inline int
inline_mysql_socket_getsockopt(const char * src_file,uint src_line,MYSQL_SOCKET mysql_socket,int level,int optname,SOCKBUF_T * optval,socklen_t * optlen)922 inline_mysql_socket_getsockopt
923 (
924 #ifdef HAVE_PSI_SOCKET_INTERFACE
925   const char *src_file, uint src_line,
926 #endif
927  MYSQL_SOCKET mysql_socket, int level, int optname, SOCKBUF_T *optval, socklen_t *optlen)
928 {
929   int result;
930 
931 #ifdef HAVE_PSI_SOCKET_INTERFACE
932   if (mysql_socket.m_psi != NULL)
933   {
934     /* Instrumentation start */
935     PSI_socket_locker *locker;
936     PSI_socket_locker_state state;
937     locker= PSI_SOCKET_CALL(start_socket_wait)
938       (&state, mysql_socket.m_psi, PSI_SOCKET_OPT, (size_t)0, src_file, src_line);
939 
940     /* Instrumented code */
941     result= getsockopt(mysql_socket.fd, level, optname, optval, optlen);
942 
943     /* Instrumentation end */
944     if (locker != NULL)
945       PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
946 
947     return result;
948   }
949 #endif
950 
951   /* Non instrumented code */
952   result= getsockopt(mysql_socket.fd, level, optname, optval, optlen);
953 
954   return result;
955 }
956 
957 /** mysql_socket_setsockopt */
958 
959 static inline int
inline_mysql_socket_setsockopt(const char * src_file,uint src_line,MYSQL_SOCKET mysql_socket,int level,int optname,const SOCKBUF_T * optval,socklen_t optlen)960 inline_mysql_socket_setsockopt
961 (
962 #ifdef HAVE_PSI_SOCKET_INTERFACE
963   const char *src_file, uint src_line,
964 #endif
965  MYSQL_SOCKET mysql_socket, int level, int optname, const SOCKBUF_T *optval,
966  socklen_t optlen)
967 {
968   int result;
969 
970 #ifdef HAVE_PSI_SOCKET_INTERFACE
971   if (mysql_socket.m_psi)
972   {
973     /* Instrumentation start */
974     PSI_socket_locker *locker;
975     PSI_socket_locker_state state;
976     locker= PSI_SOCKET_CALL(start_socket_wait)
977       (&state, mysql_socket.m_psi, PSI_SOCKET_OPT, (size_t)0, src_file, src_line);
978 
979     /* Instrumented code */
980     result= setsockopt(mysql_socket.fd, level, optname, optval, optlen);
981 
982     /* Instrumentation end */
983     if (locker != NULL)
984       PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
985 
986     return result;
987   }
988 #endif
989 
990   /* Non instrumented code */
991   result= setsockopt(mysql_socket.fd, level, optname, optval, optlen);
992 
993   return result;
994 }
995 
996 /** set_socket_nonblock */
997 static inline int
set_socket_nonblock(my_socket fd)998 set_socket_nonblock(my_socket fd)
999 {
1000   int ret= 0;
1001 #ifdef _WIN32
1002   {
1003     u_long nonblocking= 1;
1004     ret= ioctlsocket(fd, FIONBIO, &nonblocking);
1005   }
1006 #else
1007   {
1008     int fd_flags;
1009     fd_flags= fcntl(fd, F_GETFL, 0);
1010     if (fd_flags < 0)
1011       return errno;
1012 #if defined(O_NONBLOCK)
1013     fd_flags |= O_NONBLOCK;
1014 #elif defined(O_NDELAY)
1015     fd_flags |= O_NDELAY;
1016 #elif defined(O_FNDELAY)
1017     fd_flags |= O_FNDELAY;
1018 #else
1019 #error "No definition of non-blocking flag found."
1020 #endif /* O_NONBLOCK */
1021     if (fcntl(fd, F_SETFL, fd_flags) == -1)
1022       ret= errno;
1023   }
1024 #endif /* _WIN32 */
1025   return ret;
1026 }
1027 
1028 /** mysql_socket_set_nonblocking */
1029 
1030 static inline int
inline_mysql_sock_set_nonblocking(const char * src_file,uint src_line,MYSQL_SOCKET mysql_socket)1031 inline_mysql_sock_set_nonblocking
1032 (
1033 #ifdef HAVE_PSI_SOCKET_INTERFACE
1034   const char *src_file, uint src_line,
1035 #endif
1036   MYSQL_SOCKET mysql_socket
1037 )
1038 {
1039   int result= 0;
1040 
1041 #ifdef HAVE_PSI_SOCKET_INTERFACE
1042   if (mysql_socket.m_psi)
1043   {
1044     /* Instrumentation start */
1045     PSI_socket_locker *locker;
1046     PSI_socket_locker_state state;
1047     locker= PSI_SOCKET_CALL(start_socket_wait)
1048         (&state, mysql_socket.m_psi, PSI_SOCKET_OPT,
1049          (size_t)0, src_file, src_line);
1050 
1051     /* Instrumented code */
1052     result= set_socket_nonblock(mysql_socket.fd);
1053 
1054     /* Instrumentation end */
1055     if (locker != NULL)
1056       PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
1057 
1058     return result;
1059   }
1060 #endif
1061 
1062   /* Non instrumented code */
1063   result= set_socket_nonblock(mysql_socket.fd);
1064 
1065   return result;
1066 }
1067 
1068 /** mysql_socket_listen */
1069 
1070 static inline int
inline_mysql_socket_listen(const char * src_file,uint src_line,MYSQL_SOCKET mysql_socket,int backlog)1071 inline_mysql_socket_listen
1072 (
1073 #ifdef HAVE_PSI_SOCKET_INTERFACE
1074   const char *src_file, uint src_line,
1075 #endif
1076  MYSQL_SOCKET mysql_socket, int backlog)
1077 {
1078   int result;
1079 
1080 #ifdef HAVE_PSI_SOCKET_INTERFACE
1081   if (mysql_socket.m_psi != NULL)
1082   {
1083     /* Instrumentation start */
1084     PSI_socket_locker *locker;
1085     PSI_socket_locker_state state;
1086     locker= PSI_SOCKET_CALL(start_socket_wait)
1087       (&state, mysql_socket.m_psi, PSI_SOCKET_CONNECT, (size_t)0, src_file, src_line);
1088 
1089     /* Instrumented code */
1090     result= listen(mysql_socket.fd, backlog);
1091 
1092     /* Instrumentation end */
1093     if (locker != NULL)
1094       PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
1095 
1096     return result;
1097   }
1098 #endif
1099 
1100   /* Non instrumented code */
1101   result= listen(mysql_socket.fd, backlog);
1102 
1103   return result;
1104 }
1105 
1106 /** mysql_socket_accept */
1107 
1108 static inline MYSQL_SOCKET
inline_mysql_socket_accept(const char * src_file,uint src_line,PSI_socket_key key,MYSQL_SOCKET socket_listen,struct sockaddr * addr,socklen_t * addr_len)1109 inline_mysql_socket_accept
1110 (
1111 #ifdef HAVE_PSI_SOCKET_INTERFACE
1112   const char *src_file, uint src_line, PSI_socket_key key,
1113 #endif
1114   MYSQL_SOCKET socket_listen, struct sockaddr *addr, socklen_t *addr_len)
1115 {
1116   MYSQL_SOCKET socket_accept= MYSQL_INVALID_SOCKET;
1117   socklen_t addr_length= (addr_len != NULL) ? *addr_len : 0;
1118 
1119 #ifdef HAVE_PSI_SOCKET_INTERFACE
1120   if (socket_listen.m_psi != NULL)
1121   {
1122     /* Instrumentation start */
1123     PSI_socket_locker *locker;
1124     PSI_socket_locker_state state;
1125     locker= PSI_SOCKET_CALL(start_socket_wait)
1126       (&state, socket_listen.m_psi, PSI_SOCKET_CONNECT, (size_t)0, src_file, src_line);
1127 
1128     /* Instrumented code */
1129     socket_accept.fd= accept(socket_listen.fd, addr, &addr_length);
1130 
1131     /* Instrumentation end */
1132     if (locker != NULL)
1133       PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
1134   }
1135   else
1136 #endif
1137   {
1138     /* Non instrumented code */
1139     socket_accept.fd= accept(socket_listen.fd, addr, &addr_length);
1140   }
1141 
1142 #ifdef HAVE_PSI_SOCKET_INTERFACE
1143   if (likely(socket_accept.fd != INVALID_SOCKET))
1144   {
1145     /* Initialize the instrument with the new socket descriptor and address */
1146     socket_accept.m_psi= PSI_SOCKET_CALL(init_socket)
1147       (key, (const my_socket*)&socket_accept.fd, addr, addr_length);
1148   }
1149 #endif
1150 
1151   return socket_accept;
1152 }
1153 
1154 /** mysql_socket_close */
1155 
1156 static inline int
inline_mysql_socket_close(const char * src_file,uint src_line,MYSQL_SOCKET mysql_socket)1157 inline_mysql_socket_close
1158 (
1159 #ifdef HAVE_PSI_SOCKET_INTERFACE
1160   const char *src_file, uint src_line,
1161 #endif
1162   MYSQL_SOCKET mysql_socket)
1163 {
1164   int result;
1165 
1166 #ifdef HAVE_PSI_SOCKET_INTERFACE
1167   if (mysql_socket.m_psi != NULL)
1168   {
1169     /* Instrumentation start */
1170     PSI_socket_locker *locker;
1171     PSI_socket_locker_state state;
1172     locker= PSI_SOCKET_CALL(start_socket_wait)
1173       (&state, mysql_socket.m_psi, PSI_SOCKET_CLOSE, (size_t)0, src_file, src_line);
1174 
1175     /* Instrumented code */
1176     result= closesocket(mysql_socket.fd);
1177 
1178     /* Instrumentation end */
1179     if (locker != NULL)
1180       PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
1181     /* Remove the instrumentation for this socket. */
1182     if (mysql_socket.m_psi != NULL)
1183       PSI_SOCKET_CALL(destroy_socket)(mysql_socket.m_psi);
1184 
1185     return result;
1186   }
1187 #endif
1188 
1189   /* Non instrumented code */
1190   result= closesocket(mysql_socket.fd);
1191 
1192   return result;
1193 }
1194 
1195 /** mysql_socket_shutdown */
1196 
1197 static inline int
inline_mysql_socket_shutdown(const char * src_file,uint src_line,MYSQL_SOCKET mysql_socket,int how)1198 inline_mysql_socket_shutdown
1199 (
1200 #ifdef HAVE_PSI_SOCKET_INTERFACE
1201   const char *src_file, uint src_line,
1202 #endif
1203   MYSQL_SOCKET mysql_socket, int how)
1204 {
1205   int result;
1206 
1207 #ifdef _WIN32
1208   static LPFN_DISCONNECTEX DisconnectEx = NULL;
1209   if (DisconnectEx == NULL)
1210   {
1211     DWORD dwBytesReturned;
1212     GUID guidDisconnectEx = WSAID_DISCONNECTEX;
1213     WSAIoctl(mysql_socket.fd, SIO_GET_EXTENSION_FUNCTION_POINTER,
1214              &guidDisconnectEx, sizeof(GUID),
1215              &DisconnectEx, sizeof(DisconnectEx),
1216              &dwBytesReturned, NULL, NULL);
1217   }
1218 #endif
1219 
1220 /* Instrumentation start */
1221 #ifdef HAVE_PSI_SOCKET_INTERFACE
1222   if (mysql_socket.m_psi != NULL)
1223   {
1224     PSI_socket_locker *locker;
1225     PSI_socket_locker_state state;
1226     locker= PSI_SOCKET_CALL(start_socket_wait)
1227       (&state, mysql_socket.m_psi, PSI_SOCKET_SHUTDOWN, (size_t)0, src_file, src_line);
1228 
1229     /* Instrumented code */
1230 #ifdef _WIN32
1231     if (DisconnectEx)
1232       result= (DisconnectEx(mysql_socket.fd, (LPOVERLAPPED) NULL,
1233                             (DWORD) 0, (DWORD) 0) == TRUE) ? 0 : -1;
1234     else
1235 #endif
1236       result= shutdown(mysql_socket.fd, how);
1237 
1238     /* Instrumentation end */
1239     if (locker != NULL)
1240       PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
1241 
1242     return result;
1243   }
1244 #endif
1245 
1246   /* Non instrumented code */
1247 #ifdef _WIN32
1248   if (DisconnectEx)
1249     result= (DisconnectEx(mysql_socket.fd, (LPOVERLAPPED) NULL,
1250                           (DWORD) 0, (DWORD) 0) == TRUE) ? 0 : -1;
1251   else
1252 #endif
1253     result= shutdown(mysql_socket.fd, how);
1254 
1255   return result;
1256 }
1257 
1258 /** @} (end of group Socket_instrumentation) */
1259 
1260 #endif
1261 
1262