#At file:///opt/local/work/5.5-runtime/ based on revid:magne.mahre@stripped
3100 Konstantin Osipov 2010-08-11
A pre-requisite patch for the fix for Bug#52044.
Implement a few simple asserts in my_rwlock_t locks.
@ include/my_pthread.h
Declare two simple assert functions.
@ include/mysql/psi/mysql_thread.h
Add wrappers for new assert functions.
@ mysys/thr_rwlock.c
Add asserts.
@ sql/sql_base.cc
Silence a compiler warning for the case when
SAFE_MUTEX is not ON.
modified:
include/my_pthread.h
include/mysql/psi/mysql_thread.h
mysys/thr_rwlock.c
sql/sql_base.cc
=== modified file 'include/my_pthread.h'
--- a/include/my_pthread.h 2010-07-20 19:30:10 +0000
+++ b/include/my_pthread.h 2010-08-10 21:12:01 +0000
@@ -601,6 +601,8 @@ int my_pthread_fastmutex_lock(my_pthread
#define rw_trywrlock(A) my_rw_trywrlock((A))
#define rw_unlock(A) my_rw_unlock((A))
#define rwlock_destroy(A) my_rw_destroy((A))
+#define rw_lock_assert_write_owner(A) my_rw_lock_assert_write_owner((A))
+#define rw_lock_assert_not_write_owner(A) my_rw_lock_assert_not_write_owner((A))
#endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */
@@ -624,6 +626,8 @@ extern int rw_pr_init(rw_pr_lock_t *);
#define rw_pr_trywrlock(A) pthread_rwlock_trywrlock(A)
#define rw_pr_unlock(A) pthread_rwlock_unlock(A)
#define rw_pr_destroy(A) pthread_rwlock_destroy(A)
+#define rw_pr_lock_assert_write_owner(A)
+#define rw_pr_lock_assert_not_write_owner(A)
#else
/* Otherwise we have to use our own implementation of read/write locks. */
#define NEED_MY_RW_LOCK 1
@@ -636,6 +640,8 @@ extern int rw_pr_init(struct st_my_rw_lo
#define rw_pr_trywrlock(A) my_rw_trywrlock((A))
#define rw_pr_unlock(A) my_rw_unlock((A))
#define rw_pr_destroy(A) my_rw_destroy((A))
+#define rw_pr_lock_assert_write_owner(A) my_rw_lock_assert_write_owner((A))
+#define rw_pr_lock_assert_not_write_owner(A) my_rw_lock_assert_not_write_owner((A))
#endif /* defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP) */
@@ -651,6 +657,9 @@ typedef struct st_my_rw_lock_t {
int state; /* -1:writer,0:free,>0:readers */
int waiters; /* number of waiting writers */
my_bool prefer_readers;
+#ifdef SAFE_MUTEX
+ pthread_t write_thread;
+#endif
} my_rw_lock_t;
extern int my_rw_init(my_rw_lock_t *, my_bool *);
@@ -660,6 +669,17 @@ extern int my_rw_wrlock(my_rw_lock_t *);
extern int my_rw_unlock(my_rw_lock_t *);
extern int my_rw_tryrdlock(my_rw_lock_t *);
extern int my_rw_trywrlock(my_rw_lock_t *);
+#ifdef SAFE_MUTEX
+#define my_rw_lock_assert_write_owner(A) \
+ DBUG_ASSERT((A)->state == -1 && pthread_equal(pthread_self(), \
+ (A)->write_thread))
+#define my_rw_lock_assert_not_write_owner(A) \
+ DBUG_ASSERT((A)->state >= 0 || ! pthread_equal(pthread_self(), \
+ (A)->write_thread))
+#else
+#define my_rw_lock_assert_write_owner(A)
+#define my_rw_lock_assert_not_write_owner(A)
+#endif
#endif /* NEED_MY_RW_LOCK */
=== modified file 'include/mysql/psi/mysql_thread.h'
--- a/include/mysql/psi/mysql_thread.h 2010-07-09 23:00:24 +0000
+++ b/include/mysql/psi/mysql_thread.h 2010-08-10 21:12:01 +0000
@@ -215,6 +215,14 @@ typedef struct st_mysql_cond mysql_cond_
#define mysql_mutex_assert_not_owner(M) \
safe_mutex_assert_not_owner(&(M)->m_mutex)
+/** Wrappers for instrumented prlock objects. */
+
+#define mysql_prlock_assert_write_owner(M) \
+ rw_pr_lock_assert_write_owner(&(M)->m_prlock)
+
+#define mysql_prlock_assert_not_write_owner(M) \
+ rw_pr_lock_assert_not_write_owner(&(M)->m_prlock)
+
/**
@def mysql_mutex_init(K, M, A)
Instrumented mutex_init.
=== modified file 'mysys/thr_rwlock.c'
--- a/mysys/thr_rwlock.c 2010-02-28 04:35:09 +0000
+++ b/mysys/thr_rwlock.c 2010-08-10 21:12:01 +0000
@@ -71,6 +71,9 @@ int my_rw_init(my_rw_lock_t *rwp, my_boo
rwp->state = 0;
rwp->waiters = 0;
+#ifdef SAFE_MUTEX
+ rwp->write_thread = 0;
+#endif
/* If attribute argument is NULL use default value - prefer writers. */
rwp->prefer_readers= prefer_readers_attr ? *prefer_readers_attr : FALSE;
@@ -80,6 +83,7 @@ int my_rw_init(my_rw_lock_t *rwp, my_boo
int my_rw_destroy(my_rw_lock_t *rwp)
{
+ DBUG_ASSERT(rwp->state == 0);
pthread_mutex_destroy( &rwp->lock );
pthread_cond_destroy( &rwp->readers );
pthread_cond_destroy( &rwp->writers );
@@ -123,10 +127,15 @@ int my_rw_wrlock(my_rw_lock_t *rwp)
pthread_mutex_lock(&rwp->lock);
rwp->waiters++; /* another writer queued */
+ my_rw_lock_assert_not_owner(rwp);
+
while (rwp->state)
pthread_cond_wait(&rwp->writers, &rwp->lock);
rwp->state = -1;
rwp->waiters--;
+#ifdef SAFE_MUTEX
+ rwp->write_thread= pthread_self();
+#endif
pthread_mutex_unlock(&rwp->lock);
return(0);
}
@@ -142,6 +151,9 @@ int my_rw_trywrlock(my_rw_lock_t *rwp)
{
res=0;
rwp->state = -1;
+#ifdef SAFE_MUTEX
+ rwp->write_thread= pthread_self();
+#endif
}
pthread_mutex_unlock(&rwp->lock);
return(res);
@@ -154,9 +166,15 @@ int my_rw_unlock(my_rw_lock_t *rwp)
("state: %d waiters: %d", rwp->state, rwp->waiters));
pthread_mutex_lock(&rwp->lock);
+ DBUG_ASSERT(rwp->state != 0);
+
if (rwp->state == -1) /* writer releasing */
{
+ my_rw_lock_assert_write_owner(rwp);
rwp->state= 0; /* mark as available */
+#ifdef SAFE_MUTEX
+ rwp->write_thread= 0;
+#endif
if ( rwp->waiters ) /* writers queued */
pthread_cond_signal( &rwp->writers );
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2010-08-09 18:33:47 +0000
+++ b/sql/sql_base.cc 2010-08-10 21:12:01 +0000
@@ -8654,7 +8654,9 @@ void tdc_remove_table(THD *thd, enum_tdc
if (! has_lock)
mysql_mutex_lock(&LOCK_open);
else
+ {
mysql_mutex_assert_owner(&LOCK_open);
+ }
DBUG_ASSERT(remove_type == TDC_RT_REMOVE_UNUSED ||
thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name,
Attachment: [text/bzr-bundle] bzr/kostja@sun.com-20100810211201-906u35vg6u0u1vcn.bundle
| Thread |
|---|
| • bzr commit into mysql-5.5-bugfixing branch (kostja:3100) Bug#52044 | Konstantin Osipov | 10 Aug |