diff options
-rw-r--r-- | include/violite.h | 2 | ||||
-rw-r--r-- | mysql-test/suite/perfschema/r/all_instances.result | 1 | ||||
-rw-r--r-- | mysys/my_rnd.c | 15 | ||||
-rw-r--r-- | sql/event_scheduler.cc | 26 | ||||
-rw-r--r-- | sql/mysqld.cc | 208 | ||||
-rw-r--r-- | sql/mysqld.h | 45 | ||||
-rw-r--r-- | sql/sql_class.cc | 32 | ||||
-rw-r--r-- | sql/sql_insert.cc | 8 | ||||
-rw-r--r-- | sql/sql_parse.cc | 5 | ||||
-rw-r--r-- | vio/vio.c | 8 |
10 files changed, 176 insertions, 174 deletions
diff --git a/include/violite.h b/include/violite.h index 14c99e8d8fe..3a284a9e00d 100644 --- a/include/violite.h +++ b/include/violite.h @@ -216,7 +216,7 @@ struct st_vio struct sockaddr_storage remote; /* Remote internet address */ int addrLen; /* Length of remote address */ enum enum_vio_type type; /* Type of connection */ - char desc[30]; /* String description */ + const char *desc; /* String description */ char *read_buffer; /* buffer for vio_read_buff */ char *read_pos; /* start of unfetched data in the read buffer */ diff --git a/mysql-test/suite/perfschema/r/all_instances.result b/mysql-test/suite/perfschema/r/all_instances.result index d59f17847e2..616ff646c5c 100644 --- a/mysql-test/suite/perfschema/r/all_instances.result +++ b/mysql-test/suite/perfschema/r/all_instances.result @@ -64,6 +64,7 @@ wait/synch/mutex/sql/LOCK_server_started wait/synch/mutex/sql/LOCK_slave_list wait/synch/mutex/sql/LOCK_stats wait/synch/mutex/sql/LOCK_status +wait/synch/mutex/sql/LOCK_thread_cache wait/synch/mutex/sql/LOCK_thread_count wait/synch/mutex/sql/LOCK_user_conn wait/synch/mutex/sql/LOCK_user_locks diff --git a/mysys/my_rnd.c b/mysys/my_rnd.c index 178bcd9c539..d043c8529ad 100644 --- a/mysys/my_rnd.c +++ b/mysys/my_rnd.c @@ -45,11 +45,20 @@ void my_rnd_init(struct my_rnd_struct *rand_st, ulong seed1, ulong seed2) RETURN VALUE generated pseudo random number + + NOTE: + This is codes so that it can be called by two threads at the same time + with minimum impact. + (As the number is supposed to be random, it doesn't matter much if + rand->seed1 or rand->seed2 are updated with slightly wrong numbers or + if two threads gets the same number. */ double my_rnd(struct my_rnd_struct *rand_st) { - rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value; - rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value; - return (((double) rand_st->seed1)/rand_st->max_value_dbl); + unsigned long seed1; + seed1= (rand_st->seed1*3+rand_st->seed2) % rand_st->max_value; + rand_st->seed2=(seed1+rand_st->seed2+33) % rand_st->max_value; + rand_st->seed1= seed1; + return (((double) seed1)/rand_st->max_value_dbl); } diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 8c3e57778ab..4a4ae5a732f 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -132,11 +132,11 @@ post_init_event_thread(THD *thd) return TRUE; } + thread_safe_increment32(&thread_count, &thread_count_lock); mysql_mutex_lock(&LOCK_thread_count); threads.append(thd); - thread_count++; - inc_thread_running(); mysql_mutex_unlock(&LOCK_thread_count); + inc_thread_running(); return FALSE; } @@ -154,12 +154,8 @@ deinit_event_thread(THD *thd) { thd->proc_info= "Clearing"; DBUG_PRINT("exit", ("Event thread finishing")); - mysql_mutex_lock(&LOCK_thread_count); - thread_count--; - dec_thread_running(); - delete thd; - mysql_cond_broadcast(&COND_thread_count); - mysql_mutex_unlock(&LOCK_thread_count); + + delete_running_thd(thd); } @@ -436,12 +432,7 @@ Event_scheduler::start() ret= TRUE; new_thd->proc_info= "Clearing"; - mysql_mutex_lock(&LOCK_thread_count); - thread_count--; - dec_thread_running(); - delete new_thd; - mysql_cond_broadcast(&COND_thread_count); - mysql_mutex_unlock(&LOCK_thread_count); + delete_running_thd(new_thd); } end: UNLOCK_DATA(); @@ -570,12 +561,7 @@ error: if (new_thd) { new_thd->proc_info= "Clearing"; - mysql_mutex_lock(&LOCK_thread_count); - thread_count--; - dec_thread_running(); - delete new_thd; - mysql_cond_broadcast(&COND_thread_count); - mysql_mutex_unlock(&LOCK_thread_count); + delete_running_thd(new_thd); } delete event_name; DBUG_RETURN(TRUE); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c662b3279ef..cebef02e349 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -465,7 +465,7 @@ ulong delay_key_write_options; uint protocol_version; uint lower_case_table_names; ulong tc_heuristic_recover= 0; -uint volatile thread_count; +int32 thread_count; int32 thread_running; ulong thread_created; ulong back_log, connect_timeout, concurrency, server_id; @@ -489,6 +489,7 @@ ulong executed_events=0; query_id_t global_query_id; my_atomic_rwlock_t global_query_id_lock; my_atomic_rwlock_t thread_running_lock; +my_atomic_rwlock_t thread_count_lock; my_atomic_rwlock_t statistics_lock; ulong aborted_threads, aborted_connects; ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size; @@ -663,7 +664,7 @@ SHOW_COMP_OPTION have_openssl; pthread_key(MEM_ROOT**,THR_MALLOC); pthread_key(THD*, THR_THD); -mysql_mutex_t LOCK_thread_count; +mysql_mutex_t LOCK_thread_count, LOCK_thread_cache; mysql_mutex_t LOCK_status, LOCK_error_log, LOCK_short_uuid_generator, LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, @@ -761,7 +762,8 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list, key_relay_log_info_log_space_lock, key_relay_log_info_run_lock, key_relay_log_info_sleep_lock, key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data, - key_LOCK_error_messages, key_LOG_INFO_lock, key_LOCK_thread_count, + key_LOCK_error_messages, key_LOG_INFO_lock, + key_LOCK_thread_count, key_LOCK_thread_cache, key_PARTITION_LOCK_auto_inc; PSI_mutex_key key_RELAYLOG_LOCK_index; @@ -832,6 +834,7 @@ static PSI_mutex_info all_server_mutexes[]= { &key_LOCK_commit_ordered, "LOCK_commit_ordered", PSI_FLAG_GLOBAL}, { &key_LOG_INFO_lock, "LOG_INFO::lock", 0}, { &key_LOCK_thread_count, "LOCK_thread_count", PSI_FLAG_GLOBAL}, + { &key_LOCK_thread_cache, "LOCK_thread_cache", PSI_FLAG_GLOBAL}, { &key_PARTITION_LOCK_auto_inc, "HA_DATA_PARTITION::LOCK_auto_inc", 0} }; @@ -1472,7 +1475,7 @@ static void close_connections(void) end_slave(); /* Give threads time to die. */ - for (int i= 0; thread_count && i < 100; i++) + for (int i= 0; *(volatile int32*) &thread_count && i < 100; i++) my_sleep(20000); /* @@ -1886,6 +1889,7 @@ void clean_up(bool print_message) sys_var_end(); my_atomic_rwlock_destroy(&global_query_id_lock); my_atomic_rwlock_destroy(&thread_running_lock); + my_atomic_rwlock_destroy(&thread_count_lock); my_atomic_rwlock_destroy(&statistics_lock); mysql_mutex_lock(&LOCK_thread_count); DBUG_PRINT("quit", ("got thread count lock")); @@ -1929,6 +1933,7 @@ static void clean_up_mutexes() DBUG_ENTER("clean_up_mutexes"); mysql_rwlock_destroy(&LOCK_grant); mysql_mutex_destroy(&LOCK_thread_count); + mysql_mutex_destroy(&LOCK_thread_cache); mysql_mutex_destroy(&LOCK_status); mysql_mutex_destroy(&LOCK_delayed_insert); mysql_mutex_destroy(&LOCK_delayed_status); @@ -2456,6 +2461,28 @@ void dec_connection_count(THD *thd) /* + Delete THD and decrement thread counters, including thread_running +*/ + +void delete_running_thd(THD *thd) +{ + mysql_mutex_lock(&LOCK_thread_count); + thd->unlink(); + mysql_mutex_unlock(&LOCK_thread_count); + + delete thd; + dec_thread_running(); + thread_safe_decrement32(&thread_count, &thread_count_lock); + if (!thread_count) + { + mysql_mutex_lock(&LOCK_thread_count); + mysql_cond_broadcast(&COND_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); + } +} + + +/* Unlink thd from global list of available connections and free thd SYNOPSIS @@ -2479,7 +2506,6 @@ void unlink_thd(THD *thd) 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 @@ -2487,13 +2513,11 @@ void unlink_thd(THD *thd) sync feature has been shut down at this point. */ DBUG_EXECUTE_IF("sleep_after_lock_thread_count_before_delete_thd", sleep(5);); - /* - We must delete thd inside the lock to ensure that we don't start cleanup - before THD is deleted - */ - delete thd; mysql_mutex_unlock(&LOCK_thread_count); + delete thd; + thread_safe_decrement32(&thread_count, &thread_count_lock); + DBUG_VOID_RETURN; } @@ -2505,7 +2529,7 @@ void unlink_thd(THD *thd) cache_thread() NOTES - LOCK_thread_count has to be locked + LOCK_thread_cache has to be locked RETURN 0 Thread was not put in cache @@ -2516,7 +2540,9 @@ void unlink_thd(THD *thd) static bool cache_thread() { - mysql_mutex_assert_owner(&LOCK_thread_count); + DBUG_ENTER("cache_thread"); + + mysql_mutex_assert_owner(&LOCK_thread_cache); if (cached_thread_count < thread_cache_size && ! abort_loop && !kill_cached_threads) { @@ -2534,7 +2560,7 @@ static bool cache_thread() #endif while (!abort_loop && ! wake_thread && ! kill_cached_threads) - mysql_cond_wait(&COND_thread_cache, &LOCK_thread_count); + mysql_cond_wait(&COND_thread_cache, &LOCK_thread_cache); cached_thread_count--; if (kill_cached_threads) mysql_cond_signal(&COND_flush_thread_cache); @@ -2569,10 +2595,10 @@ static bool cache_thread() thd->thr_create_utime= microsecond_interval_timer(); thd->start_utime= thd->thr_create_utime; threads.append(thd); - return(1); + DBUG_RETURN(1); } } - return(0); + DBUG_RETURN(0); } @@ -2603,17 +2629,26 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache) set_current_thd(0); if (put_in_cache) { - mysql_mutex_lock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_thread_cache); put_in_cache= cache_thread(); - mysql_mutex_unlock(&LOCK_thread_count); + mysql_mutex_unlock(&LOCK_thread_cache); 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")); - mysql_cond_broadcast(&COND_thread_count); - + /* + It's safe to check for thread_count outside of the mutex + as we are only interested to see if it was counted to 0 by the + above unlink_thd() call. We should only signal COND_thread_count if + thread_count is likely to be 0. (false positives are ok) + */ + if (!thread_count) + { + mysql_mutex_lock(&LOCK_thread_count); + DBUG_PRINT("signal", ("Broadcasting COND_thread_count")); + mysql_cond_broadcast(&COND_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); + } DBUG_LEAVE; // Must match DBUG_ENTER() my_thread_end(); @@ -2624,15 +2659,17 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache) void flush_thread_cache() { - mysql_mutex_lock(&LOCK_thread_count); + DBUG_ENTER("flush_thread_cache"); + mysql_mutex_lock(&LOCK_thread_cache); kill_cached_threads++; while (cached_thread_count) { mysql_cond_broadcast(&COND_thread_cache); - mysql_cond_wait(&COND_flush_thread_cache, &LOCK_thread_count); + mysql_cond_wait(&COND_flush_thread_cache, &LOCK_thread_cache); } kill_cached_threads--; - mysql_mutex_unlock(&LOCK_thread_count); + mysql_mutex_unlock(&LOCK_thread_cache); + DBUG_VOID_RETURN; } @@ -3973,6 +4010,7 @@ static int init_thread_environment() { DBUG_ENTER("init_thread_environment"); mysql_mutex_init(key_LOCK_thread_count, &LOCK_thread_count, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_LOCK_thread_cache, &LOCK_thread_cache, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_status, &LOCK_status, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_delayed_insert, &LOCK_delayed_insert, MY_MUTEX_INIT_FAST); @@ -5363,7 +5401,7 @@ static void bootstrap(MYSQL_FILE *file) thd->max_client_packet_length= thd->net.max_packet; thd->security_ctx->master_access= ~(ulong)0; thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; - thread_count++; + thread_count++; // Safe as only one thread running in_bootstrap= TRUE; bootstrap_file=file; @@ -5444,54 +5482,69 @@ void handle_connection_in_main_thread(THD *thd) void create_thread_to_handle_connection(THD *thd) { + DBUG_ENTER("create_thread_to_handle_connection"); + mysql_mutex_assert_owner(&LOCK_thread_count); + + /* Check if we can get thread from the cache */ if (cached_thread_count > wake_thread) { - /* Get thread from cache */ - thread_cache.push_back(thd); - wake_thread++; - mysql_cond_signal(&COND_thread_cache); - } - else - { - char error_message_buff[MYSQL_ERRMSG_SIZE]; - /* Create new thread to handle connection */ - int error; - thread_created++; - threads.append(thd); - DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id)); - thd->prior_thr_create_utime= microsecond_interval_timer(); - if ((error= mysql_thread_create(key_thread_one_connection, - &thd->real_id, &connection_attrib, - handle_one_connection, - (void*) thd))) + mysql_mutex_lock(&LOCK_thread_cache); + /* Recheck condition when we have the lock */ + if (cached_thread_count > wake_thread) { - /* purecov: begin inspected */ - DBUG_PRINT("error", - ("Can't create thread to handle request (error %d)", - error)); - thread_count--; - thd->killed= KILL_CONNECTION; // Safety mysql_mutex_unlock(&LOCK_thread_count); + /* Get thread from cache */ + thread_cache.push_back(thd); + wake_thread++; + mysql_cond_signal(&COND_thread_cache); + mysql_mutex_unlock(&LOCK_thread_cache); + DBUG_PRINT("info",("Thread created")); + DBUG_VOID_RETURN; + } + mysql_mutex_unlock(&LOCK_thread_cache); + } + + char error_message_buff[MYSQL_ERRMSG_SIZE]; + /* Create new thread to handle connection */ + int error; + thread_created++; + threads.append(thd); + DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id)); + thd->prior_thr_create_utime= microsecond_interval_timer(); + if ((error= mysql_thread_create(key_thread_one_connection, + &thd->real_id, &connection_attrib, + handle_one_connection, + (void*) thd))) + { + /* purecov: begin inspected */ + DBUG_PRINT("error", + ("Can't create thread to handle request (error %d)", + error)); + thd->killed= KILL_CONNECTION; // Safety + mysql_mutex_unlock(&LOCK_thread_count); - mysql_mutex_lock(&LOCK_connection_count); - (*thd->scheduler->connection_count)--; - mysql_mutex_unlock(&LOCK_connection_count); + mysql_mutex_lock(&LOCK_connection_count); + (*thd->scheduler->connection_count)--; + mysql_mutex_unlock(&LOCK_connection_count); - statistic_increment(aborted_connects,&LOCK_status); - /* Can't use my_error() since store_globals has not been called. */ - 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, ER_OUT_OF_RESOURCES); - mysql_mutex_lock(&LOCK_thread_count); - delete thd; - mysql_mutex_unlock(&LOCK_thread_count); - return; - /* purecov: end */ - } + statistic_increment(aborted_connects,&LOCK_status); + /* Can't use my_error() since store_globals has not been called. */ + 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, ER_OUT_OF_RESOURCES); + + mysql_mutex_lock(&LOCK_thread_count); + thd->unlink(); + mysql_mutex_unlock(&LOCK_thread_count); + delete thd; + thread_safe_decrement32(&thread_count, &thread_count_lock); + return; + /* purecov: end */ } mysql_mutex_unlock(&LOCK_thread_count); DBUG_PRINT("info",("Thread created")); + DBUG_VOID_RETURN; } @@ -5538,10 +5591,10 @@ static void create_new_thread(THD *thd) mysql_mutex_unlock(&LOCK_connection_count); - /* Start a new thread to handle connection. */ + thread_safe_increment32(&thread_count, &thread_count_lock); + /* Start a new thread to handle connection. */ mysql_mutex_lock(&LOCK_thread_count); - /* The initialization of thread_id is done in create_embedded_thd() for the embedded library. @@ -5549,8 +5602,6 @@ static void create_new_thread(THD *thd) */ thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; - thread_count++; - MYSQL_CALLBACK(thd->scheduler, add_connection, (thd)); DBUG_VOID_RETURN; @@ -5758,20 +5809,6 @@ void handle_connections_sockets() } #endif /* HAVE_LIBWRAP */ - { - size_socket dummyLen; - struct sockaddr_storage dummy; - dummyLen = sizeof(dummy); - if ( getsockname(new_sock,(struct sockaddr *)&dummy, - (SOCKET_SIZE_TYPE *)&dummyLen) < 0 ) - { - sql_perror("Error on new connection socket"); - (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); - (void) closesocket(new_sock); - continue; - } - } - /* ** Don't allow too many connections */ @@ -7402,6 +7439,7 @@ static int mysql_init_variables(void) global_query_id= thread_id= 1L; my_atomic_rwlock_init(&global_query_id_lock); my_atomic_rwlock_init(&thread_running_lock); + my_atomic_rwlock_init(&thread_count_lock); my_atomic_rwlock_init(&statistics_lock); strmov(server_version, MYSQL_SERVER_VERSION); threads.empty(); @@ -8461,12 +8499,8 @@ void refresh_status(THD *thd) /* Set max_used_connections to the number of currently open - connections. Lock LOCK_thread_count out of LOCK_status to avoid - deadlocks. Status reset becomes not atomic, but status data is - not exact anyway. + connections. This is not perfect, but status data is not exact anyway. */ - mysql_mutex_lock(&LOCK_thread_count); max_used_connections= thread_count-delayed_insert_threads; - mysql_mutex_unlock(&LOCK_thread_count); } diff --git a/sql/mysqld.h b/sql/mysqld.h index 6bde25f08fb..1be59bfe53a 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -56,6 +56,7 @@ void kill_mysql(void); 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 delete_running_thd(THD *thd); void unlink_thd(THD *thd); bool one_thread_per_connection_end(THD *thd, bool put_in_cache); void flush_thread_cache(); @@ -89,7 +90,6 @@ extern bool opt_ignore_builtin_innodb; extern my_bool opt_character_set_client_handshake; extern bool volatile abort_loop; extern bool in_bootstrap; -extern uint volatile thread_count; extern uint connection_count; extern my_bool opt_safe_user_create; extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap; @@ -352,7 +352,8 @@ extern mysql_rwlock_t LOCK_system_variables_hash; extern mysql_cond_t COND_thread_count; extern mysql_cond_t COND_manager; extern int32 thread_running; -extern my_atomic_rwlock_t thread_running_lock; +extern int32 thread_count; +extern my_atomic_rwlock_t thread_running_lock, thread_count_lock; extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher, *opt_ssl_key; @@ -479,42 +480,30 @@ inline void table_case_convert(char * name, uint length) name, length, name, length); } -inline ulong sql_rnd_with_mutex() +inline void thread_safe_increment32(int32 *value, my_atomic_rwlock_t *lock) { - mysql_mutex_lock(&LOCK_thread_count); - ulong tmp=(ulong) (my_rnd(&sql_rand) * 0xffffffff); /* make all bits random */ - mysql_mutex_unlock(&LOCK_thread_count); - return tmp; + my_atomic_rwlock_wrlock(lock); + (void) my_atomic_add32(value, 1); + my_atomic_rwlock_wrunlock(lock); } -inline int32 -inc_thread_running() +inline void thread_safe_decrement32(int32 *value, my_atomic_rwlock_t *lock) { - int32 num_thread_running; - my_atomic_rwlock_wrlock(&thread_running_lock); - num_thread_running= my_atomic_add32(&thread_running, 1); - my_atomic_rwlock_wrunlock(&thread_running_lock); - return (num_thread_running+1); + my_atomic_rwlock_wrlock(lock); + (void) my_atomic_add32(value, -1); + my_atomic_rwlock_wrunlock(lock); } -inline int32 -dec_thread_running() +inline void +inc_thread_running() { - int32 num_thread_running; - my_atomic_rwlock_wrlock(&thread_running_lock); - num_thread_running= my_atomic_add32(&thread_running, -1); - my_atomic_rwlock_wrunlock(&thread_running_lock); - return (num_thread_running-1); + thread_safe_increment32(&thread_running, &thread_running_lock); } -inline int32 -get_thread_running() +inline void +dec_thread_running() { - int32 num_thread_running; - my_atomic_rwlock_wrlock(&thread_running_lock); - num_thread_running= my_atomic_load32(&thread_running); - my_atomic_rwlock_wrunlock(&thread_running_lock); - return num_thread_running; + thread_safe_decrement32(&thread_running, &thread_running_lock); } void set_server_version(void); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 155c6365e76..33883f852aa 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -350,29 +350,6 @@ void thd_set_thread_stack(THD *thd, char *stack_start) } /** - Lock connection data for the set of connections this connection - belongs to - - @param thd THD object -*/ -void thd_lock_thread_count(THD *) -{ - mysql_mutex_lock(&LOCK_thread_count); -} - -/** - Lock connection data for the set of connections this connection - belongs to - - @param thd THD object -*/ -void thd_unlock_thread_count(THD *) -{ - mysql_cond_broadcast(&COND_thread_count); - mysql_mutex_unlock(&LOCK_thread_count); -} - -/** Close the socket used by this connection @param thd THD object @@ -947,7 +924,14 @@ THD::THD() protocol_binary.init(this); tablespace_op=FALSE; - tmp= sql_rnd_with_mutex(); + + /* + Initialize the random generator. We call my_rnd() without a lock as + it's not really critical if two threads modifies the structure at the + same time. We ensure that we have an unique number foreach thread + by adding the address of the stack. + */ + tmp= (ulong) (my_rnd(&sql_rand) * 0xffffffff); my_rnd_init(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id); substitute_null_with_insert_id = FALSE; thr_lock_info_init(&lock_info); /* safety: will be reset after start */ diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 833e134bff9..efbf35fe575 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2038,9 +2038,9 @@ public: thd.unlink(); // Must be unlinked under lock my_free(thd.query()); thd.security_ctx->user= thd.security_ctx->host=0; - thread_count--; delayed_insert_threads--; mysql_mutex_unlock(&LOCK_thread_count); + thread_safe_decrement32(&thread_count, &thread_count_lock); mysql_cond_broadcast(&COND_thread_count); /* Tell main we are ready */ } @@ -2175,9 +2175,9 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request, { if (!(di= new Delayed_insert())) goto end_create; - mysql_mutex_lock(&LOCK_thread_count); - thread_count++; - mysql_mutex_unlock(&LOCK_thread_count); + + thread_safe_increment32(&thread_count, &thread_count_lock); + /* Annotating delayed inserts is not supported. */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0abb249d97b..f6b765335b8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -645,9 +645,10 @@ end: delete thd; #ifndef EMBEDDED_LIBRARY - mysql_mutex_lock(&LOCK_thread_count); - thread_count--; + thread_safe_decrement32(&thread_count, &thread_count_lock); in_bootstrap= FALSE; + + mysql_mutex_lock(&LOCK_thread_count); mysql_cond_broadcast(&COND_thread_count); mysql_mutex_unlock(&LOCK_thread_count); my_thread_end(); diff --git a/vio/vio.c b/vio/vio.c index aed99e72d54..6e2ec3f674b 100644 --- a/vio/vio.c +++ b/vio/vio.c @@ -213,9 +213,7 @@ Vio *vio_new(my_socket sd, enum enum_vio_type type, uint flags) if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME)))) { vio_init(vio, type, sd, 0, flags); - sprintf(vio->desc, - (vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"), - vio->sd); + vio->desc= (vio->type == VIO_TYPE_SOCKET ? "socket" : "TCP/IP"); #if !defined(__WIN__) #if !defined(NO_FCNTL_NONBLOCK) /* @@ -257,7 +255,7 @@ Vio *vio_new_win32pipe(HANDLE hPipe) if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME)))) { vio_init(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, VIO_LOCALHOST); - strmov(vio->desc, "named pipe"); + vio->desc= "named pipe"; } DBUG_RETURN(vio); } @@ -282,7 +280,7 @@ Vio *vio_new_win32shared_memory(HANDLE handle_file_map, HANDLE handle_map, vio->event_conn_closed= event_conn_closed; vio->shared_memory_remain= 0; vio->shared_memory_pos= handle_map; - strmov(vio->desc, "shared memory"); + vio->desc= "shared memory"; } DBUG_RETURN(vio); } |