diff options
-rw-r--r-- | sql/mysqld.cc | 45 | ||||
-rw-r--r-- | sql/mysqld.h | 2 | ||||
-rw-r--r-- | sql/sql_class.cc | 34 | ||||
-rw-r--r-- | sql/sql_class.h | 3 | ||||
-rw-r--r-- | sql/sql_connect.cc | 6 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 |
6 files changed, 59 insertions, 33 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5fb63fb61ba..68795ca377b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1134,7 +1134,7 @@ static void close_connections(void) tmp->thread_id, (tmp->main_security_ctx.user ? tmp->main_security_ctx.user : "")); - close_connection(tmp,0,0); + close_connection(tmp); } #endif DBUG_PRINT("quit",("Unlocking LOCK_thread_count")); @@ -1960,39 +1960,28 @@ static void network_init(void) /** Close a connection. - @param thd Thread handle - @param errcode Error code to print to console - @param lock 1 if we have have to lock LOCK_thread_count + @param thd Thread handle. + @param sql_errno The error code to send before disconnect. @note For the connection that is doing shutdown, this is called twice */ -void close_connection(THD *thd, uint errcode, bool lock) +void close_connection(THD *thd, uint sql_errno) { - st_vio *vio; DBUG_ENTER("close_connection"); - DBUG_PRINT("enter",("fd: %s error: '%s'", - thd->net.vio ? vio_description(thd->net.vio) : - "(not connected)", - errcode ? ER_DEFAULT(errcode) : "")); - if (lock) - mysql_mutex_lock(&LOCK_thread_count); - thd->killed= THD::KILL_CONNECTION; - if ((vio= thd->net.vio) != 0) - { - if (errcode) - net_send_error(thd, errcode, - ER_DEFAULT(errcode), NULL); /* purecov: inspected */ - vio_close(vio); /* vio is freed in delete thd */ - } - if (lock) - mysql_mutex_unlock(&LOCK_thread_count); - MYSQL_CONNECTION_DONE((int) errcode, thd->thread_id); + + if (sql_errno) + net_send_error(thd, sql_errno, ER_DEFAULT(sql_errno), NULL); + + thd->disconnect(); + + MYSQL_CONNECTION_DONE((int) sql_errno, thd->thread_id); + if (MYSQL_CONNECTION_DONE_ENABLED()) { sleep(0); /* Workaround to avoid tailcall optimisation */ } - MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, errcode); + MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, sql_errno); DBUG_VOID_RETURN; } #endif /* EMBEDDED_LIBRARY */ @@ -4951,8 +4940,8 @@ void create_thread_to_handle_connection(THD *thd) my_snprintf(error_message_buff, sizeof(error_message_buff), ER_THD(thd, ER_CANT_CREATE_THREAD), error); net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff, NULL); + close_connection(thd); mysql_mutex_lock(&LOCK_thread_count); - close_connection(thd,0,0); delete thd; mysql_mutex_unlock(&LOCK_thread_count); return; @@ -4993,7 +4982,7 @@ static void create_new_thread(THD *thd) mysql_mutex_unlock(&LOCK_connection_count); DBUG_PRINT("error",("Too many connections")); - close_connection(thd, ER_CON_COUNT_ERROR, 1); + close_connection(thd, ER_CON_COUNT_ERROR); delete thd; DBUG_VOID_RETURN; } @@ -5374,7 +5363,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg) if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) || my_net_init(&thd->net, thd->net.vio)) { - close_connection(thd, ER_OUT_OF_RESOURCES, 1); + close_connection(thd, ER_OUT_OF_RESOURCES); delete thd; continue; } @@ -5569,7 +5558,7 @@ pthread_handler_t handle_connections_shared_memory(void *arg) event_conn_closed)) || my_net_init(&thd->net, thd->net.vio)) { - close_connection(thd, ER_OUT_OF_RESOURCES, 1); + close_connection(thd, ER_OUT_OF_RESOURCES); errmsg= 0; goto errorconn; } diff --git a/sql/mysqld.h b/sql/mysqld.h index 5d8885ac277..9218503d477 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -64,7 +64,7 @@ typedef Bitmap<((MAX_INDEXES+7)/8*8)> key_map; /* Used for finding keys */ some places */ /* Function prototypes */ void kill_mysql(void); -void close_connection(THD *thd, uint errcode, bool lock); +void close_connection(THD *thd, uint sql_errno= 0); void handle_connection_in_main_thread(THD *thd); void create_thread_to_handle_connection(THD *thd); void unlink_thd(THD *thd); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2df7a2c8572..c4aa4ba7efb 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1283,6 +1283,40 @@ void THD::awake(THD::killed_state state_to_set) DBUG_VOID_RETURN; } + +/** + Close the Vio associated this session. + + @remark LOCK_thd_data is taken due to the fact that + the Vio might be disassociated concurrently. +*/ + +void THD::disconnect() +{ + Vio *vio= NULL; + + mysql_mutex_lock(&LOCK_thd_data); + + killed= THD::KILL_CONNECTION; + +#ifdef SIGNAL_WITH_VIO_CLOSE + /* + Since a active vio might might have not been set yet, in + any case save a reference to avoid closing a inexistent + one or closing the vio twice if there is a active one. + */ + vio= active_vio; + close_active_vio(); +#endif + + /* Disconnect even if a active vio is not associated. */ + if (net.vio != vio) + vio_close(net.vio); + + mysql_mutex_unlock(&LOCK_thd_data); +} + + /* Remember the location of thread info, the structure needed for sql_alloc() and the structure for the net buffer diff --git a/sql/sql_class.h b/sql/sql_class.h index db20fd73b42..b8e7b685108 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2209,6 +2209,9 @@ public: #endif void awake(THD::killed_state state_to_set); + /** Disconnect the associated communication endpoint. */ + void disconnect(); + #ifndef MYSQL_CLIENT enum enum_binlog_query_type { /* The query can be logged in row format or in statement format. */ diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 9799ae14b2f..ad6fe492056 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -518,7 +518,7 @@ bool setup_connection_thread_globals(THD *thd) { if (thd->store_globals()) { - close_connection(thd, ER_OUT_OF_RESOURCES, 1); + close_connection(thd, ER_OUT_OF_RESOURCES); statistic_increment(aborted_connects,&LOCK_status); MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0)); return 1; // Error @@ -693,7 +693,7 @@ void do_handle_one_connection(THD *thd_arg) if (MYSQL_CALLBACK_ELSE(thread_scheduler, init_new_connection_thread, (), 0)) { - close_connection(thd, ER_OUT_OF_RESOURCES, 1); + close_connection(thd, ER_OUT_OF_RESOURCES); statistic_increment(aborted_connects,&LOCK_status); MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0)); return; @@ -751,7 +751,7 @@ void do_handle_one_connection(THD *thd_arg) end_connection(thd); end_thread: - close_connection(thd, 0, 1); + close_connection(thd); if (MYSQL_CALLBACK_ELSE(thread_scheduler, end_thread, (thd, 1), 0)) return; // Probably no-threads diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index dff6510817f..c4782f37417 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -600,7 +600,7 @@ void do_handle_bootstrap(THD *thd) if (my_thread_init() || thd->store_globals()) { #ifndef EMBEDDED_LIBRARY - close_connection(thd, ER_OUT_OF_RESOURCES, 1); + close_connection(thd, ER_OUT_OF_RESOURCES); #endif thd->fatal_error(); goto end; |