diff options
Diffstat (limited to 'sql/sql_connect.cc')
-rw-r--r-- | sql/sql_connect.cc | 108 |
1 files changed, 79 insertions, 29 deletions
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 6bf43d3df5e..0add71b7b11 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -43,6 +43,7 @@ #include "wsrep_mysqld.h" #endif /* WITH_WSREP */ #include "proxy_protocol.h" +#include <ssl_compat.h> HASH global_user_stats, global_client_stats, global_table_stats; HASH global_index_stats; @@ -1112,7 +1113,6 @@ bool setup_connection_thread_globals(THD *thd) close_connection(thd, ER_OUT_OF_RESOURCES); statistic_increment(aborted_connects,&LOCK_status); statistic_increment(connection_errors_internal, &LOCK_status); - thd->scheduler->end_thread(thd, 0); return 1; // Error } return 0; @@ -1313,7 +1313,16 @@ pthread_handler_t handle_one_connection(void *arg) mysql_thread_set_psi_id(connect->thread_id); - do_handle_one_connection(connect); + if (init_new_connection_handler_thread()) + connect->close_with_error(0, 0, ER_OUT_OF_RESOURCES); + else + do_handle_one_connection(connect, true); + + DBUG_PRINT("info", ("killing thread")); +#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) + ERR_remove_state(0); +#endif + my_thread_end(); return 0; } @@ -1347,16 +1356,13 @@ bool thd_is_connection_alive(THD *thd) } -void do_handle_one_connection(CONNECT *connect) +void do_handle_one_connection(CONNECT *connect, bool put_in_cache) { ulonglong thr_create_utime= microsecond_interval_timer(); THD *thd; - if (connect->scheduler->init_new_connection_thread() || - !(thd= connect->create_thd(NULL))) + if (!(thd= connect->create_thd(NULL))) { - scheduler_functions *scheduler= connect->scheduler; - connect->close_with_error(0, 0, ER_OUT_OF_RESOURCES); - scheduler->end_thread(0, 0); + connect->close_and_delete(); return; } @@ -1392,7 +1398,11 @@ void do_handle_one_connection(CONNECT *connect) */ thd->thread_stack= (char*) &thd; if (setup_connection_thread_globals(thd)) + { + unlink_thd(thd); + delete thd; return; + } for (;;) { @@ -1420,16 +1430,40 @@ end_thread: if (thd->userstat_running) update_global_user_stats(thd, create_user, time(NULL)); - if (thd->scheduler->end_thread(thd, 1)) - return; // Probably no-threads + unlink_thd(thd); + if (IF_WSREP(thd->wsrep_applier, false) || !put_in_cache || + !(connect= cache_thread(thd))) + break; + + if (!(connect->create_thd(thd))) + { + /* Out of resources. Free thread to get more resources */ + connect->close_and_delete(); + break; + } + delete connect; + + /* + We have to call store_globals to update mysys_var->id and lock_info + with the new thread_id + */ + thd->store_globals(); /* - If end_thread() returns, this thread has been schedule to - handle the next connection. + Create new instrumentation for the new THD job, + and attach it to this running pthread. */ - thd= current_thd; - thd->thread_stack= (char*) &thd; + PSI_CALL_set_thread(PSI_CALL_new_thread(key_thread_one_connection, + thd, thd->thread_id)); + + /* reset abort flag for the thread */ + thd->mysys_var->abort= 0; + thd->thr_create_utime= microsecond_interval_timer(); + thd->start_utime= thd->thr_create_utime; + + server_threads.insert(thd); } + delete thd; } #endif /* EMBEDDED_LIBRARY */ @@ -1446,10 +1480,16 @@ void CONNECT::close_and_delete() { DBUG_ENTER("close_and_delete"); - if (vio) - vio_close(vio); - if (thread_count_incremented) - dec_connection_count(scheduler); +#if _WIN32 + if (vio_type == VIO_TYPE_NAMEDPIPE) + CloseHandle(pipe); + else +#endif + if (vio_type != VIO_CLOSED) + mysql_socket_close(sock); + vio_type= VIO_CLOSED; + + --*scheduler->connection_count; statistic_increment(connection_errors_internal, &LOCK_status); statistic_increment(aborted_connects,&LOCK_status); @@ -1478,18 +1518,12 @@ void CONNECT::close_with_error(uint sql_errno, } -CONNECT::~CONNECT() -{ - if (vio) - vio_delete(vio); -} - - /* Reuse or create a THD based on a CONNECT object */ THD *CONNECT::create_thd(THD *thd) { bool res, thd_reused= thd != 0; + Vio *vio; DBUG_ENTER("create_thd"); DBUG_EXECUTE_IF("simulate_failed_connection_2", DBUG_RETURN(0); ); @@ -1508,9 +1542,23 @@ THD *CONNECT::create_thd(THD *thd) else if (!(thd= new THD(thread_id))) DBUG_RETURN(0); +#if _WIN32 + if (vio_type == VIO_TYPE_NAMEDPIPE) + vio= vio_new_win32pipe(pipe); + else +#endif + vio= mysql_socket_vio_new(sock, vio_type, vio_type == VIO_TYPE_SOCKET ? + VIO_LOCALHOST : 0); + if (!vio) + { + if (!thd_reused) + delete thd; + DBUG_RETURN(0); + } + set_current_thd(thd); res= my_net_init(&thd->net, vio, thd, MYF(MY_THREAD_SPECIFIC)); - vio= 0; // Vio now handled by thd + vio_type= VIO_CLOSED; // Vio now handled by thd if (unlikely(res || thd->is_error())) { @@ -1522,9 +1570,11 @@ THD *CONNECT::create_thd(THD *thd) init_net_server_extension(thd); - thd->security_ctx->host= host; - thd->extra_port= extra_port; + thd->security_ctx->host= thd->net.vio->type == VIO_TYPE_NAMEDPIPE || + thd->net.vio->type == VIO_TYPE_SOCKET ? + my_localhost : 0; + thd->scheduler= scheduler; - thd->real_id= real_id; + thd->real_id= pthread_self(); /* Duplicates THD::store_globals() setting. */ DBUG_RETURN(thd); } |