50
50
51
51
namespace {
52
52
53
- typedef void (*Xpl_status_variable_get)(THD *, SHOW_VAR *, char *);
54
-
55
- char *xpl_func_ptr (Xpl_status_variable_get callback) {
56
- union {
57
- char *ptr;
58
- Xpl_status_variable_get callback;
59
- } ptr_cast;
60
-
61
- ptr_cast.callback = callback;
62
-
63
- return ptr_cast.ptr ;
53
+ inline char *xpl_func_ptr (mysql_show_var_func callback) {
54
+ return reinterpret_cast <char *>(callback);
64
55
}
65
56
66
57
void exit_hook () { google::protobuf::ShutdownProtobufLibrary (); }
@@ -74,6 +65,180 @@ void check_exit_hook() {
74
65
}
75
66
}
76
67
68
+ xpl::Client_ptr get_client_by_thd (xpl::Server::Server_ptr &server, THD *thd) {
69
+ struct Client_check_handler_thd {
70
+ Client_check_handler_thd (THD *thd) : m_thd(thd) {}
71
+
72
+ bool operator ()(ngs::Client_ptr &client) {
73
+ xpl::Client *xpl_client = (xpl::Client *)client.get ();
74
+
75
+ return xpl_client->is_handler_thd (m_thd);
76
+ }
77
+
78
+ THD *m_thd;
79
+ } client_check_thd (thd);
80
+
81
+ std::vector<ngs::Client_ptr> clients;
82
+ (*server)->server ().get_client_list ().get_all_clients (clients);
83
+
84
+ std::vector<ngs::Client_ptr>::iterator i =
85
+ std::find_if (clients.begin (), clients.end (), client_check_thd);
86
+ if (clients.end () != i) return ngs::dynamic_pointer_cast<xpl::Client>(*i);
87
+
88
+ return xpl::Client_ptr ();
89
+ }
90
+
91
+ template <void (xpl::Client::*method)(SHOW_VAR *)>
92
+ int session_status_variable (THD *thd, SHOW_VAR *var, char *buff) {
93
+ var->type = SHOW_UNDEF;
94
+ var->value = buff;
95
+
96
+ auto server (xpl::Server::get_instance ());
97
+ if (server) {
98
+ MUTEX_LOCK (lock, (*server)->server ().get_client_exit_mutex ());
99
+ xpl::Client_ptr client = get_client_by_thd (server, thd);
100
+
101
+ if (client) ((*client).*method)(var);
102
+ }
103
+ return 0 ;
104
+ }
105
+
106
+ template <typename ReturnType,
107
+ ReturnType (ngs::Ssl_session_options_interface::*method)() const >
108
+ int session_status_variable (THD *thd, SHOW_VAR *var, char *buff) {
109
+ var->type = SHOW_UNDEF;
110
+ var->value = buff;
111
+
112
+ auto server (xpl::Server::get_instance ());
113
+ if (server) {
114
+ MUTEX_LOCK (lock, (*server)->server ().get_client_exit_mutex ());
115
+ xpl::Client_ptr client = get_client_by_thd (server, thd);
116
+
117
+ if (client) {
118
+ ReturnType result =
119
+ (ngs::Ssl_session_options (&client->connection ()).*method)();
120
+ mysqld::xpl_show_var (var).assign (result);
121
+ }
122
+ }
123
+ return 0 ;
124
+ }
125
+
126
+ template <void (xpl::Server::*method)(SHOW_VAR *)>
127
+ int global_status_variable (THD *, SHOW_VAR *var, char *buff) {
128
+ var->type = SHOW_UNDEF;
129
+ var->value = buff;
130
+
131
+ auto server (xpl::Server::get_instance ());
132
+ if (server) {
133
+ xpl::Server *server_ptr = server->container ();
134
+ (server_ptr->*method)(var);
135
+ }
136
+ return 0 ;
137
+ }
138
+
139
+ template <typename ReturnType, ReturnType (xpl::Server::*method)()>
140
+ int global_status_variable_server_with_return (THD *, SHOW_VAR *var,
141
+ char *buff) {
142
+ var->type = SHOW_UNDEF;
143
+ var->value = buff;
144
+
145
+ auto server (xpl::Server::get_instance ());
146
+ if (server) {
147
+ xpl::Server *server_ptr = server->container ();
148
+ ReturnType result = (server_ptr->*method)();
149
+
150
+ mysqld::xpl_show_var (var).assign (result);
151
+ }
152
+ return 0 ;
153
+ }
154
+
155
+ template <typename ReturnType, xpl::Global_status_variables::Variable
156
+ xpl::Global_status_variables::*variable>
157
+ int global_status_variable_server (THD *, SHOW_VAR *var, char *buff) {
158
+ var->type = SHOW_UNDEF;
159
+ var->value = buff;
160
+
161
+ ReturnType result =
162
+ (xpl::Global_status_variables::instance ().*variable).load ();
163
+ mysqld::xpl_show_var (var).assign (result);
164
+ return 0 ;
165
+ }
166
+
167
+ template <typename ReturnType, ngs::Common_status_variables::Variable
168
+ ngs::Common_status_variables::*variable>
169
+ int common_status_variable (THD *thd, SHOW_VAR *var, char *buff) {
170
+ var->type = SHOW_UNDEF;
171
+ var->value = buff;
172
+
173
+ auto server (xpl::Server::get_instance ());
174
+ if (server) {
175
+ MUTEX_LOCK (lock, (*server)->server ().get_client_exit_mutex ());
176
+ xpl::Client_ptr client = get_client_by_thd (server, thd);
177
+
178
+ if (client) {
179
+ // Status can be queried from different thread than client is bound to.
180
+ // User can reset the session by sending SessionReset, to be secure for
181
+ // released session pointer, the code needs to hold current session by
182
+ // shared_ptr.
183
+ auto client_session (client->session_smart_ptr ());
184
+
185
+ if (client_session) {
186
+ auto &common_status = client_session->get_status_variables ();
187
+ ReturnType result = (common_status.*variable).load ();
188
+ mysqld::xpl_show_var (var).assign (result);
189
+ }
190
+ return 0 ;
191
+ }
192
+ }
193
+
194
+ ngs::Common_status_variables &common_status =
195
+ xpl::Global_status_variables::instance ();
196
+ ReturnType result = (common_status.*variable).load ();
197
+ mysqld::xpl_show_var (var).assign (result);
198
+ return 0 ;
199
+ }
200
+
201
+ template <typename ReturnType,
202
+ ReturnType (ngs::Ssl_context_options_interface::*method)()>
203
+ int global_status_variable (THD *, SHOW_VAR *var, char *buff) {
204
+ var->type = SHOW_UNDEF;
205
+ var->value = buff;
206
+
207
+ auto server (xpl::Server::get_instance ());
208
+ if (!server || !(*server)->server ().ssl_context ()) return 0 ;
209
+
210
+ auto &context = (*server)->server ().ssl_context ()->options ();
211
+ auto context_method = method; // workaround on VC compiler internal error
212
+ ReturnType result = (context.*context_method)();
213
+
214
+ mysqld::xpl_show_var (var).assign (result);
215
+ return 0 ;
216
+ }
217
+
218
+ template <typename Copy_type,
219
+ void (ngs::Client_interface::*method)(const Copy_type value)>
220
+ void thd_variable (THD *thd, SYS_VAR *sys_var, void *tgt, const void *save) {
221
+ // Lets copy the data to mysqld storage
222
+ // this is going to allow following to return correct value:
223
+ // SHOW SESSION VARIABLE LIKE '**var-name**';
224
+ *static_cast <Copy_type *>(tgt) = *static_cast <const Copy_type *>(save);
225
+
226
+ // Lets make our own copy of it
227
+ auto server (xpl::Server::get_instance ());
228
+ if (server) {
229
+ MUTEX_LOCK (lock, (*server)->server ().get_client_exit_mutex ());
230
+
231
+ xpl::Client_ptr client = get_client_by_thd (server, thd);
232
+ if (client) ((*client).*method)(*static_cast <Copy_type *>(tgt));
233
+
234
+ // We should store the variables values so that they can be set when new
235
+ // client is connecting. This is done through a registered
236
+ // update_global_timeout_values callback.
237
+ xpl::Plugin_system_variables::update_func<Copy_type>(thd, sys_var, tgt,
238
+ save);
239
+ }
240
+ }
241
+
77
242
} // namespace
78
243
79
244
/*
@@ -219,36 +384,30 @@ static MYSQL_THDVAR_UINT(
219
384
wait_timeout, PLUGIN_VAR_OPCMDARG,
220
385
" Number or seconds that X Plugin must wait for activity on noninteractive "
221
386
" connection" ,
222
- NULL ,
223
- (&xpl::Server::thd_variable<uint32_t ,
224
- &ngs::Client_interface::set_wait_timeout>),
387
+ NULL , (&thd_variable<uint32_t , &ngs::Client_interface::set_wait_timeout>),
225
388
Global_timeouts::Default::k_wait_timeout, 1, 2147483, 0);
226
389
227
390
static MYSQL_SYSVAR_UINT (
228
391
interactive_timeout, xpl::Plugin_system_variables::m_interactive_timeout,
229
392
PLUGIN_VAR_OPCMDARG,
230
- " Default value for \" mysqlx_wait_timeout\" , when the connection is \
231
- interactive. The value defines number or seconds that X Plugin must wait for \
232
- activity on interactive connection" ,
393
+ " Default value for \" mysqlx_wait_timeout\" , when the connection is "
394
+ " interactive. The value defines number or seconds that X Plugin must "
395
+ " wait for activity on interactive connection" ,
233
396
NULL , &xpl::Plugin_system_variables::update_func<uint32_t >,
234
397
Global_timeouts::Default::k_interactive_timeout, 1 , 2147483 , 0 );
235
398
236
399
static MYSQL_THDVAR_UINT (
237
400
read_timeout, PLUGIN_VAR_OPCMDARG,
238
401
" Number or seconds that X Plugin must wait for blocking read operation to "
239
402
" complete" ,
240
- NULL ,
241
- (&xpl::Server::thd_variable<uint32_t ,
242
- &ngs::Client_interface::set_read_timeout>),
403
+ NULL , (&thd_variable<uint32_t , &ngs::Client_interface::set_read_timeout>),
243
404
Global_timeouts::Default::k_read_timeout, 1, 2147483, 0);
244
405
245
406
static MYSQL_THDVAR_UINT (
246
407
write_timeout, PLUGIN_VAR_OPCMDARG,
247
408
" Number or seconds that X Plugin must wait for blocking write operation to "
248
409
" complete" ,
249
- NULL ,
250
- (&xpl::Server::thd_variable<uint32_t ,
251
- &ngs::Client_interface::set_write_timeout>),
410
+ NULL , (&thd_variable<uint32_t , &ngs::Client_interface::set_write_timeout>),
252
411
Global_timeouts::Default::k_write_timeout, 1, 2147483, 0);
253
412
254
413
static MYSQL_SYSVAR_UINT (
@@ -285,49 +444,47 @@ static struct SYS_VAR *xpl_plugin_system_variables[] = {
285
444
MYSQL_SYSVAR (document_id_unique_prefix),
286
445
NULL };
287
446
288
- #define SESSION_STATUS_VARIABLE_ENTRY_LONGLONG (NAME, METHOD ) \
289
- { \
290
- MYSQLX_STATUS_VARIABLE_PREFIX (NAME), \
291
- xpl_func_ptr (xpl::Server::common_status_variable<long long , &METHOD>), \
292
- SHOW_FUNC, SHOW_SCOPE_GLOBAL \
293
- }
294
-
295
- #define GLOBAL_STATUS_VARIABLE_ENTRY_LONGLONG (NAME, METHOD ) \
447
+ #define SESSION_STATUS_VARIABLE_ENTRY_LONGLONG (NAME, METHOD ) \
296
448
{ \
297
449
MYSQLX_STATUS_VARIABLE_PREFIX (NAME), \
298
- xpl_func_ptr ( \
299
- xpl::Server::global_status_variable_server<long long , &METHOD>), \
300
- SHOW_FUNC, SHOW_SCOPE_GLOBAL \
450
+ xpl_func_ptr (common_status_variable<long long , &METHOD>), SHOW_FUNC, \
451
+ SHOW_SCOPE_GLOBAL \
452
+ }
453
+
454
+ #define GLOBAL_STATUS_VARIABLE_ENTRY_LONGLONG (NAME, METHOD ) \
455
+ { \
456
+ MYSQLX_STATUS_VARIABLE_PREFIX (NAME), \
457
+ xpl_func_ptr (global_status_variable_server<long long , &METHOD>), \
458
+ SHOW_FUNC, SHOW_SCOPE_GLOBAL \
301
459
}
302
460
303
- #define GLOBAL_SSL_STATUS_VARIABLE_ENTRY (NAME, TYPE, METHOD ) \
304
- { \
305
- MYSQLX_STATUS_VARIABLE_PREFIX (NAME), \
306
- xpl_func_ptr (xpl::Server:: global_status_variable<TYPE, &METHOD>), \
307
- SHOW_FUNC, SHOW_SCOPE_GLOBAL \
461
+ #define GLOBAL_SSL_STATUS_VARIABLE_ENTRY (NAME, TYPE, METHOD ) \
462
+ { \
463
+ MYSQLX_STATUS_VARIABLE_PREFIX (NAME), \
464
+ xpl_func_ptr (global_status_variable<TYPE, &METHOD>), SHOW_FUNC , \
465
+ SHOW_SCOPE_GLOBAL \
308
466
}
309
467
310
- #define SESSION_SSL_STATUS_VARIABLE_ENTRY (NAME, TYPE, METHOD ) \
311
- { \
312
- MYSQLX_STATUS_VARIABLE_PREFIX (NAME), \
313
- xpl_func_ptr (xpl::Server:: session_status_variable<TYPE, &METHOD>), \
314
- SHOW_FUNC, SHOW_SCOPE_GLOBAL \
468
+ #define SESSION_SSL_STATUS_VARIABLE_ENTRY (NAME, TYPE, METHOD ) \
469
+ { \
470
+ MYSQLX_STATUS_VARIABLE_PREFIX (NAME), \
471
+ xpl_func_ptr (session_status_variable<TYPE, &METHOD>), SHOW_FUNC , \
472
+ SHOW_SCOPE_GLOBAL \
315
473
}
316
474
317
- #define SESSION_SSL_STATUS_VARIABLE_ENTRY_ARRAY (NAME, METHOD ) \
318
- { \
319
- MYSQLX_STATUS_VARIABLE_PREFIX (NAME), \
320
- xpl_func_ptr (xpl::Server:: session_status_variable<&METHOD>), \
321
- SHOW_FUNC, SHOW_SCOPE_GLOBAL \
475
+ #define SESSION_SSL_STATUS_VARIABLE_ENTRY_ARRAY (NAME, METHOD ) \
476
+ { \
477
+ MYSQLX_STATUS_VARIABLE_PREFIX (NAME), \
478
+ xpl_func_ptr (session_status_variable<&METHOD>), SHOW_FUNC , \
479
+ SHOW_SCOPE_GLOBAL \
322
480
}
323
481
324
- #define GLOBAL_CUSTOM_STATUS_VARIABLE_ENTRY (NAME, TYPE, METHOD ) \
325
- { \
326
- MYSQLX_STATUS_VARIABLE_PREFIX (NAME), \
327
- xpl_func_ptr ( \
328
- xpl::Server::global_status_variable_server_with_return<TYPE, \
329
- &METHOD>), \
330
- SHOW_FUNC, SHOW_SCOPE_GLOBAL \
482
+ #define GLOBAL_CUSTOM_STATUS_VARIABLE_ENTRY (NAME, TYPE, METHOD ) \
483
+ { \
484
+ MYSQLX_STATUS_VARIABLE_PREFIX (NAME), \
485
+ xpl_func_ptr ( \
486
+ global_status_variable_server_with_return<TYPE, &METHOD>), \
487
+ SHOW_FUNC, SHOW_SCOPE_GLOBAL \
331
488
}
332
489
333
490
static SHOW_VAR xpl_plugin_status[] = {
0 commit comments