Commit 21b4fda3 authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-3945 - do not hold LOCK_thread_count when freeing THD.

  
The patch decreases the duration of LOCK_thread_count, so it is not hold during THD destructor and freeing memory.
This mutex  now only protects the integrity of threads list, when removing THD from it,  and thread_count variable.
  
The add_to_status() function that updates global status during client disconnect,  is now correctly protected by the LOCK_status mutex.

Benchmark : in a  "non-persistent" sysbench test (oltp_ro with reconnect after each query),  ~ 25% more connects/disconnects were measured
parent 1b2692d0
......@@ -2440,21 +2440,6 @@ void dec_connection_count(THD *thd)
}
/*
Delete the THD object and decrease number of threads
SYNOPSIS
delete_thd()
thd Thread handler
*/
void delete_thd(THD *thd)
{
thread_count--;
delete thd;
}
/*
Unlink thd from global list of available connections and free thd
......@@ -2473,14 +2458,23 @@ void unlink_thd(THD *thd)
thd_cleanup(thd);
dec_connection_count(thd);
mysql_mutex_lock(&LOCK_status);
add_to_status(&global_status_var, &thd->status_var);
mysql_mutex_unlock(&LOCK_status);
mysql_mutex_lock(&LOCK_thread_count);
thread_count--;
thd->unlink();
/*
Used by binlog_reset_master. It would be cleaner to use
DEBUG_SYNC here, but that's not possible because the THD's debug
sync feature has been shut down at this point.
*/
DBUG_EXECUTE_IF("sleep_after_lock_thread_count_before_delete_thd", sleep(5););
delete_thd(thd);
mysql_mutex_unlock(&LOCK_thread_count);
delete thd;
DBUG_VOID_RETURN;
}
......@@ -2589,10 +2583,13 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
/* Mark that current_thd is not valid anymore */
my_pthread_setspecific_ptr(THR_THD, 0);
if (put_in_cache)
{
mysql_mutex_lock(&LOCK_thread_count);
put_in_cache= cache_thread();
mysql_mutex_unlock(&LOCK_thread_count);
if (put_in_cache)
DBUG_RETURN(0); // Thread is reused
mysql_mutex_unlock(&LOCK_thread_count);
if (put_in_cache)
DBUG_RETURN(0); // Thread is reused
}
/* It's safe to broadcast outside a lock (COND... is not deleted here) */
DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
......
......@@ -35,7 +35,6 @@
static bool no_threads_end(THD *thd, bool put_in_cache)
{
unlink_thd(thd);
mysql_mutex_unlock(&LOCK_thread_count);
return 1; // Abort handle_one_connection
}
......
......@@ -1444,7 +1444,6 @@ THD::~THD()
mysql_mutex_lock(&LOCK_thd_data);
mysys_var=0; // Safety (shouldn't be needed)
mysql_mutex_unlock(&LOCK_thd_data);
add_to_status(&global_status_var, &status_var);
/* Close connection */
#ifndef EMBEDDED_LIBRARY
......
......@@ -173,7 +173,6 @@ void threadpool_remove_connection(THD *thd)
close_connection(thd, 0);
unlink_thd(thd);
mysql_mutex_unlock(&LOCK_thread_count);
mysql_cond_broadcast(&COND_thread_count);
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment