mysql_socket.h 31 KB

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