Skip to content

Commit c1fffc3

Browse files
author
Bharathy Satish
committed
WL#11381: Add asynchronous support into the mysql protocol
C APIs are synchronous, which means client sends a request and waits until server responds. This makes applications to not do anything until server sends a response. There can be a requirement where client is not bothered about when server sends data back, client can submit a query, do some other tasks and when in need of server response, client can check if server has sent the response and act accordingly. Thus making a need to implement asynchronous communication between client and server. This WL introduces new non blocking version of above C APIs which does not wait for data to be available on the socket to be read. These APIs will return immediately with a return status. Return status is used to decide if the API has completed its operation or needs to be called again at some later point in time to complete the operation. RB: 21150 Reviewed-by: Georgi Kodinov Ramil Kalimullin
1 parent b8be8ee commit c1fffc3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+5346
-533
lines changed

client/mysqltest.cc

+450-79
Large diffs are not rendered by default.

include/errmsg.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef ERRMSG_INCLUDED
22
#define ERRMSG_INCLUDED
33

4-
/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
4+
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
55
66
This program is free software; you can redistribute it and/or modify
77
it under the terms of the GNU General Public License, version 2.0,
@@ -123,7 +123,8 @@ extern const char *client_errors[]; /* Error messages */
123123
#define CR_INSECURE_API_ERR 2062
124124
#define CR_FILE_NAME_TOO_LONG 2063
125125
#define CR_SSL_FIPS_MODE_ERR 2064
126-
#define CR_ERROR_LAST /*Copy last error nr:*/ 2064
126+
#define CR_COMPRESSION_NOT_SUPPORTED 2065
127+
#define CR_ERROR_LAST /*Copy last error nr:*/ 2065
127128
/* Add error numbers before CR_ERROR_LAST and change it accordingly. */
128129

129130
/* Visual Studio requires '__inline' for C code */

include/mysql.h

+18
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,20 @@ int STDCALL mysql_real_query(MYSQL *mysql, const char *q, unsigned long length);
465465
MYSQL_RES *STDCALL mysql_store_result(MYSQL *mysql);
466466
MYSQL_RES *STDCALL mysql_use_result(MYSQL *mysql);
467467

468+
enum net_async_status STDCALL mysql_real_connect_nonblocking(
469+
MYSQL *mysql, const char *host, const char *user, const char *passwd,
470+
const char *db, unsigned int port, const char *unix_socket,
471+
unsigned long clientflag);
472+
enum net_async_status STDCALL mysql_send_query_nonblocking(
473+
MYSQL *mysql, const char *query, unsigned long length);
474+
enum net_async_status STDCALL mysql_real_query_nonblocking(
475+
MYSQL *mysql, const char *query, unsigned long length);
476+
enum net_async_status STDCALL
477+
mysql_store_result_nonblocking(MYSQL *mysql, MYSQL_RES **result);
478+
enum net_async_status STDCALL mysql_next_result_nonblocking(MYSQL *mysql);
479+
enum net_async_status STDCALL mysql_select_db_nonblocking(MYSQL *mysql,
480+
const char *db,
481+
bool *error);
468482
void STDCALL mysql_get_character_set_info(MYSQL *mysql,
469483
MY_CHARSET_INFO *charset);
470484

@@ -510,12 +524,16 @@ int STDCALL mysql_options4(MYSQL *mysql, enum mysql_option option,
510524
int STDCALL mysql_get_option(MYSQL *mysql, enum mysql_option option,
511525
const void *arg);
512526
void STDCALL mysql_free_result(MYSQL_RES *result);
527+
enum net_async_status STDCALL mysql_free_result_nonblocking(MYSQL_RES *result);
513528
void STDCALL mysql_data_seek(MYSQL_RES *result, my_ulonglong offset);
514529
MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result,
515530
MYSQL_ROW_OFFSET offset);
516531
MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result,
517532
MYSQL_FIELD_OFFSET offset);
518533
MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);
534+
enum net_async_status STDCALL mysql_fetch_row_nonblocking(MYSQL_RES *res,
535+
MYSQL_ROW *row);
536+
519537
unsigned long *STDCALL mysql_fetch_lengths(MYSQL_RES *result);
520538
MYSQL_FIELD *STDCALL mysql_fetch_field(MYSQL_RES *result);
521539
MYSQL_RES *STDCALL mysql_list_fields(MYSQL *mysql, const char *table,

include/mysql.h.pp

+33-1
Original file line numberDiff line numberDiff line change
@@ -264,16 +264,31 @@
264264
} protocol;
265265
int socket;
266266
};
267+
enum net_async_status {
268+
NET_ASYNC_COMPLETE = 0,
269+
NET_ASYNC_NOT_READY,
270+
NET_ASYNC_ERROR,
271+
NET_ASYNC_COMPLETE_WITH_MORE_RESULTS
272+
};
267273
typedef struct MYSQL_PLUGIN_VIO {
268274
int (*read_packet)(struct MYSQL_PLUGIN_VIO *vio, unsigned char **buf);
269275
int (*write_packet)(struct MYSQL_PLUGIN_VIO *vio, const unsigned char *packet,
270276
int packet_len);
271277
void (*info)(struct MYSQL_PLUGIN_VIO *vio,
272278
struct MYSQL_PLUGIN_VIO_INFO *info);
279+
enum net_async_status (*read_packet_nonblocking)(struct MYSQL_PLUGIN_VIO *vio,
280+
unsigned char **buf,
281+
int *result);
282+
enum net_async_status (*write_packet_nonblocking)(
283+
struct MYSQL_PLUGIN_VIO *vio, const unsigned char *pkt, int pkt_len,
284+
int *result);
273285
} MYSQL_PLUGIN_VIO;
274286
struct auth_plugin_t {
275287
int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; const char *license; void *mysql_api; int (*init)(char *, size_t, int, va_list); int (*deinit)(void); int (*options)(const char *option, const void *);
276288
int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct MYSQL *mysql);
289+
enum net_async_status (*authenticate_user_nonblocking)(MYSQL_PLUGIN_VIO *vio,
290+
struct MYSQL *mysql,
291+
int *result);
277292
};
278293
typedef struct auth_plugin_t st_mysql_client_plugin_AUTHENTICATION;
279294
struct st_mysql_client_plugin *mysql_load_plugin(struct MYSQL *mysql,
@@ -309,7 +324,7 @@
309324
void finish_client_errs(void);
310325
extern const char *client_errors[];
311326
static inline const char *ER_CLIENT(int client_errno) {
312-
if (client_errno >= 2000 && client_errno <= 2064)
327+
if (client_errno >= 2000 && client_errno <= 2065)
313328
return client_errors[client_errno - 2000];
314329
return client_errors[2000];
315330
}
@@ -561,6 +576,20 @@
561576
int mysql_real_query(MYSQL *mysql, const char *q, unsigned long length);
562577
MYSQL_RES * mysql_store_result(MYSQL *mysql);
563578
MYSQL_RES * mysql_use_result(MYSQL *mysql);
579+
enum net_async_status mysql_real_connect_nonblocking(
580+
MYSQL *mysql, const char *host, const char *user, const char *passwd,
581+
const char *db, unsigned int port, const char *unix_socket,
582+
unsigned long clientflag);
583+
enum net_async_status mysql_send_query_nonblocking(
584+
MYSQL *mysql, const char *query, unsigned long length);
585+
enum net_async_status mysql_real_query_nonblocking(
586+
MYSQL *mysql, const char *query, unsigned long length);
587+
enum net_async_status
588+
mysql_store_result_nonblocking(MYSQL *mysql, MYSQL_RES **result);
589+
enum net_async_status mysql_next_result_nonblocking(MYSQL *mysql);
590+
enum net_async_status mysql_select_db_nonblocking(MYSQL *mysql,
591+
const char *db,
592+
bool *error);
564593
void mysql_get_character_set_info(MYSQL *mysql,
565594
MY_CHARSET_INFO *charset);
566595
int mysql_session_track_get_first(MYSQL *mysql,
@@ -600,12 +629,15 @@
600629
int mysql_get_option(MYSQL *mysql, enum mysql_option option,
601630
const void *arg);
602631
void mysql_free_result(MYSQL_RES *result);
632+
enum net_async_status mysql_free_result_nonblocking(MYSQL_RES *result);
603633
void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset);
604634
MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result,
605635
MYSQL_ROW_OFFSET offset);
606636
MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result,
607637
MYSQL_FIELD_OFFSET offset);
608638
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
639+
enum net_async_status mysql_fetch_row_nonblocking(MYSQL_RES *res,
640+
MYSQL_ROW *row);
609641
unsigned long * mysql_fetch_lengths(MYSQL_RES *result);
610642
MYSQL_FIELD * mysql_fetch_field(MYSQL_RES *result);
611643
MYSQL_RES * mysql_list_fields(MYSQL *mysql, const char *table,

include/mysql/client_authentication.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License, version 2.0,
@@ -35,5 +35,9 @@ int sha256_password_deinit(void);
3535
int caching_sha2_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
3636
int caching_sha2_password_init(char *, size_t, int, va_list);
3737
int caching_sha2_password_deinit(void);
38-
38+
net_async_status caching_sha2_password_auth_client_nonblocking(
39+
MYSQL_PLUGIN_VIO *vio, MYSQL *mysql, int *res);
40+
net_async_status sha256_password_auth_client_nonblocking(MYSQL_PLUGIN_VIO *vio,
41+
MYSQL *mysql,
42+
int *res);
3943
#endif

include/mysql/client_plugin.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#ifndef MYSQL_CLIENT_PLUGIN_INCLUDED
2-
/* Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
2+
/* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License, version 2.0,
@@ -75,7 +75,7 @@ extern "C" {
7575
#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN 2
7676
#define MYSQL_CLIENT_TRACE_PLUGIN 3
7777

78-
#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION 0x0100
78+
#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION 0x0101
7979
#define MYSQL_CLIENT_TRACE_PLUGIN_INTERFACE_VERSION 0x0100
8080

8181
#define MYSQL_CLIENT_MAX_PLUGINS 4
@@ -113,6 +113,9 @@ struct MYSQL;
113113
struct auth_plugin_t {
114114
MYSQL_CLIENT_PLUGIN_HEADER
115115
int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct MYSQL *mysql);
116+
enum net_async_status (*authenticate_user_nonblocking)(MYSQL_PLUGIN_VIO *vio,
117+
struct MYSQL *mysql,
118+
int *result);
116119
};
117120

118121
// Needed for the mysql_declare_client_plugin() macro. Do not use elsewhere.

include/mysql/client_plugin.h.pp

+15
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,31 @@
1313
} protocol;
1414
int socket;
1515
};
16+
enum net_async_status {
17+
NET_ASYNC_COMPLETE = 0,
18+
NET_ASYNC_NOT_READY,
19+
NET_ASYNC_ERROR,
20+
NET_ASYNC_COMPLETE_WITH_MORE_RESULTS
21+
};
1622
typedef struct MYSQL_PLUGIN_VIO {
1723
int (*read_packet)(struct MYSQL_PLUGIN_VIO *vio, unsigned char **buf);
1824
int (*write_packet)(struct MYSQL_PLUGIN_VIO *vio, const unsigned char *packet,
1925
int packet_len);
2026
void (*info)(struct MYSQL_PLUGIN_VIO *vio,
2127
struct MYSQL_PLUGIN_VIO_INFO *info);
28+
enum net_async_status (*read_packet_nonblocking)(struct MYSQL_PLUGIN_VIO *vio,
29+
unsigned char **buf,
30+
int *result);
31+
enum net_async_status (*write_packet_nonblocking)(
32+
struct MYSQL_PLUGIN_VIO *vio, const unsigned char *pkt, int pkt_len,
33+
int *result);
2234
} MYSQL_PLUGIN_VIO;
2335
struct auth_plugin_t {
2436
int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; const char *license; void *mysql_api; int (*init)(char *, size_t, int, va_list); int (*deinit)(void); int (*options)(const char *option, const void *);
2537
int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct MYSQL *mysql);
38+
enum net_async_status (*authenticate_user_nonblocking)(MYSQL_PLUGIN_VIO *vio,
39+
struct MYSQL *mysql,
40+
int *result);
2641
};
2742
typedef struct auth_plugin_t st_mysql_client_plugin_AUTHENTICATION;
2843
struct st_mysql_client_plugin *mysql_load_plugin(struct MYSQL *mysql,

include/mysql/plugin_auth.h.pp

+12
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,24 @@
130130
} protocol;
131131
int socket;
132132
};
133+
enum net_async_status {
134+
NET_ASYNC_COMPLETE = 0,
135+
NET_ASYNC_NOT_READY,
136+
NET_ASYNC_ERROR,
137+
NET_ASYNC_COMPLETE_WITH_MORE_RESULTS
138+
};
133139
typedef struct MYSQL_PLUGIN_VIO {
134140
int (*read_packet)(struct MYSQL_PLUGIN_VIO *vio, unsigned char **buf);
135141
int (*write_packet)(struct MYSQL_PLUGIN_VIO *vio, const unsigned char *packet,
136142
int packet_len);
137143
void (*info)(struct MYSQL_PLUGIN_VIO *vio,
138144
struct MYSQL_PLUGIN_VIO_INFO *info);
145+
enum net_async_status (*read_packet_nonblocking)(struct MYSQL_PLUGIN_VIO *vio,
146+
unsigned char **buf,
147+
int *result);
148+
enum net_async_status (*write_packet_nonblocking)(
149+
struct MYSQL_PLUGIN_VIO *vio, const unsigned char *pkt, int pkt_len,
150+
int *result);
139151
} MYSQL_PLUGIN_VIO;
140152
struct MYSQL_SERVER_AUTH_INFO {
141153
char *user_name;

include/mysql/plugin_auth_common.h

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#ifndef MYSQL_PLUGIN_AUTH_COMMON_INCLUDED
2-
/* Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
2+
/* Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License, version 2.0,
@@ -126,6 +126,14 @@ struct MYSQL_PLUGIN_VIO_INFO {
126126
#endif
127127
};
128128

129+
/* state of an asynchronous operation */
130+
enum net_async_status {
131+
NET_ASYNC_COMPLETE = 0,
132+
NET_ASYNC_NOT_READY,
133+
NET_ASYNC_ERROR,
134+
NET_ASYNC_COMPLETE_WITH_MORE_RESULTS
135+
};
136+
129137
/**
130138
Provides plugin access to communication channel
131139
*/
@@ -151,6 +159,24 @@ typedef struct MYSQL_PLUGIN_VIO {
151159
void (*info)(struct MYSQL_PLUGIN_VIO *vio,
152160
struct MYSQL_PLUGIN_VIO_INFO *info);
153161

162+
/**
163+
Non blocking version of read_packet. This function points buf to starting
164+
position of incoming packet. When this function returns NET_ASYNC_NOT_READY
165+
plugin should call this function again until all incoming packets are read.
166+
If return code is NET_ASYNC_COMPLETE, plugin can do further processing of
167+
read packets.
168+
*/
169+
enum net_async_status (*read_packet_nonblocking)(struct MYSQL_PLUGIN_VIO *vio,
170+
unsigned char **buf,
171+
int *result);
172+
/**
173+
Non blocking version of write_packet. Sends data available in pkt of length
174+
pkt_len to server in asynchrnous way.
175+
*/
176+
enum net_async_status (*write_packet_nonblocking)(
177+
struct MYSQL_PLUGIN_VIO *vio, const unsigned char *pkt, int pkt_len,
178+
int *result);
179+
154180
} MYSQL_PLUGIN_VIO;
155181

156182
#endif

0 commit comments

Comments
 (0)