diff options
author | Sergei Golubchik <sergii@pisem.net> | 2011-10-19 21:53:14 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2011-10-19 21:53:14 +0200 |
commit | c612e1c8f5248a19462e3648e72f3d51237108f8 (patch) | |
tree | 3538a24ed306fc91ed1b1d0b5af8e1ba8b8dfc90 | |
parent | 0148d259535752ca5cc22c31e9f16570937ca083 (diff) | |
download | mariadb-git-c612e1c8f5248a19462e3648e72f3d51237108f8.tar.gz |
safe_mutex deadlock detector post-merge fixes
-rw-r--r-- | include/my_pthread.h | 12 | ||||
-rw-r--r-- | include/mysql/psi/mysql_thread.h | 3 | ||||
-rw-r--r-- | mysys/thr_mutex.c | 2 | ||||
-rw-r--r-- | sql/rpl_mi.cc | 10 | ||||
-rw-r--r-- | sql/slave.cc | 6 | ||||
-rw-r--r-- | sql/sql_class.cc | 5 | ||||
-rw-r--r-- | storage/maria/ma_loghandler.c | 1 |
7 files changed, 28 insertions, 11 deletions
diff --git a/include/my_pthread.h b/include/my_pthread.h index 40b939f8fc7..9f851db4209 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -512,11 +512,13 @@ void safe_mutex_free_deadlock_data(safe_mutex_t *mp); #define safe_mutex_assert_not_owner(mp) \ DBUG_ASSERT(! (mp)->count || \ ! pthread_equal(pthread_self(), (mp)->thread)) +#define safe_mutex_setflags(mp, F) do { (mp)->create_flags|= (F); } while (0) #else #define my_pthread_mutex_init(A,B,C,D) pthread_mutex_init((A),(B)) #define safe_mutex_assert_owner(mp) do {} while(0) #define safe_mutex_assert_not_owner(mp) do {} while(0) #define safe_mutex_free_deadlock_data(mp) do {} while(0) +#define safe_mutex_setflags(mp, F) do {} while (0) #endif /* SAFE_MUTEX */ #if defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) @@ -920,6 +922,16 @@ extern uint thd_lib_detected; #define status_var_add(V,C) (V)+=(C) #define status_var_sub(V,C) (V)-=(C) +#ifdef SAFE_MUTEX +#define mysql_mutex_record_order(A,B) \ + do { \ + mysql_mutex_lock(A); mysql_mutex_lock(B); \ + mysql_mutex_unlock(B); mysql_mutex_unlock(A); \ + } while(0) +#else +#define mysql_mutex_record_order(A,B) do { } while(0) +#endif + #ifdef __cplusplus } #endif diff --git a/include/mysql/psi/mysql_thread.h b/include/mysql/psi/mysql_thread.h index d20e89a26fd..18b4fde8c5c 100644 --- a/include/mysql/psi/mysql_thread.h +++ b/include/mysql/psi/mysql_thread.h @@ -213,6 +213,9 @@ typedef struct st_mysql_cond mysql_cond_t; #define mysql_mutex_assert_not_owner(M) \ safe_mutex_assert_not_owner(&(M)->m_mutex) +#define mysql_mutex_setflags(M, F) \ + safe_mutex_setflags(&(M)->m_mutex, (F)) + /** Wrappers for instrumented prlock objects. */ #define mysql_prlock_assert_write_owner(M) \ diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c index 86a7ce9684b..83395adaf61 100644 --- a/mysys/thr_mutex.c +++ b/mysys/thr_mutex.c @@ -201,7 +201,7 @@ int safe_mutex_init(safe_mutex_t *mp, /* Deadlock detection is initialised only lazily, on first use. */ - mp->create_flags= safe_mutex_deadlock_detector ? MYF_NO_DEADLOCK_DETECTION : 0; + mp->create_flags= safe_mutex_deadlock_detector ? 0 : MYF_NO_DEADLOCK_DETECTION; #ifdef SAFE_MUTEX_DETECT_DESTROY /* diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 705d3a8e450..f491db25048 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -41,17 +41,11 @@ Master_info::Master_info(bool is_slave_recovery) bzero((char*) &file, sizeof(file)); mysql_mutex_init(key_master_info_run_lock, &run_lock, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_master_info_data_lock, &data_lock, MY_MUTEX_INIT_FAST); + mysql_mutex_setflags(&run_lock, MYF_NO_DEADLOCK_DETECTION); + mysql_mutex_setflags(&data_lock, MYF_NO_DEADLOCK_DETECTION); mysql_cond_init(key_master_info_data_cond, &data_cond, NULL); mysql_cond_init(key_master_info_start_cond, &start_cond, NULL); mysql_cond_init(key_master_info_stop_cond, &stop_cond, NULL); - -#ifdef SAFE_MUTEX - /* Define mutex order for locks to find wrong lock usage */ - mysql_mutex_lock(&data_lock); - mysql_mutex_lock(&run_lock); - mysql_mutex_unlock(&run_lock); - mysql_mutex_unlock(&data_lock); -#endif } Master_info::~Master_info() diff --git a/sql/slave.cc b/sql/slave.cc index 4d8759b1c29..26d57353084 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3331,6 +3331,10 @@ pthread_handler_t handle_slave_sql(void *arg) LINT_INIT(saved_master_log_pos); LINT_INIT(saved_log_pos); + + thd = new THD; // note that contructor of THD uses DBUG_ ! + thd->thread_stack = (char*)&thd; // remember where our stack is + DBUG_ASSERT(rli->inited); mysql_mutex_lock(&rli->run_lock); DBUG_ASSERT(!rli->slave_running); @@ -3339,8 +3343,6 @@ pthread_handler_t handle_slave_sql(void *arg) rli->events_till_abort = abort_slave_event_count; #endif - thd = new THD; // note that contructor of THD uses DBUG_ ! - thd->thread_stack = (char*)&thd; // remember where our stack is rli->sql_thd= thd; /* Inform waiting threads that slave has started */ diff --git a/sql/sql_class.cc b/sql/sql_class.cc index b139dc962e2..160c8902701 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -828,6 +828,11 @@ THD::THD() mysql_mutex_init(key_LOCK_thd_data, &LOCK_thd_data, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_wakeup_ready, &LOCK_wakeup_ready, MY_MUTEX_INIT_FAST); mysql_cond_init(key_COND_wakeup_ready, &COND_wakeup_ready, 0); + /* + LOCK_thread_count goes before LOCK_thd_data - the former is called around + 'delete thd', the latter - in THD::~THD + */ + mysql_mutex_record_order(&LOCK_thread_count, &LOCK_thd_data); /* Variables with default values */ proc_info="login"; diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 18a6179d056..7ca9c46a998 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -1518,6 +1518,7 @@ static my_bool translog_buffer_init(struct st_translog_buffer *buffer, int num) mysql_cond_init(key_TRANSLOG_BUFFER_prev_sent_to_disk_cond, &buffer->prev_sent_to_disk_cond, 0)) DBUG_RETURN(1); + mysql_mutex_setflags(&buffer->mutex, MYF_NO_DEADLOCK_DETECTION); buffer->is_closing_buffer= 0; buffer->prev_sent_to_disk= LSN_IMPOSSIBLE; buffer->prev_buffer_offset= LSN_IMPOSSIBLE; |