diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index fbd4ec2dd3f..987ed3d578f 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -43,7 +43,8 @@ typedef enum _thd_wait_type_e { THD_WAIT_BINLOG= 8, THD_WAIT_GROUP_COMMIT= 9, THD_WAIT_SYNC= 10, - THD_WAIT_LAST= 11 + THD_WAIT_NET= 11, + THD_WAIT_LAST= 12 } thd_wait_type; extern struct thd_wait_service_st { void (*thd_wait_begin_func)(void*, int); diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index 46811825142..9371cb90b95 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -43,7 +43,8 @@ typedef enum _thd_wait_type_e { THD_WAIT_BINLOG= 8, THD_WAIT_GROUP_COMMIT= 9, THD_WAIT_SYNC= 10, - THD_WAIT_LAST= 11 + THD_WAIT_NET= 11, + THD_WAIT_LAST= 12 } thd_wait_type; extern struct thd_wait_service_st { void (*thd_wait_begin_func)(void*, int); diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index 49cf7e5b931..16aa496588b 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -43,7 +43,8 @@ typedef enum _thd_wait_type_e { THD_WAIT_BINLOG= 8, THD_WAIT_GROUP_COMMIT= 9, THD_WAIT_SYNC= 10, - THD_WAIT_LAST= 11 + THD_WAIT_NET= 11, + THD_WAIT_LAST= 12 } thd_wait_type; extern struct thd_wait_service_st { void (*thd_wait_begin_func)(void*, int); diff --git a/include/mysql/service_thd_wait.h b/include/mysql/service_thd_wait.h index 6b47a4ff21e..c35b35df820 100644 --- a/include/mysql/service_thd_wait.h +++ b/include/mysql/service_thd_wait.h @@ -74,7 +74,8 @@ typedef enum _thd_wait_type_e { THD_WAIT_BINLOG= 8, THD_WAIT_GROUP_COMMIT= 9, THD_WAIT_SYNC= 10, - THD_WAIT_LAST= 11 + THD_WAIT_NET= 11, + THD_WAIT_LAST= 12 } thd_wait_type; extern struct thd_wait_service_st { diff --git a/include/violite.h b/include/violite.h index 8cd4fb030c4..eb01f5e446f 100644 --- a/include/violite.h +++ b/include/violite.h @@ -105,7 +105,9 @@ my_bool vio_is_connected(Vio *vio); ssize_t vio_pending(Vio *vio); #endif /* Set timeout for a network operation. */ -int vio_timeout(Vio *vio, uint which, int timeout_sec); +extern int vio_timeout(Vio *vio, uint which, int timeout_sec); +extern void vio_set_wait_callback(void (*before_wait)(void), + void (*after_wait)(void)); /* Connect to a peer. */ my_bool vio_socket_connect(Vio *vio, struct sockaddr *addr, socklen_t len, int timeout); diff --git a/sql/scheduler.cc b/sql/scheduler.cc index 54653557b16..7f250158ccb 100644 --- a/sql/scheduler.cc +++ b/sql/scheduler.cc @@ -27,6 +27,7 @@ #include "mysqld.h" #include "sql_class.h" #include "sql_callback.h" +#include /* End connection, in case when we are using 'no-threads' @@ -61,6 +62,15 @@ static void scheduler_wait_sync_begin(void) { static void scheduler_wait_sync_end(void) { thd_wait_end(NULL); } + +static void scheduler_wait_net_begin(void) { + thd_wait_begin(NULL, THD_WAIT_NET); +} + +static void scheduler_wait_net_end(void) { + thd_wait_end(NULL); +} + }; /**@}*/ @@ -76,6 +86,9 @@ void scheduler_init() { scheduler_wait_lock_end); thr_set_sync_wait_callback(scheduler_wait_sync_begin, scheduler_wait_sync_end); + + vio_set_wait_callback(scheduler_wait_net_begin, + scheduler_wait_net_end); } diff --git a/vio/viosocket.c b/vio/viosocket.c index b13fc2d3a83..cf8ada61237 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -37,6 +37,38 @@ # include #endif +/* Network io wait callbacks for threadpool */ +static void (*before_io_wait)(void)= 0; +static void (*after_io_wait)(void)= 0; + +/* Wait callback macros (both performance schema and threadpool */ +#define START_SOCKET_WAIT(locker, state_ptr, sock, which) \ +do \ +{ \ + MYSQL_START_SOCKET_WAIT(locker, state_ptr, sock, \ + which, 0); \ + if (before_io_wait) \ + before_io_wait(); \ +} while(0) + + +#define END_SOCKET_WAIT(locker) \ +do \ +{ \ + MYSQL_END_SOCKET_WAIT(locker, 0); \ + if (after_io_wait) \ + after_io_wait(); \ +} while(0) + + + +void vio_set_wait_callback(void (*before_wait)(void), + void (*after_wait)(void)) +{ + before_io_wait= before_wait; + after_io_wait= after_wait; +} + int vio_errno(Vio *vio __attribute__((unused))) { /* These transport types are not Winsock based. */ @@ -903,12 +935,12 @@ int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout) */ if (timeout != 0 && vio->async_context && vio->async_context->active) { - MYSQL_START_SOCKET_WAIT(locker, &state, vio->mysql_socket, - PSI_SOCKET_SELECT, 0); + START_SOCKET_WAIT(locker, &state, vio->mysql_socket, + PSI_SOCKET_SELECT); ret= my_io_wait_async(vio->async_context, event, timeout); if (ret == 0) errno= SOCKET_ETIMEDOUT; - MYSQL_END_SOCKET_WAIT(locker, 0); + END_SOCKET_WAIT(locker); DBUG_RETURN(ret); } @@ -933,8 +965,7 @@ int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout) break; } - MYSQL_START_SOCKET_WAIT(locker, &state, vio->mysql_socket, PSI_SOCKET_SELECT, 0); - + START_SOCKET_WAIT(locker, &state, vio->mysql_socket, PSI_SOCKET_SELECT); /* Wait for the I/O event and return early in case of error or timeout. @@ -957,7 +988,7 @@ int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout) break; } - MYSQL_END_SOCKET_WAIT(locker, 0); + END_SOCKET_WAIT(locker); DBUG_RETURN(ret); } @@ -978,12 +1009,12 @@ int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout) */ if (timeout != 0 && vio->async_context && vio->async_context->active) { - MYSQL_START_SOCKET_WAIT(locker, &state, vio->mysql_socket, - PSI_SOCKET_SELECT, 0); + START_SOCKET_WAIT(locker, &state, vio->mysql_socket, + PSI_SOCKET_SELECT); ret= my_io_wait_async(vio->async_context, event, timeout); if (ret == 0) WSASetLastError(SOCKET_ETIMEDOUT); - MYSQL_END_SOCKET_WAIT(locker, 0); + END_SOCKET_WAIT(locker); DBUG_RETURN(ret); } @@ -1014,12 +1045,12 @@ int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout) break; } - MYSQL_START_SOCKET_WAIT(locker, &state, vio->mysql_socket, PSI_SOCKET_SELECT, 0); + START_SOCKET_WAIT(locker, &state, vio->mysql_socket, PSI_SOCKET_SELECT); /* The first argument is ignored on Windows. */ ret= select(0, &readfds, &writefds, &exceptfds, (timeout >= 0) ? &tm : NULL); - MYSQL_END_SOCKET_WAIT(locker, 0); + END_SOCKET_WAIT(locker); /* Set error code to indicate a timeout error. */ if (ret == 0)