Commit 265a6edd authored by Konstantin Osipov's avatar Konstantin Osipov

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.
parent 64cc044e
...@@ -601,6 +601,8 @@ int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp); ...@@ -601,6 +601,8 @@ int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp);
#define rw_trywrlock(A) my_rw_trywrlock((A)) #define rw_trywrlock(A) my_rw_trywrlock((A))
#define rw_unlock(A) my_rw_unlock((A)) #define rw_unlock(A) my_rw_unlock((A))
#define rwlock_destroy(A) my_rw_destroy((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 */ #endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */
...@@ -624,6 +626,8 @@ extern int rw_pr_init(rw_pr_lock_t *); ...@@ -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_trywrlock(A) pthread_rwlock_trywrlock(A)
#define rw_pr_unlock(A) pthread_rwlock_unlock(A) #define rw_pr_unlock(A) pthread_rwlock_unlock(A)
#define rw_pr_destroy(A) pthread_rwlock_destroy(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 #else
/* Otherwise we have to use our own implementation of read/write locks. */ /* Otherwise we have to use our own implementation of read/write locks. */
#define NEED_MY_RW_LOCK 1 #define NEED_MY_RW_LOCK 1
...@@ -636,6 +640,8 @@ extern int rw_pr_init(struct st_my_rw_lock_t *); ...@@ -636,6 +640,8 @@ extern int rw_pr_init(struct st_my_rw_lock_t *);
#define rw_pr_trywrlock(A) my_rw_trywrlock((A)) #define rw_pr_trywrlock(A) my_rw_trywrlock((A))
#define rw_pr_unlock(A) my_rw_unlock((A)) #define rw_pr_unlock(A) my_rw_unlock((A))
#define rw_pr_destroy(A) my_rw_destroy((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) */ #endif /* defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP) */
...@@ -651,6 +657,9 @@ typedef struct st_my_rw_lock_t { ...@@ -651,6 +657,9 @@ typedef struct st_my_rw_lock_t {
int state; /* -1:writer,0:free,>0:readers */ int state; /* -1:writer,0:free,>0:readers */
int waiters; /* number of waiting writers */ int waiters; /* number of waiting writers */
my_bool prefer_readers; my_bool prefer_readers;
#ifdef SAFE_MUTEX
pthread_t write_thread;
#endif
} my_rw_lock_t; } my_rw_lock_t;
extern int my_rw_init(my_rw_lock_t *, my_bool *); extern int my_rw_init(my_rw_lock_t *, my_bool *);
...@@ -660,6 +669,17 @@ extern int my_rw_wrlock(my_rw_lock_t *); ...@@ -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_unlock(my_rw_lock_t *);
extern int my_rw_tryrdlock(my_rw_lock_t *); extern int my_rw_tryrdlock(my_rw_lock_t *);
extern int my_rw_trywrlock(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 */ #endif /* NEED_MY_RW_LOCK */
......
...@@ -215,6 +215,14 @@ typedef struct st_mysql_cond mysql_cond_t; ...@@ -215,6 +215,14 @@ typedef struct st_mysql_cond mysql_cond_t;
#define mysql_mutex_assert_not_owner(M) \ #define mysql_mutex_assert_not_owner(M) \
safe_mutex_assert_not_owner(&(M)->m_mutex) 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) @def mysql_mutex_init(K, M, A)
Instrumented mutex_init. Instrumented mutex_init.
......
...@@ -71,6 +71,9 @@ int my_rw_init(my_rw_lock_t *rwp, my_bool *prefer_readers_attr) ...@@ -71,6 +71,9 @@ int my_rw_init(my_rw_lock_t *rwp, my_bool *prefer_readers_attr)
rwp->state = 0; rwp->state = 0;
rwp->waiters = 0; rwp->waiters = 0;
#ifdef SAFE_MUTEX
rwp->write_thread = 0;
#endif
/* If attribute argument is NULL use default value - prefer writers. */ /* If attribute argument is NULL use default value - prefer writers. */
rwp->prefer_readers= prefer_readers_attr ? *prefer_readers_attr : FALSE; rwp->prefer_readers= prefer_readers_attr ? *prefer_readers_attr : FALSE;
...@@ -80,6 +83,7 @@ int my_rw_init(my_rw_lock_t *rwp, my_bool *prefer_readers_attr) ...@@ -80,6 +83,7 @@ int my_rw_init(my_rw_lock_t *rwp, my_bool *prefer_readers_attr)
int my_rw_destroy(my_rw_lock_t *rwp) int my_rw_destroy(my_rw_lock_t *rwp)
{ {
DBUG_ASSERT(rwp->state == 0);
pthread_mutex_destroy( &rwp->lock ); pthread_mutex_destroy( &rwp->lock );
pthread_cond_destroy( &rwp->readers ); pthread_cond_destroy( &rwp->readers );
pthread_cond_destroy( &rwp->writers ); pthread_cond_destroy( &rwp->writers );
...@@ -123,10 +127,15 @@ int my_rw_wrlock(my_rw_lock_t *rwp) ...@@ -123,10 +127,15 @@ int my_rw_wrlock(my_rw_lock_t *rwp)
pthread_mutex_lock(&rwp->lock); pthread_mutex_lock(&rwp->lock);
rwp->waiters++; /* another writer queued */ rwp->waiters++; /* another writer queued */
my_rw_lock_assert_not_owner(rwp);
while (rwp->state) while (rwp->state)
pthread_cond_wait(&rwp->writers, &rwp->lock); pthread_cond_wait(&rwp->writers, &rwp->lock);
rwp->state = -1; rwp->state = -1;
rwp->waiters--; rwp->waiters--;
#ifdef SAFE_MUTEX
rwp->write_thread= pthread_self();
#endif
pthread_mutex_unlock(&rwp->lock); pthread_mutex_unlock(&rwp->lock);
return(0); return(0);
} }
...@@ -142,6 +151,9 @@ int my_rw_trywrlock(my_rw_lock_t *rwp) ...@@ -142,6 +151,9 @@ int my_rw_trywrlock(my_rw_lock_t *rwp)
{ {
res=0; res=0;
rwp->state = -1; rwp->state = -1;
#ifdef SAFE_MUTEX
rwp->write_thread= pthread_self();
#endif
} }
pthread_mutex_unlock(&rwp->lock); pthread_mutex_unlock(&rwp->lock);
return(res); return(res);
...@@ -154,9 +166,15 @@ int my_rw_unlock(my_rw_lock_t *rwp) ...@@ -154,9 +166,15 @@ int my_rw_unlock(my_rw_lock_t *rwp)
("state: %d waiters: %d", rwp->state, rwp->waiters)); ("state: %d waiters: %d", rwp->state, rwp->waiters));
pthread_mutex_lock(&rwp->lock); pthread_mutex_lock(&rwp->lock);
DBUG_ASSERT(rwp->state != 0);
if (rwp->state == -1) /* writer releasing */ if (rwp->state == -1) /* writer releasing */
{ {
my_rw_lock_assert_write_owner(rwp);
rwp->state= 0; /* mark as available */ rwp->state= 0; /* mark as available */
#ifdef SAFE_MUTEX
rwp->write_thread= 0;
#endif
if ( rwp->waiters ) /* writers queued */ if ( rwp->waiters ) /* writers queued */
pthread_cond_signal( &rwp->writers ); pthread_cond_signal( &rwp->writers );
......
...@@ -8654,7 +8654,9 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type, ...@@ -8654,7 +8654,9 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
if (! has_lock) if (! has_lock)
mysql_mutex_lock(&LOCK_open); mysql_mutex_lock(&LOCK_open);
else else
{
mysql_mutex_assert_owner(&LOCK_open); mysql_mutex_assert_owner(&LOCK_open);
}
DBUG_ASSERT(remove_type == TDC_RT_REMOVE_UNUSED || DBUG_ASSERT(remove_type == TDC_RT_REMOVE_UNUSED ||
thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name, thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name,
......
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