mysql_socket.h 33 KB

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