1 /* Copyright (C) 2012 MariaDB Services and Kristian Nielsen
2 2015 MariaDB Corporation
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with this library; if not, write to the Free
16 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 */
18
19 /*
20 MySQL non-blocking client library functions.
21 */
22
23 #include "ma_global.h"
24 #include "ma_sys.h"
25 #include "mysql.h"
26 #include "errmsg.h"
27 #ifndef LIBMARIADB
28 #include "sql_common.h"
29 #else
30 #include "ma_common.h"
31 #endif
32 #include "ma_context.h"
33 #include "ma_pvio.h"
34 #include "mariadb_async.h"
35 #include <string.h>
36
37
38 #ifdef _WIN32
39 /*
40 Windows does not support MSG_DONTWAIT for send()/recv(). So we need to ensure
41 that the socket is non-blocking at the start of every operation.
42 */
43 #define WIN_SET_NONBLOCKING(mysql) do { \
44 my_bool old_mode; \
45 if ((mysql)->net.pvio) ma_pvio_blocking((mysql)->net.pvio, FALSE, &old_mode); \
46 } while(0);
47 #else
48 #define WIN_SET_NONBLOCKING(mysql)
49 #endif
50
51 extern void mysql_close_slow_part(MYSQL *mysql);
52
53
54 void
my_context_install_suspend_resume_hook(struct mysql_async_context * b,void (* hook)(my_bool,void *),void * user_data)55 my_context_install_suspend_resume_hook(struct mysql_async_context *b,
56 void (*hook)(my_bool, void *),
57 void *user_data)
58 {
59 b->suspend_resume_hook= hook;
60 b->suspend_resume_hook_user_data= user_data;
61 }
62
63
64 /* Asynchronous connect(); socket must already be set non-blocking. */
65 int
my_connect_async(MARIADB_PVIO * pvio,const struct sockaddr * name,uint namelen,int vio_timeout)66 my_connect_async(MARIADB_PVIO *pvio,
67 const struct sockaddr *name, uint namelen, int vio_timeout)
68 {
69 int res;
70 size_socket s_err_size;
71 struct mysql_async_context *b= pvio->mysql->options.extension->async_context;
72 my_socket sock;
73
74 ma_pvio_get_handle(pvio, &sock);
75
76 /* Make the socket non-blocking. */
77 ma_pvio_blocking(pvio, 0, 0);
78
79 b->events_to_wait_for= 0;
80 /*
81 Start to connect asynchronously.
82 If this will block, we suspend the call and return control to the
83 application context. The application will then resume us when the socket
84 polls ready for write, indicating that the connection attempt completed.
85 */
86 res= connect(sock, name, namelen);
87 if (res != 0)
88 {
89 #ifdef _WIN32
90 int wsa_err= WSAGetLastError();
91 if (wsa_err != WSAEWOULDBLOCK)
92 return res;
93 b->events_to_wait_for|= MYSQL_WAIT_EXCEPT;
94 #else
95 int err= errno;
96 if (err != EINPROGRESS && err != EALREADY && err != EAGAIN)
97 return res;
98 #endif
99 b->events_to_wait_for|= MYSQL_WAIT_WRITE;
100 if (vio_timeout >= 0)
101 {
102 b->timeout_value= vio_timeout;
103 b->events_to_wait_for|= MYSQL_WAIT_TIMEOUT;
104 }
105 else
106 b->timeout_value= 0;
107 if (b->suspend_resume_hook)
108 (*b->suspend_resume_hook)(TRUE, b->suspend_resume_hook_user_data);
109 my_context_yield(&b->async_context);
110 if (b->suspend_resume_hook)
111 (*b->suspend_resume_hook)(FALSE, b->suspend_resume_hook_user_data);
112 if (b->events_occured & MYSQL_WAIT_TIMEOUT)
113 return -1;
114
115 s_err_size= sizeof(res);
116 if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char*) &res, &s_err_size) != 0)
117 return -1;
118 if (res)
119 {
120 errno= res;
121 return -1;
122 }
123 }
124 return res;
125 }
126
127 #define IS_BLOCKING_ERROR() \
128 IF_WIN(WSAGetLastError() != WSAEWOULDBLOCK, \
129 (errno != EAGAIN && errno != EINTR))
130
131 #ifdef _AIX
132 #ifndef MSG_DONTWAIT
133 #define MSG_DONTWAIT 0
134 #endif
135 #endif
136
137 #ifdef HAVE_TLS_FIXME
138 static my_bool
my_ssl_async_check_result(int res,struct mysql_async_context * b,MARIADB_SSL * cssl)139 my_ssl_async_check_result(int res, struct mysql_async_context *b, MARIADB_SSL *cssl)
140 {
141 int ssl_err;
142 b->events_to_wait_for= 0;
143 if (res >= 0)
144 return 1;
145 ssl_err= SSL_get_error(ssl, res);
146 if (ssl_err == SSL_ERROR_WANT_READ)
147 b->events_to_wait_for|= MYSQL_WAIT_READ;
148 else if (ssl_err == SSL_ERROR_WANT_WRITE)
149 b->events_to_wait_for|= MYSQL_WAIT_WRITE;
150 else
151 return 1;
152 if (b->suspend_resume_hook)
153 (*b->suspend_resume_hook)(TRUE, b->suspend_resume_hook_user_data);
154 my_context_yield(&b->async_context);
155 if (b->suspend_resume_hook)
156 (*b->suspend_resume_hook)(FALSE, b->suspend_resume_hook_user_data);
157 return 0;
158 }
159
160 int
my_ssl_read_async(struct mysql_async_context * b,SSL * ssl,void * buf,int size)161 my_ssl_read_async(struct mysql_async_context *b, SSL *ssl,
162 void *buf, int size)
163 {
164 int res;
165
166 for (;;)
167 {
168 res= SSL_read(ssl, buf, size);
169 if (my_ssl_async_check_result(res, b, ssl))
170 return res;
171 }
172 }
173
174 int
my_ssl_write_async(struct mysql_async_context * b,SSL * ssl,const void * buf,int size)175 my_ssl_write_async(struct mysql_async_context *b, SSL *ssl,
176 const void *buf, int size)
177 {
178 int res;
179
180 for (;;)
181 {
182 res= SSL_write(ssl, buf, size);
183 if (my_ssl_async_check_result(res, b, ssl))
184 return res;
185 }
186 }
187 #endif /* HAVE_OPENSSL */
188
189
190
191
192 /*
193 Now create non-blocking definitions for all the calls that may block.
194
195 Each call FOO gives rise to FOO_start() that prepares the MYSQL object for
196 doing non-blocking calls that can suspend operation mid-way, and then starts
197 the call itself. And a FOO_start_internal trampoline to assist with running
198 the real call in a co-routine that can be suspended. And a FOO_cont() that
199 can continue a suspended operation.
200 */
201
202 #define MK_ASYNC_INTERNAL_BODY(call, invoke_args, mysql_val, ret_type, ok_val)\
203 struct call ## _params *parms= (struct call ## _params *)d; \
204 ret_type ret; \
205 struct mysql_async_context *b= \
206 (mysql_val)->options.extension->async_context; \
207 \
208 ret= call invoke_args; \
209 b->ret_result. ok_val = ret; \
210 b->events_to_wait_for= 0;
211
212 #define MK_ASYNC_START_BODY(call, mysql_val, parms_assign, err_val, ok_val, extra1) \
213 int res; \
214 struct mysql_async_context *b; \
215 struct call ## _params parms; \
216 \
217 extra1 \
218 b= mysql_val->options.extension->async_context; \
219 parms_assign \
220 \
221 b->active= 1; \
222 res= my_context_spawn(&b->async_context, call ## _start_internal, &parms); \
223 b->active= b->suspended= 0; \
224 if (res > 0) \
225 { \
226 /* Suspended. */ \
227 b->suspended= 1; \
228 return b->events_to_wait_for; \
229 } \
230 if (res < 0) \
231 { \
232 set_mariadb_error((mysql_val), CR_OUT_OF_MEMORY, unknown_sqlstate); \
233 *ret= err_val; \
234 } \
235 else \
236 *ret= b->ret_result. ok_val; \
237 return 0;
238
239 #define MK_ASYNC_CONT_BODY(mysql_val, err_val, ok_val) \
240 int res; \
241 struct mysql_async_context *b= \
242 (mysql_val)->options.extension->async_context; \
243 if (!b->suspended) \
244 { \
245 set_mariadb_error((mysql_val), CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); \
246 *ret= err_val; \
247 return 0; \
248 } \
249 \
250 b->active= 1; \
251 b->events_occured= ready_status; \
252 res= my_context_continue(&b->async_context); \
253 b->active= 0; \
254 if (res > 0) \
255 return b->events_to_wait_for; /* (Still) suspended */ \
256 b->suspended= 0; \
257 if (res < 0) \
258 { \
259 set_mariadb_error((mysql_val), CR_OUT_OF_MEMORY, unknown_sqlstate); \
260 *ret= err_val; \
261 } \
262 else \
263 *ret= b->ret_result. ok_val; /* Finished. */ \
264 return 0;
265
266 #define MK_ASYNC_INTERNAL_BODY_VOID_RETURN(call, invoke_args, mysql_val) \
267 struct call ## _params *parms= (struct call ## _params *)d; \
268 struct mysql_async_context *b= \
269 (mysql_val)->options.extension->async_context; \
270 \
271 call invoke_args; \
272 b->events_to_wait_for= 0;
273
274 #define MK_ASYNC_START_BODY_VOID_RETURN(call, mysql_val, parms_assign, extra1)\
275 int res; \
276 struct mysql_async_context *b; \
277 struct call ## _params parms; \
278 \
279 extra1 \
280 b= mysql_val->options.extension->async_context; \
281 parms_assign \
282 \
283 b->active= 1; \
284 res= my_context_spawn(&b->async_context, call ## _start_internal, &parms); \
285 b->active= b->suspended= 0; \
286 if (res > 0) \
287 { \
288 /* Suspended. */ \
289 b->suspended= 1; \
290 return b->events_to_wait_for; \
291 } \
292 if (res < 0) \
293 set_mariadb_error((mysql_val), CR_OUT_OF_MEMORY, unknown_sqlstate); \
294 return 0;
295
296 #define MK_ASYNC_CONT_BODY_VOID_RETURN(mysql_val) \
297 int res; \
298 struct mysql_async_context *b= \
299 (mysql_val)->options.extension->async_context; \
300 if (!b->suspended) \
301 { \
302 set_mariadb_error((mysql_val), CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); \
303 return 0; \
304 } \
305 \
306 b->active= 1; \
307 b->events_occured= ready_status; \
308 res= my_context_continue(&b->async_context); \
309 b->active= 0; \
310 if (res > 0) \
311 return b->events_to_wait_for; /* (Still) suspended */ \
312 b->suspended= 0; \
313 if (res < 0) \
314 set_mariadb_error((mysql_val), CR_OUT_OF_MEMORY, unknown_sqlstate); \
315 return 0;
316
317
318 /* Structure used to pass parameters from mysql_real_connect_start(). */
319 struct mysql_real_connect_params {
320 MYSQL *mysql;
321 const char *host;
322 const char *user;
323 const char *passwd;
324 const char *db;
325 unsigned int port;
326 const char *unix_socket;
327 unsigned long client_flags;
328 };
329 static void
mysql_real_connect_start_internal(void * d)330 mysql_real_connect_start_internal(void *d)
331 {
332 MK_ASYNC_INTERNAL_BODY(
333 mysql_real_connect,
334 (parms->mysql, parms->host, parms->user, parms->passwd, parms->db,
335 parms->port, parms->unix_socket, parms->client_flags),
336 parms->mysql,
337 MYSQL *,
338 r_ptr)
339 }
340 int STDCALL
mysql_real_connect_start(MYSQL ** ret,MYSQL * mysql,const char * host,const char * user,const char * passwd,const char * db,unsigned int port,const char * unix_socket,unsigned long client_flags)341 mysql_real_connect_start(MYSQL **ret, MYSQL *mysql, const char *host,
342 const char *user, const char *passwd, const char *db,
343 unsigned int port, const char *unix_socket,
344 unsigned long client_flags)
345 {
346 MK_ASYNC_START_BODY(
347 mysql_real_connect,
348 mysql,
349 {
350 parms.mysql= mysql;
351 parms.host= host;
352 parms.user= user;
353 parms.passwd= passwd;
354 parms.db= db;
355 parms.port= port;
356 parms.unix_socket= unix_socket;
357 parms.client_flags= client_flags | CLIENT_REMEMBER_OPTIONS;
358 },
359 NULL,
360 r_ptr,
361 /* Nothing */)
362 }
363 int STDCALL
mysql_real_connect_cont(MYSQL ** ret,MYSQL * mysql,int ready_status)364 mysql_real_connect_cont(MYSQL **ret, MYSQL *mysql, int ready_status)
365 {
366 MK_ASYNC_CONT_BODY(
367 mysql,
368 NULL,
369 r_ptr)
370 }
371
372 /* Structure used to pass parameters from mysql_real_query_start(). */
373 struct mysql_real_query_params {
374 MYSQL *mysql;
375 const char *stmt_str;
376 unsigned long length;
377 };
378 static void
mysql_real_query_start_internal(void * d)379 mysql_real_query_start_internal(void *d)
380 {
381 MK_ASYNC_INTERNAL_BODY(
382 mysql_real_query,
383 (parms->mysql, parms->stmt_str, parms->length),
384 parms->mysql,
385 int,
386 r_int)
387 }
388 int STDCALL
mysql_real_query_start(int * ret,MYSQL * mysql,const char * stmt_str,unsigned long length)389 mysql_real_query_start(int *ret, MYSQL *mysql, const char *stmt_str, unsigned long length)
390 {
391 int res;
392 struct mysql_async_context *b;
393 struct mysql_real_query_params parms;
394
395 b= mysql->options.extension->async_context;
396 {
397 WIN_SET_NONBLOCKING(mysql)
398 parms.mysql= mysql;
399 parms.stmt_str= stmt_str;
400 parms.length= length;
401 }
402
403 b->active= 1;
404 res= my_context_spawn(&b->async_context, mysql_real_query_start_internal, &parms);
405 b->active= b->suspended= 0;
406 if (res > 0)
407 {
408 /* Suspended. */
409 b->suspended= 1;
410 return b->events_to_wait_for;
411 }
412 if (res < 0)
413 {
414 set_mariadb_error((mysql), CR_OUT_OF_MEMORY, unknown_sqlstate);
415 *ret= 1;
416 }
417 else
418 *ret= b->ret_result.r_int;
419 return 0;
420
421 }
422 int STDCALL
mysql_real_query_cont(int * ret,MYSQL * mysql,int ready_status)423 mysql_real_query_cont(int *ret, MYSQL *mysql, int ready_status)
424 {
425 MK_ASYNC_CONT_BODY(
426 mysql,
427 1,
428 r_int)
429 }
430
431 /* Structure used to pass parameters from mysql_fetch_row_start(). */
432 struct mysql_fetch_row_params {
433 MYSQL_RES *result;
434 };
435 static void
mysql_fetch_row_start_internal(void * d)436 mysql_fetch_row_start_internal(void *d)
437 {
438 MK_ASYNC_INTERNAL_BODY(
439 mysql_fetch_row,
440 (parms->result),
441 parms->result->handle,
442 MYSQL_ROW,
443 r_ptr)
444 }
445 int STDCALL
mysql_fetch_row_start(MYSQL_ROW * ret,MYSQL_RES * result)446 mysql_fetch_row_start(MYSQL_ROW *ret, MYSQL_RES *result)
447 {
448 MK_ASYNC_START_BODY(
449 mysql_fetch_row,
450 result->handle,
451 {
452 WIN_SET_NONBLOCKING(result->handle)
453 parms.result= result;
454 },
455 NULL,
456 r_ptr,
457 /*
458 If we already fetched all rows from server (eg. mysql_store_result()),
459 then result->handle will be NULL and we cannot suspend. But that is fine,
460 since in this case mysql_fetch_row cannot block anyway. Just return
461 directly.
462 */
463 if (!result->handle)
464 {
465 *ret= mysql_fetch_row(result);
466 return 0;
467 })
468 }
469 int STDCALL
mysql_fetch_row_cont(MYSQL_ROW * ret,MYSQL_RES * result,int ready_status)470 mysql_fetch_row_cont(MYSQL_ROW *ret, MYSQL_RES *result, int ready_status)
471 {
472 MK_ASYNC_CONT_BODY(
473 result->handle,
474 NULL,
475 r_ptr)
476 }
477
478 /* Structure used to pass parameters from mysql_set_character_set_start(). */
479 struct mysql_set_character_set_params {
480 MYSQL *mysql;
481 const char *csname;
482 };
483 static void
mysql_set_character_set_start_internal(void * d)484 mysql_set_character_set_start_internal(void *d)
485 {
486 MK_ASYNC_INTERNAL_BODY(
487 mysql_set_character_set,
488 (parms->mysql, parms->csname),
489 parms->mysql,
490 int,
491 r_int)
492 }
493 int STDCALL
mysql_set_character_set_start(int * ret,MYSQL * mysql,const char * csname)494 mysql_set_character_set_start(int *ret, MYSQL *mysql, const char *csname)
495 {
496 MK_ASYNC_START_BODY(
497 mysql_set_character_set,
498 mysql,
499 {
500 WIN_SET_NONBLOCKING(mysql)
501 parms.mysql= mysql;
502 parms.csname= csname;
503 },
504 1,
505 r_int,
506 /* Nothing */)
507 }
508 int STDCALL
mysql_set_character_set_cont(int * ret,MYSQL * mysql,int ready_status)509 mysql_set_character_set_cont(int *ret, MYSQL *mysql, int ready_status)
510 {
511 MK_ASYNC_CONT_BODY(
512 mysql,
513 1,
514 r_int)
515 }
516
517 /* Structure used to pass parameters from mysql_sekect_db_start(). */
518 struct mysql_select_db_params {
519 MYSQL *mysql;
520 const char *db;
521 };
522 static void
mysql_select_db_start_internal(void * d)523 mysql_select_db_start_internal(void *d)
524 {
525 MK_ASYNC_INTERNAL_BODY(
526 mysql_select_db,
527 (parms->mysql, parms->db),
528 parms->mysql,
529 int,
530 r_int)
531 }
532 int STDCALL
mysql_select_db_start(int * ret,MYSQL * mysql,const char * db)533 mysql_select_db_start(int *ret, MYSQL *mysql, const char *db)
534 {
535 MK_ASYNC_START_BODY(
536 mysql_select_db,
537 mysql,
538 {
539 WIN_SET_NONBLOCKING(mysql)
540 parms.mysql= mysql;
541 parms.db= db;
542 },
543 1,
544 r_int,
545 /* Nothing */)
546 }
547 int STDCALL
mysql_select_db_cont(int * ret,MYSQL * mysql,int ready_status)548 mysql_select_db_cont(int *ret, MYSQL *mysql, int ready_status)
549 {
550 MK_ASYNC_CONT_BODY(
551 mysql,
552 1,
553 r_int)
554 }
555
556 /* Structure used to pass parameters from mysql_send_query_start(). */
557 struct mysql_send_query_params {
558 MYSQL *mysql;
559 const char *q;
560 unsigned long length;
561 };
562 static void
mysql_send_query_start_internal(void * d)563 mysql_send_query_start_internal(void *d)
564 {
565 MK_ASYNC_INTERNAL_BODY(
566 mysql_send_query,
567 (parms->mysql, parms->q, parms->length),
568 parms->mysql,
569 int,
570 r_int)
571 }
572 int STDCALL
mysql_send_query_start(int * ret,MYSQL * mysql,const char * q,unsigned long length)573 mysql_send_query_start(int *ret, MYSQL *mysql, const char *q, unsigned long length)
574 {
575 MK_ASYNC_START_BODY(
576 mysql_send_query,
577 mysql,
578 {
579 WIN_SET_NONBLOCKING(mysql)
580 parms.mysql= mysql;
581 parms.q= q;
582 parms.length= length;
583 },
584 1,
585 r_int,
586 /* Nothing */)
587 }
588 int STDCALL
mysql_send_query_cont(int * ret,MYSQL * mysql,int ready_status)589 mysql_send_query_cont(int *ret, MYSQL *mysql, int ready_status)
590 {
591 MK_ASYNC_CONT_BODY(
592 mysql,
593 1,
594 r_int)
595 }
596
597 /* Structure used to pass parameters from mysql_store_result_start(). */
598 struct mysql_store_result_params {
599 MYSQL *mysql;
600 };
601 static void
mysql_store_result_start_internal(void * d)602 mysql_store_result_start_internal(void *d)
603 {
604 MK_ASYNC_INTERNAL_BODY(
605 mysql_store_result,
606 (parms->mysql),
607 parms->mysql,
608 MYSQL_RES *,
609 r_ptr)
610 }
611 int STDCALL
mysql_store_result_start(MYSQL_RES ** ret,MYSQL * mysql)612 mysql_store_result_start(MYSQL_RES **ret, MYSQL *mysql)
613 {
614 MK_ASYNC_START_BODY(
615 mysql_store_result,
616 mysql,
617 {
618 WIN_SET_NONBLOCKING(mysql)
619 parms.mysql= mysql;
620 },
621 NULL,
622 r_ptr,
623 /* Nothing */)
624 }
625 int STDCALL
mysql_store_result_cont(MYSQL_RES ** ret,MYSQL * mysql,int ready_status)626 mysql_store_result_cont(MYSQL_RES **ret, MYSQL *mysql, int ready_status)
627 {
628 MK_ASYNC_CONT_BODY(
629 mysql,
630 NULL,
631 r_ptr)
632 }
633
634 /* Structure used to pass parameters from mysql_free_result_start(). */
635 struct mysql_free_result_params {
636 MYSQL_RES *result;
637 };
638 static void
mysql_free_result_start_internal(void * d)639 mysql_free_result_start_internal(void *d)
640 {
641 MK_ASYNC_INTERNAL_BODY_VOID_RETURN(
642 mysql_free_result,
643 (parms->result),
644 parms->result->handle)
645 }
646 int STDCALL
mysql_free_result_start(MYSQL_RES * result)647 mysql_free_result_start(MYSQL_RES *result)
648 {
649 MK_ASYNC_START_BODY_VOID_RETURN(
650 mysql_free_result,
651 result->handle,
652 {
653 WIN_SET_NONBLOCKING(result->handle)
654 parms.result= result;
655 },
656 /*
657 mysql_free_result() can have NULL in result->handle (this happens when all
658 rows have been fetched and mysql_fetch_row() returned NULL.)
659 So we cannot suspend, but it does not matter, as in this case
660 mysql_free_result() cannot block.
661 It is also legitimate to have NULL result, which will do nothing.
662 */
663 if (!result || !result->handle)
664 {
665 mysql_free_result(result);
666 return 0;
667 })
668 }
669 int STDCALL
mysql_free_result_cont(MYSQL_RES * result,int ready_status)670 mysql_free_result_cont(MYSQL_RES *result, int ready_status)
671 {
672 MK_ASYNC_CONT_BODY_VOID_RETURN(result->handle)
673 }
674
675 /* Structure used to pass parameters from mysql_close_slow_part_start(). */
676 struct mysql_close_slow_part_params {
677 MYSQL *sock;
678 };
679 /*
680 We need special handling for mysql_close(), as the first part may block,
681 while the last part needs to free our extra library context stack.
682
683 So we do the first part (mysql_close_slow_part()) non-blocking, but the last
684 part blocking.
685 */
686 static void
mysql_close_slow_part_start_internal(void * d)687 mysql_close_slow_part_start_internal(void *d)
688 {
689 MK_ASYNC_INTERNAL_BODY_VOID_RETURN(
690 mysql_close_slow_part,
691 (parms->sock),
692 parms->sock)
693 }
694
695 int STDCALL
mysql_close_slow_part_start(MYSQL * sock)696 mysql_close_slow_part_start(MYSQL *sock)
697 {
698 MK_ASYNC_START_BODY_VOID_RETURN(
699 mysql_close_slow_part,
700 sock,
701 {
702 WIN_SET_NONBLOCKING(sock)
703 parms.sock= sock;
704 },
705 /* Nothing */)
706 }
707 int STDCALL
mysql_close_slow_part_cont(MYSQL * sock,int ready_status)708 mysql_close_slow_part_cont(MYSQL *sock, int ready_status)
709 {
710 MK_ASYNC_CONT_BODY_VOID_RETURN(sock)
711 }
712 int STDCALL
mysql_close_start(MYSQL * sock)713 mysql_close_start(MYSQL *sock)
714 {
715 int res;
716
717 /* It is legitimate to have NULL sock argument, which will do nothing. */
718 if (sock && sock->net.pvio)
719 {
720 res= mysql_close_slow_part_start(sock);
721 /* If we need to block, return now and do the rest in mysql_close_cont(). */
722 if (res)
723 return res;
724 }
725 mysql_close(sock);
726 return 0;
727 }
728 int STDCALL
mysql_close_cont(MYSQL * sock,int ready_status)729 mysql_close_cont(MYSQL *sock, int ready_status)
730 {
731 int res;
732
733 res= mysql_close_slow_part_cont(sock, ready_status);
734 if (res)
735 return res;
736 mysql_close(sock);
737 return 0;
738 }
739
740 /*
741 These following are not available inside the server (neither blocking or
742 non-blocking).
743 */
744 #ifndef MYSQL_SERVER
745 /* Structure used to pass parameters from mysql_change_user_start(). */
746 struct mysql_change_user_params {
747 MYSQL *mysql;
748 const char *user;
749 const char *passwd;
750 const char *db;
751 };
752 static void
mysql_change_user_start_internal(void * d)753 mysql_change_user_start_internal(void *d)
754 {
755 MK_ASYNC_INTERNAL_BODY(
756 mysql_change_user,
757 (parms->mysql, parms->user, parms->passwd, parms->db),
758 parms->mysql,
759 my_bool,
760 r_my_bool)
761 }
762 int STDCALL
mysql_change_user_start(my_bool * ret,MYSQL * mysql,const char * user,const char * passwd,const char * db)763 mysql_change_user_start(my_bool *ret, MYSQL *mysql, const char *user, const char *passwd, const char *db)
764 {
765 MK_ASYNC_START_BODY(
766 mysql_change_user,
767 mysql,
768 {
769 WIN_SET_NONBLOCKING(mysql)
770 parms.mysql= mysql;
771 parms.user= user;
772 parms.passwd= passwd;
773 parms.db= db;
774 },
775 TRUE,
776 r_my_bool,
777 /* Nothing */)
778 }
779 int STDCALL
mysql_change_user_cont(my_bool * ret,MYSQL * mysql,int ready_status)780 mysql_change_user_cont(my_bool *ret, MYSQL *mysql, int ready_status)
781 {
782 MK_ASYNC_CONT_BODY(
783 mysql,
784 TRUE,
785 r_my_bool)
786 }
787
788 /* Structure used to pass parameters from mysql_query_start(). */
789 struct mysql_query_params {
790 MYSQL *mysql;
791 const char *q;
792 };
793 static void
mysql_query_start_internal(void * d)794 mysql_query_start_internal(void *d)
795 {
796 MK_ASYNC_INTERNAL_BODY(
797 mysql_query,
798 (parms->mysql, parms->q),
799 parms->mysql,
800 int,
801 r_int)
802 }
803 int STDCALL
mysql_query_start(int * ret,MYSQL * mysql,const char * q)804 mysql_query_start(int *ret, MYSQL *mysql, const char *q)
805 {
806 MK_ASYNC_START_BODY(
807 mysql_query,
808 mysql,
809 {
810 WIN_SET_NONBLOCKING(mysql)
811 parms.mysql= mysql;
812 parms.q= q;
813 },
814 1,
815 r_int,
816 /* Nothing */)
817 }
818 int STDCALL
mysql_query_cont(int * ret,MYSQL * mysql,int ready_status)819 mysql_query_cont(int *ret, MYSQL *mysql, int ready_status)
820 {
821 MK_ASYNC_CONT_BODY(
822 mysql,
823 1,
824 r_int)
825 }
826
827 /* Structure used to pass parameters from mysql_shutdown_start(). */
828 struct mysql_shutdown_params {
829 MYSQL *mysql;
830 enum mysql_enum_shutdown_level shutdown_level;
831 };
832 static void
mysql_shutdown_start_internal(void * d)833 mysql_shutdown_start_internal(void *d)
834 {
835 MK_ASYNC_INTERNAL_BODY(
836 mysql_shutdown,
837 (parms->mysql, parms->shutdown_level),
838 parms->mysql,
839 int,
840 r_int)
841 }
842 int STDCALL
mysql_shutdown_start(int * ret,MYSQL * mysql,enum mysql_enum_shutdown_level shutdown_level)843 mysql_shutdown_start(int *ret, MYSQL *mysql, enum mysql_enum_shutdown_level shutdown_level)
844 {
845 MK_ASYNC_START_BODY(
846 mysql_shutdown,
847 mysql,
848 {
849 WIN_SET_NONBLOCKING(mysql)
850 parms.mysql= mysql;
851 parms.shutdown_level= shutdown_level;
852 },
853 1,
854 r_int,
855 /* Nothing */)
856 }
857 int STDCALL
mysql_shutdown_cont(int * ret,MYSQL * mysql,int ready_status)858 mysql_shutdown_cont(int *ret, MYSQL *mysql, int ready_status)
859 {
860 MK_ASYNC_CONT_BODY(
861 mysql,
862 1,
863 r_int)
864 }
865
866 /* Structure used to pass parameters from mysql_dump_debug_info_start(). */
867 struct mysql_dump_debug_info_params {
868 MYSQL *mysql;
869 };
870 static void
mysql_dump_debug_info_start_internal(void * d)871 mysql_dump_debug_info_start_internal(void *d)
872 {
873 MK_ASYNC_INTERNAL_BODY(
874 mysql_dump_debug_info,
875 (parms->mysql),
876 parms->mysql,
877 int,
878 r_int)
879 }
880 int STDCALL
mysql_dump_debug_info_start(int * ret,MYSQL * mysql)881 mysql_dump_debug_info_start(int *ret, MYSQL *mysql)
882 {
883 MK_ASYNC_START_BODY(
884 mysql_dump_debug_info,
885 mysql,
886 {
887 WIN_SET_NONBLOCKING(mysql)
888 parms.mysql= mysql;
889 },
890 1,
891 r_int,
892 /* Nothing */)
893 }
894 int STDCALL
mysql_dump_debug_info_cont(int * ret,MYSQL * mysql,int ready_status)895 mysql_dump_debug_info_cont(int *ret, MYSQL *mysql, int ready_status)
896 {
897 MK_ASYNC_CONT_BODY(
898 mysql,
899 1,
900 r_int)
901 }
902
903 /* Structure used to pass parameters from mysql_refresh_start(). */
904 struct mysql_refresh_params {
905 MYSQL *mysql;
906 unsigned int refresh_options;
907 };
908 static void
mysql_refresh_start_internal(void * d)909 mysql_refresh_start_internal(void *d)
910 {
911 MK_ASYNC_INTERNAL_BODY(
912 mysql_refresh,
913 (parms->mysql, parms->refresh_options),
914 parms->mysql,
915 int,
916 r_int)
917 }
918 int STDCALL
mysql_refresh_start(int * ret,MYSQL * mysql,unsigned int refresh_options)919 mysql_refresh_start(int *ret, MYSQL *mysql, unsigned int refresh_options)
920 {
921 MK_ASYNC_START_BODY(
922 mysql_refresh,
923 mysql,
924 {
925 WIN_SET_NONBLOCKING(mysql)
926 parms.mysql= mysql;
927 parms.refresh_options= refresh_options;
928 },
929 1,
930 r_int,
931 /* Nothing */)
932 }
933 int STDCALL
mysql_refresh_cont(int * ret,MYSQL * mysql,int ready_status)934 mysql_refresh_cont(int *ret, MYSQL *mysql, int ready_status)
935 {
936 MK_ASYNC_CONT_BODY(
937 mysql,
938 1,
939 r_int)
940 }
941
942 /* Structure used to pass parameters from mysql_kill_start(). */
943 struct mysql_kill_params {
944 MYSQL *mysql;
945 unsigned long pid;
946 };
947 static void
mysql_kill_start_internal(void * d)948 mysql_kill_start_internal(void *d)
949 {
950 MK_ASYNC_INTERNAL_BODY(
951 mysql_kill,
952 (parms->mysql, parms->pid),
953 parms->mysql,
954 int,
955 r_int)
956 }
957 int STDCALL
mysql_kill_start(int * ret,MYSQL * mysql,unsigned long pid)958 mysql_kill_start(int *ret, MYSQL *mysql, unsigned long pid)
959 {
960 MK_ASYNC_START_BODY(
961 mysql_kill,
962 mysql,
963 {
964 WIN_SET_NONBLOCKING(mysql)
965 parms.mysql= mysql;
966 parms.pid= pid;
967 },
968 1,
969 r_int,
970 /* Nothing */)
971 }
972 int STDCALL
mysql_kill_cont(int * ret,MYSQL * mysql,int ready_status)973 mysql_kill_cont(int *ret, MYSQL *mysql, int ready_status)
974 {
975 MK_ASYNC_CONT_BODY(
976 mysql,
977 1,
978 r_int)
979 }
980
981 /* Structure used to pass parameters from mysql_set_server_option_start(). */
982 struct mysql_set_server_option_params {
983 MYSQL *mysql;
984 enum enum_mysql_set_option option;
985 };
986 static void
mysql_set_server_option_start_internal(void * d)987 mysql_set_server_option_start_internal(void *d)
988 {
989 MK_ASYNC_INTERNAL_BODY(
990 mysql_set_server_option,
991 (parms->mysql, parms->option),
992 parms->mysql,
993 int,
994 r_int)
995 }
996 int STDCALL
mysql_set_server_option_start(int * ret,MYSQL * mysql,enum enum_mysql_set_option option)997 mysql_set_server_option_start(int *ret, MYSQL *mysql,
998 enum enum_mysql_set_option option)
999 {
1000 MK_ASYNC_START_BODY(
1001 mysql_set_server_option,
1002 mysql,
1003 {
1004 WIN_SET_NONBLOCKING(mysql)
1005 parms.mysql= mysql;
1006 parms.option= option;
1007 },
1008 1,
1009 r_int,
1010 /* Nothing */)
1011 }
1012 int STDCALL
mysql_set_server_option_cont(int * ret,MYSQL * mysql,int ready_status)1013 mysql_set_server_option_cont(int *ret, MYSQL *mysql, int ready_status)
1014 {
1015 MK_ASYNC_CONT_BODY(
1016 mysql,
1017 1,
1018 r_int)
1019 }
1020
1021 /* Structure used to pass parameters from mysql_ping_start(). */
1022 struct mysql_ping_params {
1023 MYSQL *mysql;
1024 };
1025 static void
mysql_ping_start_internal(void * d)1026 mysql_ping_start_internal(void *d)
1027 {
1028 MK_ASYNC_INTERNAL_BODY(
1029 mysql_ping,
1030 (parms->mysql),
1031 parms->mysql,
1032 int,
1033 r_int)
1034 }
1035 int STDCALL
mysql_ping_start(int * ret,MYSQL * mysql)1036 mysql_ping_start(int *ret, MYSQL *mysql)
1037 {
1038 MK_ASYNC_START_BODY(
1039 mysql_ping,
1040 mysql,
1041 {
1042 WIN_SET_NONBLOCKING(mysql)
1043 parms.mysql= mysql;
1044 },
1045 1,
1046 r_int,
1047 /* Nothing */)
1048 }
1049 int STDCALL
mysql_ping_cont(int * ret,MYSQL * mysql,int ready_status)1050 mysql_ping_cont(int *ret, MYSQL *mysql, int ready_status)
1051 {
1052 MK_ASYNC_CONT_BODY(
1053 mysql,
1054 1,
1055 r_int)
1056 }
1057
1058 /* Structure used to pass parameters from mysql_reset_connection_start(). */
1059 struct mysql_reset_connection_params {
1060 MYSQL *mysql;
1061 };
1062 static void
mysql_reset_connection_start_internal(void * d)1063 mysql_reset_connection_start_internal(void *d)
1064 {
1065 MK_ASYNC_INTERNAL_BODY(
1066 mysql_reset_connection,
1067 (parms->mysql),
1068 parms->mysql,
1069 int,
1070 r_int)
1071 }
1072 int STDCALL
mysql_reset_connection_start(int * ret,MYSQL * mysql)1073 mysql_reset_connection_start(int *ret, MYSQL *mysql)
1074 {
1075 MK_ASYNC_START_BODY(
1076 mysql_reset_connection,
1077 mysql,
1078 {
1079 WIN_SET_NONBLOCKING(mysql)
1080 parms.mysql= mysql;
1081 },
1082 1,
1083 r_int,
1084 /* Nothing */)
1085 }
1086 int STDCALL
mysql_reset_connection_cont(int * ret,MYSQL * mysql,int ready_status)1087 mysql_reset_connection_cont(int *ret, MYSQL *mysql, int ready_status)
1088 {
1089 MK_ASYNC_CONT_BODY(
1090 mysql,
1091 1,
1092 r_int)
1093 }
1094
1095 /* Structure used to pass parameters from mysql_stat_start(). */
1096 struct mysql_stat_params {
1097 MYSQL *mysql;
1098 };
1099 static void
mysql_stat_start_internal(void * d)1100 mysql_stat_start_internal(void *d)
1101 {
1102 MK_ASYNC_INTERNAL_BODY(
1103 mysql_stat,
1104 (parms->mysql),
1105 parms->mysql,
1106 const char *,
1107 r_const_ptr)
1108 }
1109 int STDCALL
mysql_stat_start(const char ** ret,MYSQL * mysql)1110 mysql_stat_start(const char **ret, MYSQL *mysql)
1111 {
1112 MK_ASYNC_START_BODY(
1113 mysql_stat,
1114 mysql,
1115 {
1116 WIN_SET_NONBLOCKING(mysql)
1117 parms.mysql= mysql;
1118 },
1119 NULL,
1120 r_const_ptr,
1121 /* Nothing */)
1122 }
1123 int STDCALL
mysql_stat_cont(const char ** ret,MYSQL * mysql,int ready_status)1124 mysql_stat_cont(const char **ret, MYSQL *mysql, int ready_status)
1125 {
1126 MK_ASYNC_CONT_BODY(
1127 mysql,
1128 NULL,
1129 r_const_ptr)
1130 }
1131
1132 /* Structure used to pass parameters from mysql_list_dbs_start(). */
1133 struct mysql_list_dbs_params {
1134 MYSQL *mysql;
1135 const char *wild;
1136 };
1137 static void
mysql_list_dbs_start_internal(void * d)1138 mysql_list_dbs_start_internal(void *d)
1139 {
1140 MK_ASYNC_INTERNAL_BODY(
1141 mysql_list_dbs,
1142 (parms->mysql, parms->wild),
1143 parms->mysql,
1144 MYSQL_RES *,
1145 r_ptr)
1146 }
1147 int STDCALL
mysql_list_dbs_start(MYSQL_RES ** ret,MYSQL * mysql,const char * wild)1148 mysql_list_dbs_start(MYSQL_RES **ret, MYSQL *mysql, const char *wild)
1149 {
1150 MK_ASYNC_START_BODY(
1151 mysql_list_dbs,
1152 mysql,
1153 {
1154 WIN_SET_NONBLOCKING(mysql)
1155 parms.mysql= mysql;
1156 parms.wild= wild;
1157 },
1158 NULL,
1159 r_ptr,
1160 /* Nothing */)
1161 }
1162 int STDCALL
mysql_list_dbs_cont(MYSQL_RES ** ret,MYSQL * mysql,int ready_status)1163 mysql_list_dbs_cont(MYSQL_RES **ret, MYSQL *mysql, int ready_status)
1164 {
1165 MK_ASYNC_CONT_BODY(
1166 mysql,
1167 NULL,
1168 r_ptr)
1169 }
1170
1171 /* Structure used to pass parameters from mysql_list_tables_start(). */
1172 struct mysql_list_tables_params {
1173 MYSQL *mysql;
1174 const char *wild;
1175 };
1176 static void
mysql_list_tables_start_internal(void * d)1177 mysql_list_tables_start_internal(void *d)
1178 {
1179 MK_ASYNC_INTERNAL_BODY(
1180 mysql_list_tables,
1181 (parms->mysql, parms->wild),
1182 parms->mysql,
1183 MYSQL_RES *,
1184 r_ptr)
1185 }
1186 int STDCALL
mysql_list_tables_start(MYSQL_RES ** ret,MYSQL * mysql,const char * wild)1187 mysql_list_tables_start(MYSQL_RES **ret, MYSQL *mysql, const char *wild)
1188 {
1189 MK_ASYNC_START_BODY(
1190 mysql_list_tables,
1191 mysql,
1192 {
1193 WIN_SET_NONBLOCKING(mysql)
1194 parms.mysql= mysql;
1195 parms.wild= wild;
1196 },
1197 NULL,
1198 r_ptr,
1199 /* Nothing */)
1200 }
1201 int STDCALL
mysql_list_tables_cont(MYSQL_RES ** ret,MYSQL * mysql,int ready_status)1202 mysql_list_tables_cont(MYSQL_RES **ret, MYSQL *mysql, int ready_status)
1203 {
1204 MK_ASYNC_CONT_BODY(
1205 mysql,
1206 NULL,
1207 r_ptr)
1208 }
1209
1210 /* Structure used to pass parameters from mysql_list_processes_start(). */
1211 struct mysql_list_processes_params {
1212 MYSQL *mysql;
1213 };
1214 static void
mysql_list_processes_start_internal(void * d)1215 mysql_list_processes_start_internal(void *d)
1216 {
1217 MK_ASYNC_INTERNAL_BODY(
1218 mysql_list_processes,
1219 (parms->mysql),
1220 parms->mysql,
1221 MYSQL_RES *,
1222 r_ptr)
1223 }
1224 int STDCALL
mysql_list_processes_start(MYSQL_RES ** ret,MYSQL * mysql)1225 mysql_list_processes_start(MYSQL_RES **ret, MYSQL *mysql)
1226 {
1227 MK_ASYNC_START_BODY(
1228 mysql_list_processes,
1229 mysql,
1230 {
1231 WIN_SET_NONBLOCKING(mysql)
1232 parms.mysql= mysql;
1233 },
1234 NULL,
1235 r_ptr,
1236 /* Nothing */)
1237 }
1238 int STDCALL
mysql_list_processes_cont(MYSQL_RES ** ret,MYSQL * mysql,int ready_status)1239 mysql_list_processes_cont(MYSQL_RES **ret, MYSQL *mysql, int ready_status)
1240 {
1241 MK_ASYNC_CONT_BODY(
1242 mysql,
1243 NULL,
1244 r_ptr)
1245 }
1246
1247 /* Structure used to pass parameters from mysql_list_fields_start(). */
1248 struct mysql_list_fields_params {
1249 MYSQL *mysql;
1250 const char *table;
1251 const char *wild;
1252 };
1253 static void
mysql_list_fields_start_internal(void * d)1254 mysql_list_fields_start_internal(void *d)
1255 {
1256 MK_ASYNC_INTERNAL_BODY(
1257 mysql_list_fields,
1258 (parms->mysql, parms->table, parms->wild),
1259 parms->mysql,
1260 MYSQL_RES *,
1261 r_ptr)
1262 }
1263 int STDCALL
mysql_list_fields_start(MYSQL_RES ** ret,MYSQL * mysql,const char * table,const char * wild)1264 mysql_list_fields_start(MYSQL_RES **ret, MYSQL *mysql, const char *table,
1265 const char *wild)
1266 {
1267 MK_ASYNC_START_BODY(
1268 mysql_list_fields,
1269 mysql,
1270 {
1271 WIN_SET_NONBLOCKING(mysql)
1272 parms.mysql= mysql;
1273 parms.table= table;
1274 parms.wild= wild;
1275 },
1276 NULL,
1277 r_ptr,
1278 /* Nothing */)
1279 }
1280 int STDCALL
mysql_list_fields_cont(MYSQL_RES ** ret,MYSQL * mysql,int ready_status)1281 mysql_list_fields_cont(MYSQL_RES **ret, MYSQL *mysql, int ready_status)
1282 {
1283 MK_ASYNC_CONT_BODY(
1284 mysql,
1285 NULL,
1286 r_ptr)
1287 }
1288
1289 /* Structure used to pass parameters from mysql_read_query_result_start(). */
1290 struct mysql_read_query_result_params {
1291 MYSQL *mysql;
1292 };
1293 static void
mysql_read_query_result_start_internal(void * d)1294 mysql_read_query_result_start_internal(void *d)
1295 {
1296 MK_ASYNC_INTERNAL_BODY(
1297 mysql_read_query_result,
1298 (parms->mysql),
1299 parms->mysql,
1300 my_bool,
1301 r_my_bool)
1302 }
1303 int STDCALL
mysql_read_query_result_start(my_bool * ret,MYSQL * mysql)1304 mysql_read_query_result_start(my_bool *ret, MYSQL *mysql)
1305 {
1306 MK_ASYNC_START_BODY(
1307 mysql_read_query_result,
1308 mysql,
1309 {
1310 WIN_SET_NONBLOCKING(mysql)
1311 parms.mysql= mysql;
1312 },
1313 TRUE,
1314 r_my_bool,
1315 /* Nothing */)
1316 }
1317 int STDCALL
mysql_read_query_result_cont(my_bool * ret,MYSQL * mysql,int ready_status)1318 mysql_read_query_result_cont(my_bool *ret, MYSQL *mysql, int ready_status)
1319 {
1320 MK_ASYNC_CONT_BODY(
1321 mysql,
1322 TRUE,
1323 r_my_bool)
1324 }
1325
1326 /* Structure used to pass parameters from mysql_stmt_prepare_start(). */
1327 struct mysql_stmt_prepare_params {
1328 MYSQL_STMT *stmt;
1329 const char *query;
1330 unsigned long length;
1331 };
1332 static void
mysql_stmt_prepare_start_internal(void * d)1333 mysql_stmt_prepare_start_internal(void *d)
1334 {
1335 MK_ASYNC_INTERNAL_BODY(
1336 mysql_stmt_prepare,
1337 (parms->stmt, parms->query, parms->length),
1338 parms->stmt->mysql,
1339 int,
1340 r_int)
1341 }
1342 int STDCALL
mysql_stmt_prepare_start(int * ret,MYSQL_STMT * stmt,const char * query,unsigned long length)1343 mysql_stmt_prepare_start(int *ret, MYSQL_STMT *stmt, const char *query,
1344 unsigned long length)
1345 {
1346 MK_ASYNC_START_BODY(
1347 mysql_stmt_prepare,
1348 stmt->mysql,
1349 {
1350 WIN_SET_NONBLOCKING(stmt->mysql)
1351 parms.stmt= stmt;
1352 parms.query= query;
1353 parms.length= length;
1354 },
1355 1,
1356 r_int,
1357 /* If stmt->mysql==NULL then we will not block so can call directly. */
1358 if (!stmt->mysql)
1359 {
1360 *ret= mysql_stmt_prepare(stmt, query, length);
1361 return 0;
1362 })
1363 }
1364 int STDCALL
mysql_stmt_prepare_cont(int * ret,MYSQL_STMT * stmt,int ready_status)1365 mysql_stmt_prepare_cont(int *ret, MYSQL_STMT *stmt, int ready_status)
1366 {
1367 MK_ASYNC_CONT_BODY(
1368 stmt->mysql,
1369 1,
1370 r_int)
1371 }
1372
1373 /* Structure used to pass parameters from mysql_stmt_execute_start(). */
1374 struct mysql_stmt_execute_params {
1375 MYSQL_STMT *stmt;
1376 };
1377 static void
mysql_stmt_execute_start_internal(void * d)1378 mysql_stmt_execute_start_internal(void *d)
1379 {
1380 MK_ASYNC_INTERNAL_BODY(
1381 mysql_stmt_execute,
1382 (parms->stmt),
1383 parms->stmt->mysql,
1384 int,
1385 r_int)
1386 }
1387 int STDCALL
mysql_stmt_execute_start(int * ret,MYSQL_STMT * stmt)1388 mysql_stmt_execute_start(int *ret, MYSQL_STMT *stmt)
1389 {
1390 MK_ASYNC_START_BODY(
1391 mysql_stmt_execute,
1392 stmt->mysql,
1393 {
1394 WIN_SET_NONBLOCKING(stmt->mysql)
1395 parms.stmt= stmt;
1396 },
1397 1,
1398 r_int,
1399 /*
1400 If eg. mysql_change_user(), stmt->mysql will be NULL.
1401 In this case, we cannot block.
1402 */
1403 if (!stmt->mysql)
1404 {
1405 *ret= mysql_stmt_execute(stmt);
1406 return 0;
1407 })
1408 }
1409 int STDCALL
mysql_stmt_execute_cont(int * ret,MYSQL_STMT * stmt,int ready_status)1410 mysql_stmt_execute_cont(int *ret, MYSQL_STMT *stmt, int ready_status)
1411 {
1412 MK_ASYNC_CONT_BODY(
1413 stmt->mysql,
1414 1,
1415 r_int)
1416 }
1417
1418 /* Structure used to pass parameters from mysql_stmt_fetch_start(). */
1419 struct mysql_stmt_fetch_params {
1420 MYSQL_STMT *stmt;
1421 };
1422 static void
mysql_stmt_fetch_start_internal(void * d)1423 mysql_stmt_fetch_start_internal(void *d)
1424 {
1425 MK_ASYNC_INTERNAL_BODY(
1426 mysql_stmt_fetch,
1427 (parms->stmt),
1428 parms->stmt->mysql,
1429 int,
1430 r_int)
1431 }
1432 int STDCALL
mysql_stmt_fetch_start(int * ret,MYSQL_STMT * stmt)1433 mysql_stmt_fetch_start(int *ret, MYSQL_STMT *stmt)
1434 {
1435 MK_ASYNC_START_BODY(
1436 mysql_stmt_fetch,
1437 stmt->mysql,
1438 {
1439 WIN_SET_NONBLOCKING(stmt->mysql)
1440 parms.stmt= stmt;
1441 },
1442 1,
1443 r_int,
1444 /* If stmt->mysql==NULL then we will not block so can call directly. */
1445 if (!stmt->mysql)
1446 {
1447 *ret= mysql_stmt_fetch(stmt);
1448 return 0;
1449 })
1450 }
1451 int STDCALL
mysql_stmt_fetch_cont(int * ret,MYSQL_STMT * stmt,int ready_status)1452 mysql_stmt_fetch_cont(int *ret, MYSQL_STMT *stmt, int ready_status)
1453 {
1454 MK_ASYNC_CONT_BODY(
1455 stmt->mysql,
1456 1,
1457 r_int)
1458 }
1459
1460 /* Structure used to pass parameters from mysql_stmt_store_result_start(). */
1461 struct mysql_stmt_store_result_params {
1462 MYSQL_STMT *stmt;
1463 };
1464 static void
mysql_stmt_store_result_start_internal(void * d)1465 mysql_stmt_store_result_start_internal(void *d)
1466 {
1467 MK_ASYNC_INTERNAL_BODY(
1468 mysql_stmt_store_result,
1469 (parms->stmt),
1470 parms->stmt->mysql,
1471 int,
1472 r_int)
1473 }
1474 int STDCALL
mysql_stmt_store_result_start(int * ret,MYSQL_STMT * stmt)1475 mysql_stmt_store_result_start(int *ret, MYSQL_STMT *stmt)
1476 {
1477 MK_ASYNC_START_BODY(
1478 mysql_stmt_store_result,
1479 stmt->mysql,
1480 {
1481 WIN_SET_NONBLOCKING(stmt->mysql)
1482 parms.stmt= stmt;
1483 },
1484 1,
1485 r_int,
1486 /* If stmt->mysql==NULL then we will not block so can call directly. */
1487 if (!stmt->mysql)
1488 {
1489 *ret= mysql_stmt_store_result(stmt);
1490 return 0;
1491 })
1492 }
1493 int STDCALL
mysql_stmt_store_result_cont(int * ret,MYSQL_STMT * stmt,int ready_status)1494 mysql_stmt_store_result_cont(int *ret, MYSQL_STMT *stmt, int ready_status)
1495 {
1496 MK_ASYNC_CONT_BODY(
1497 stmt->mysql,
1498 1,
1499 r_int)
1500 }
1501
1502 /* Structure used to pass parameters from mysql_stmt_close_start(). */
1503 struct mysql_stmt_close_params {
1504 MYSQL_STMT *stmt;
1505 };
1506 static void
mysql_stmt_close_start_internal(void * d)1507 mysql_stmt_close_start_internal(void *d)
1508 {
1509 MK_ASYNC_INTERNAL_BODY(
1510 mysql_stmt_close,
1511 (parms->stmt),
1512 parms->stmt->mysql,
1513 my_bool,
1514 r_my_bool)
1515 }
1516 int STDCALL
mysql_stmt_close_start(my_bool * ret,MYSQL_STMT * stmt)1517 mysql_stmt_close_start(my_bool *ret, MYSQL_STMT *stmt)
1518 {
1519 MK_ASYNC_START_BODY(
1520 mysql_stmt_close,
1521 stmt->mysql,
1522 {
1523 WIN_SET_NONBLOCKING(stmt->mysql)
1524 parms.stmt= stmt;
1525 },
1526 TRUE,
1527 r_my_bool,
1528 /* If stmt->mysql==NULL then we will not block so can call directly. */
1529 if (!stmt->mysql)
1530 {
1531 *ret= mysql_stmt_close(stmt);
1532 return 0;
1533 })
1534 }
1535 int STDCALL
mysql_stmt_close_cont(my_bool * ret,MYSQL_STMT * stmt,int ready_status)1536 mysql_stmt_close_cont(my_bool *ret, MYSQL_STMT *stmt, int ready_status)
1537 {
1538 MK_ASYNC_CONT_BODY(
1539 stmt->mysql,
1540 TRUE,
1541 r_my_bool)
1542 }
1543
1544 /* Structure used to pass parameters from mysql_stmt_reset_start(). */
1545 struct mysql_stmt_reset_params {
1546 MYSQL_STMT *stmt;
1547 };
1548 static void
mysql_stmt_reset_start_internal(void * d)1549 mysql_stmt_reset_start_internal(void *d)
1550 {
1551 MK_ASYNC_INTERNAL_BODY(
1552 mysql_stmt_reset,
1553 (parms->stmt),
1554 parms->stmt->mysql,
1555 my_bool,
1556 r_my_bool)
1557 }
1558 int STDCALL
mysql_stmt_reset_start(my_bool * ret,MYSQL_STMT * stmt)1559 mysql_stmt_reset_start(my_bool *ret, MYSQL_STMT *stmt)
1560 {
1561 MK_ASYNC_START_BODY(
1562 mysql_stmt_reset,
1563 stmt->mysql,
1564 {
1565 WIN_SET_NONBLOCKING(stmt->mysql)
1566 parms.stmt= stmt;
1567 },
1568 TRUE,
1569 r_my_bool,
1570 /* If stmt->mysql==NULL then we will not block so can call directly. */
1571 if (!stmt->mysql)
1572 {
1573 *ret= mysql_stmt_reset(stmt);
1574 return 0;
1575 })
1576 }
1577 int STDCALL
mysql_stmt_reset_cont(my_bool * ret,MYSQL_STMT * stmt,int ready_status)1578 mysql_stmt_reset_cont(my_bool *ret, MYSQL_STMT *stmt, int ready_status)
1579 {
1580 MK_ASYNC_CONT_BODY(
1581 stmt->mysql,
1582 TRUE,
1583 r_my_bool)
1584 }
1585
1586 /* Structure used to pass parameters from mysql_stmt_free_result_start(). */
1587 struct mysql_stmt_free_result_params {
1588 MYSQL_STMT *stmt;
1589 };
1590 static void
mysql_stmt_free_result_start_internal(void * d)1591 mysql_stmt_free_result_start_internal(void *d)
1592 {
1593 MK_ASYNC_INTERNAL_BODY(
1594 mysql_stmt_free_result,
1595 (parms->stmt),
1596 parms->stmt->mysql,
1597 my_bool,
1598 r_my_bool)
1599 }
1600 int STDCALL
mysql_stmt_free_result_start(my_bool * ret,MYSQL_STMT * stmt)1601 mysql_stmt_free_result_start(my_bool *ret, MYSQL_STMT *stmt)
1602 {
1603 MK_ASYNC_START_BODY(
1604 mysql_stmt_free_result,
1605 stmt->mysql,
1606 {
1607 WIN_SET_NONBLOCKING(stmt->mysql)
1608 parms.stmt= stmt;
1609 },
1610 TRUE,
1611 r_my_bool,
1612 /* If stmt->mysql==NULL then we will not block so can call directly. */
1613 if (!stmt->mysql)
1614 {
1615 *ret= mysql_stmt_free_result(stmt);
1616 return 0;
1617 })
1618 }
1619 int STDCALL
mysql_stmt_free_result_cont(my_bool * ret,MYSQL_STMT * stmt,int ready_status)1620 mysql_stmt_free_result_cont(my_bool *ret, MYSQL_STMT *stmt, int ready_status)
1621 {
1622 MK_ASYNC_CONT_BODY(
1623 stmt->mysql,
1624 TRUE,
1625 r_my_bool)
1626 }
1627
1628 /* Structure used to pass parameters from mysql_stmt_send_long_data_start(). */
1629 struct mysql_stmt_send_long_data_params {
1630 MYSQL_STMT *stmt;
1631 unsigned int param_number;
1632 const char *data;
1633 unsigned long length;
1634 };
1635 static void
mysql_stmt_send_long_data_start_internal(void * d)1636 mysql_stmt_send_long_data_start_internal(void *d)
1637 {
1638 MK_ASYNC_INTERNAL_BODY(
1639 mysql_stmt_send_long_data,
1640 (parms->stmt, parms->param_number, parms->data, parms->length),
1641 parms->stmt->mysql,
1642 my_bool,
1643 r_my_bool)
1644 }
1645 int STDCALL
mysql_stmt_send_long_data_start(my_bool * ret,MYSQL_STMT * stmt,unsigned int param_number,const char * data,unsigned long length)1646 mysql_stmt_send_long_data_start(my_bool *ret, MYSQL_STMT *stmt,
1647 unsigned int param_number,
1648 const char *data, unsigned long length)
1649 {
1650 MK_ASYNC_START_BODY(
1651 mysql_stmt_send_long_data,
1652 stmt->mysql,
1653 {
1654 WIN_SET_NONBLOCKING(stmt->mysql)
1655 parms.stmt= stmt;
1656 parms.param_number= param_number;
1657 parms.data= data;
1658 parms.length= length;
1659 },
1660 TRUE,
1661 r_my_bool,
1662 /* If stmt->mysql==NULL then we will not block so can call directly. */
1663 if (!stmt->mysql)
1664 {
1665 *ret= mysql_stmt_send_long_data(stmt, param_number, data, length);
1666 return 0;
1667 })
1668 }
1669 int STDCALL
mysql_stmt_send_long_data_cont(my_bool * ret,MYSQL_STMT * stmt,int ready_status)1670 mysql_stmt_send_long_data_cont(my_bool *ret, MYSQL_STMT *stmt, int ready_status)
1671 {
1672 MK_ASYNC_CONT_BODY(
1673 stmt->mysql,
1674 TRUE,
1675 r_my_bool)
1676 }
1677
1678 /* Structure used to pass parameters from mysql_commit_start(). */
1679 struct mysql_commit_params {
1680 MYSQL *mysql;
1681 };
1682 static void
mysql_commit_start_internal(void * d)1683 mysql_commit_start_internal(void *d)
1684 {
1685 MK_ASYNC_INTERNAL_BODY(
1686 mysql_commit,
1687 (parms->mysql),
1688 parms->mysql,
1689 my_bool,
1690 r_my_bool)
1691 }
1692 int STDCALL
mysql_commit_start(my_bool * ret,MYSQL * mysql)1693 mysql_commit_start(my_bool *ret, MYSQL *mysql)
1694 {
1695 MK_ASYNC_START_BODY(
1696 mysql_commit,
1697 mysql,
1698 {
1699 WIN_SET_NONBLOCKING(mysql)
1700 parms.mysql= mysql;
1701 },
1702 TRUE,
1703 r_my_bool,
1704 /* Nothing */)
1705 }
1706 int STDCALL
mysql_commit_cont(my_bool * ret,MYSQL * mysql,int ready_status)1707 mysql_commit_cont(my_bool *ret, MYSQL *mysql, int ready_status)
1708 {
1709 MK_ASYNC_CONT_BODY(
1710 mysql,
1711 TRUE,
1712 r_my_bool)
1713 }
1714
1715 /* Structure used to pass parameters from mysql_rollback_start(). */
1716 struct mysql_rollback_params {
1717 MYSQL *mysql;
1718 };
1719 static void
mysql_rollback_start_internal(void * d)1720 mysql_rollback_start_internal(void *d)
1721 {
1722 MK_ASYNC_INTERNAL_BODY(
1723 mysql_rollback,
1724 (parms->mysql),
1725 parms->mysql,
1726 my_bool,
1727 r_my_bool)
1728 }
1729 int STDCALL
mysql_rollback_start(my_bool * ret,MYSQL * mysql)1730 mysql_rollback_start(my_bool *ret, MYSQL *mysql)
1731 {
1732 MK_ASYNC_START_BODY(
1733 mysql_rollback,
1734 mysql,
1735 {
1736 WIN_SET_NONBLOCKING(mysql)
1737 parms.mysql= mysql;
1738 },
1739 TRUE,
1740 r_my_bool,
1741 /* Nothing */)
1742 }
1743 int STDCALL
mysql_rollback_cont(my_bool * ret,MYSQL * mysql,int ready_status)1744 mysql_rollback_cont(my_bool *ret, MYSQL *mysql, int ready_status)
1745 {
1746 MK_ASYNC_CONT_BODY(
1747 mysql,
1748 TRUE,
1749 r_my_bool)
1750 }
1751
1752 /* Structure used to pass parameters from mysql_autocommit_start(). */
1753 struct mysql_autocommit_params {
1754 MYSQL *mysql;
1755 my_bool auto_mode;
1756 };
1757 static void
mysql_autocommit_start_internal(void * d)1758 mysql_autocommit_start_internal(void *d)
1759 {
1760 MK_ASYNC_INTERNAL_BODY(
1761 mysql_autocommit,
1762 (parms->mysql, parms->auto_mode),
1763 parms->mysql,
1764 my_bool,
1765 r_my_bool)
1766 }
1767 int STDCALL
mysql_autocommit_start(my_bool * ret,MYSQL * mysql,my_bool auto_mode)1768 mysql_autocommit_start(my_bool *ret, MYSQL *mysql, my_bool auto_mode)
1769 {
1770 MK_ASYNC_START_BODY(
1771 mysql_autocommit,
1772 mysql,
1773 {
1774 WIN_SET_NONBLOCKING(mysql)
1775 parms.mysql= mysql;
1776 parms.auto_mode= auto_mode;
1777 },
1778 TRUE,
1779 r_my_bool,
1780 /* Nothing */)
1781 }
1782 int STDCALL
mysql_autocommit_cont(my_bool * ret,MYSQL * mysql,int ready_status)1783 mysql_autocommit_cont(my_bool *ret, MYSQL *mysql, int ready_status)
1784 {
1785 MK_ASYNC_CONT_BODY(
1786 mysql,
1787 TRUE,
1788 r_my_bool)
1789 }
1790
1791 /* Structure used to pass parameters from mysql_next_result_start(). */
1792 struct mysql_next_result_params {
1793 MYSQL *mysql;
1794 };
1795 static void
mysql_next_result_start_internal(void * d)1796 mysql_next_result_start_internal(void *d)
1797 {
1798 MK_ASYNC_INTERNAL_BODY(
1799 mysql_next_result,
1800 (parms->mysql),
1801 parms->mysql,
1802 int,
1803 r_int)
1804 }
1805 int STDCALL
mysql_next_result_start(int * ret,MYSQL * mysql)1806 mysql_next_result_start(int *ret, MYSQL *mysql)
1807 {
1808 MK_ASYNC_START_BODY(
1809 mysql_next_result,
1810 mysql,
1811 {
1812 WIN_SET_NONBLOCKING(mysql)
1813 parms.mysql= mysql;
1814 },
1815 1,
1816 r_int,
1817 /* Nothing */)
1818 }
1819 int STDCALL
mysql_next_result_cont(int * ret,MYSQL * mysql,int ready_status)1820 mysql_next_result_cont(int *ret, MYSQL *mysql, int ready_status)
1821 {
1822 MK_ASYNC_CONT_BODY(
1823 mysql,
1824 1,
1825 r_int)
1826 }
1827
1828 /* Structure used to pass parameters from mysql_stmt_next_result_start(). */
1829 struct mysql_stmt_next_result_params {
1830 MYSQL_STMT *stmt;
1831 };
1832 static void
mysql_stmt_next_result_start_internal(void * d)1833 mysql_stmt_next_result_start_internal(void *d)
1834 {
1835 MK_ASYNC_INTERNAL_BODY(
1836 mysql_stmt_next_result,
1837 (parms->stmt),
1838 parms->stmt->mysql,
1839 int,
1840 r_int)
1841 }
1842 int STDCALL
mysql_stmt_next_result_start(int * ret,MYSQL_STMT * stmt)1843 mysql_stmt_next_result_start(int *ret, MYSQL_STMT *stmt)
1844 {
1845 MK_ASYNC_START_BODY(
1846 mysql_stmt_next_result,
1847 stmt->mysql,
1848 {
1849 WIN_SET_NONBLOCKING(stmt->mysql)
1850 parms.stmt= stmt;
1851 },
1852 1,
1853 r_int,
1854 /* Nothing */)
1855 }
1856 int STDCALL
mysql_stmt_next_result_cont(int * ret,MYSQL_STMT * stmt,int ready_status)1857 mysql_stmt_next_result_cont(int *ret, MYSQL_STMT *stmt, int ready_status)
1858 {
1859 MK_ASYNC_CONT_BODY(
1860 stmt->mysql,
1861 1,
1862 r_int)
1863 }
1864 #endif
1865
1866
1867 /*
1868 The following functions are deprecated, and so have no non-blocking version:
1869
1870 mysql_connect
1871 mysql_create_db
1872 mysql_drop_db
1873 */
1874
1875 /*
1876 The following functions can newer block, and so do not have special
1877 non-blocking versions:
1878
1879 mysql_num_rows()
1880 mysql_num_fields()
1881 mysql_eof()
1882 mysql_fetch_field_direct()
1883 mysql_fetch_fields()
1884 mysql_row_tell()
1885 mysql_field_tell()
1886 mysql_field_count()
1887 mysql_affected_rows()
1888 mysql_insert_id()
1889 mysql_errno()
1890 mysql_error()
1891 mysql_sqlstate()
1892 mysql_warning_count()
1893 mysql_info()
1894 mysql_thread_id()
1895 mysql_character_set_name()
1896 mysql_init()
1897 mysql_ssl_set()
1898 mysql_get_ssl_cipher()
1899 mysql_use_result()
1900 mysql_get_character_set_info()
1901 mysql_set_local_infile_handler()
1902 mysql_set_local_infile_default()
1903 mysql_get_server_info()
1904 mysql_get_server_name()
1905 mysql_get_client_info()
1906 mysql_get_client_version()
1907 mysql_get_host_info()
1908 mysql_get_server_version()
1909 mysql_get_proto_info()
1910 mysql_options()
1911 mysql_data_seek()
1912 mysql_row_seek()
1913 mysql_field_seek()
1914 mysql_fetch_lengths()
1915 mysql_fetch_field()
1916 mysql_escape_string()
1917 mysql_hex_string()
1918 mysql_real_escape_string()
1919 mysql_debug()
1920 myodbc_remove_escape()
1921 mysql_thread_safe()
1922 mysql_embedded()
1923 mariadb_connection()
1924 mysql_stmt_init()
1925 mysql_stmt_fetch_column()
1926 mysql_stmt_param_count()
1927 mysql_stmt_attr_set()
1928 mysql_stmt_attr_get()
1929 mysql_stmt_bind_param()
1930 mysql_stmt_bind_result()
1931 mysql_stmt_result_metadata()
1932 mysql_stmt_param_metadata()
1933 mysql_stmt_errno()
1934 mysql_stmt_error()
1935 mysql_stmt_sqlstate()
1936 mysql_stmt_row_seek()
1937 mysql_stmt_row_tell()
1938 mysql_stmt_data_seek()
1939 mysql_stmt_num_rows()
1940 mysql_stmt_affected_rows()
1941 mysql_stmt_insert_id()
1942 mysql_stmt_field_count()
1943 mysql_more_results()
1944 mysql_get_socket()
1945 mysql_get_timeout_value()
1946 */
1947