summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2011-10-19 21:53:14 +0200
committerSergei Golubchik <sergii@pisem.net>2011-10-19 21:53:14 +0200
commitc612e1c8f5248a19462e3648e72f3d51237108f8 (patch)
tree3538a24ed306fc91ed1b1d0b5af8e1ba8b8dfc90
parent0148d259535752ca5cc22c31e9f16570937ca083 (diff)
downloadmariadb-git-c612e1c8f5248a19462e3648e72f3d51237108f8.tar.gz
safe_mutex deadlock detector post-merge fixes
-rw-r--r--include/my_pthread.h12
-rw-r--r--include/mysql/psi/mysql_thread.h3
-rw-r--r--mysys/thr_mutex.c2
-rw-r--r--sql/rpl_mi.cc10
-rw-r--r--sql/slave.cc6
-rw-r--r--sql/sql_class.cc5
-rw-r--r--storage/maria/ma_loghandler.c1
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;