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) { \ |
44 | my_bool old_mode; \ |
45 | if ((mysql)->net.pvio) ma_pvio_blocking((mysql)->net.pvio, FALSE, &old_mode); \ |
46 | } |
47 | #else |
48 | #define WIN_SET_NONBLOCKING(mysql) |
49 | #endif |
50 | |
51 | extern void mysql_close_slow_part(MYSQL *mysql); |
52 | |
53 | |
54 | void |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
708 | mysql_close_slow_part_cont(MYSQL *sock, int ready_status) |
709 | { |
710 | MK_ASYNC_CONT_BODY_VOID_RETURN(sock) |
711 | } |
712 | int STDCALL |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 | |