summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--storage/innobase/sync/srw_lock.cc15
1 files changed, 10 insertions, 5 deletions
diff --git a/storage/innobase/sync/srw_lock.cc b/storage/innobase/sync/srw_lock.cc
index 3efdb05f3f7..223acac665f 100644
--- a/storage/innobase/sync/srw_lock.cc
+++ b/storage/innobase/sync/srw_lock.cc
@@ -204,11 +204,12 @@ void ssux_lock_low::write_lock(bool holding_u)
ut_delay(srv_spin_wait_delay);
}
- l= holding_u ? WRITER_WAITING | UPDATER : WRITER_WAITING;
+ const uint32_t e= holding_u ? WRITER_WAITING | UPDATER : WRITER_WAITING;
+ l= e;
if (write_lock_wait_try(l))
return;
- while (!(l & WRITER_WAITING))
+ if (!(l & WRITER_WAITING))
{
switch (l) {
case UNLOCKED:
@@ -220,10 +221,14 @@ void ssux_lock_low::write_lock(bool holding_u)
if (holding_u && upgrade_trylock())
return;
}
- l= write_lock_wait_start() | WRITER_WAITING;
- }
- DBUG_ASSERT(~WRITER_WAITING & l);
+ for (l= write_lock_wait_start() | WRITER_WAITING;
+ (l | WRITER_WAITING) == e; )
+ if (write_lock_wait_try(l))
+ return;
+ }
+ else
+ DBUG_ASSERT(~WRITER_WAITING & l);
writer_wait(l);
}