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