diff options
author | Eugene Kosov <claprix@yandex.ru> | 2017-10-12 17:13:01 +0300 |
---|---|---|
committer | Sergey Vojtovich <svoj@mariadb.org> | 2017-10-12 18:26:22 +0400 |
commit | f3ad3bbe7704d2a45e825b763d9ca36e3a7b4483 (patch) | |
tree | c4f0d0e00c104ea4cce1b4a5df450004954fd756 | |
parent | 7d2a7782fe580b6e2c220eefa392340440d59c6a (diff) | |
download | mariadb-git-f3ad3bbe7704d2a45e825b763d9ca36e3a7b4483.tar.gz |
fix data races
-rw-r--r-- | storage/innobase/include/sync0rw.ic | 18 | ||||
-rw-r--r-- | storage/innobase/sync/sync0rw.cc | 4 |
2 files changed, 14 insertions, 8 deletions
diff --git a/storage/innobase/include/sync0rw.ic b/storage/innobase/include/sync0rw.ic index dd59cd2615a..a048476d0e8 100644 --- a/storage/innobase/include/sync0rw.ic +++ b/storage/innobase/include/sync0rw.ic @@ -393,17 +393,21 @@ rw_lock_x_unlock_func( #endif /* UNIV_DEBUG */ rw_lock_t* lock) /*!< in/out: rw-lock */ { - ut_ad(lock->lock_word == 0 || lock->lock_word == -X_LOCK_HALF_DECR - || lock->lock_word <= -X_LOCK_DECR); + lint lock_word; + lock_word = my_atomic_loadlint_explicit(&lock->lock_word, + MY_MEMORY_ORDER_RELAXED); - if (lock->lock_word == 0) { + ut_ad(lock_word == 0 || lock_word == -X_LOCK_HALF_DECR + || lock_word <= -X_LOCK_DECR); + + if (lock_word == 0) { /* Last caller in a possible recursive chain. */ lock->writer_thread = 0; } ut_d(rw_lock_remove_debug_info(lock, pass, RW_LOCK_X)); - if (lock->lock_word == 0 || lock->lock_word == -X_LOCK_HALF_DECR) { + if (lock_word == 0 || lock_word == -X_LOCK_HALF_DECR) { /* There is 1 x-lock */ /* atomic increment is needed, because it is last */ if (my_atomic_addlint(&lock->lock_word, X_LOCK_DECR) <= -X_LOCK_DECR) { @@ -421,13 +425,13 @@ rw_lock_x_unlock_func( os_event_set(lock->event); sync_array_object_signalled(); } - } else if (lock->lock_word == -X_LOCK_DECR - || lock->lock_word == -(X_LOCK_DECR + X_LOCK_HALF_DECR)) { + } else if (lock_word == -X_LOCK_DECR + || lock_word == -(X_LOCK_DECR + X_LOCK_HALF_DECR)) { /* There are 2 x-locks */ lock->lock_word += X_LOCK_DECR; } else { /* There are more than 2 x-locks. */ - ut_ad(lock->lock_word < -X_LOCK_DECR); + ut_ad(lock_word < -X_LOCK_DECR); lock->lock_word += 1; } diff --git a/storage/innobase/sync/sync0rw.cc b/storage/innobase/sync/sync0rw.cc index 079f968dff9..328094f5fd3 100644 --- a/storage/innobase/sync/sync0rw.cc +++ b/storage/innobase/sync/sync0rw.cc @@ -310,7 +310,9 @@ lock_loop: /* Spin waiting for the writer field to become free */ HMT_low(); - while (i < srv_n_spin_wait_rounds && lock->lock_word <= 0) { + while (i < srv_n_spin_wait_rounds && + my_atomic_loadlint_explicit(&lock->lock_word, + MY_MEMORY_ORDER_RELAXED) <= 0) { if (srv_spin_wait_delay) { ut_delay(ut_rnd_interval(0, srv_spin_wait_delay)); } |