mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
Avoiding a theoretically possible crash (pthread_mutex_lock(0)) which could (at least in POSIX Threads books)
happen on SMP machines, when a thread is going to wait on a condition and it is KILLed at the same time. Cleaning code a bit by adding a test in enter_cond() that we have the mutex (was already the case in all places where it's called except one which is fixed here).
This commit is contained in:
parent
e5c2285782
commit
0f20e2fece
4 changed files with 13 additions and 2 deletions
|
@ -1544,7 +1544,6 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
|
|||
|
||||
void MYSQL_LOG:: wait_for_update(THD* thd, bool master_or_slave)
|
||||
{
|
||||
safe_mutex_assert_owner(&LOCK_log);
|
||||
const char* old_msg = thd->enter_cond(&update_cond, &LOCK_log,
|
||||
master_or_slave ?
|
||||
"Has read all relay log; waiting for \
|
||||
|
|
|
@ -588,6 +588,7 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock,
|
|||
while (start_id == *slave_run_id)
|
||||
{
|
||||
DBUG_PRINT("sleep",("Waiting for slave thread to start"));
|
||||
pthread_mutex_lock(cond_lock);
|
||||
const char* old_msg = thd->enter_cond(start_cond,cond_lock,
|
||||
"Waiting for slave thread to start");
|
||||
pthread_cond_wait(start_cond,cond_lock);
|
||||
|
|
|
@ -299,8 +299,18 @@ void THD::awake(bool prepare_to_die)
|
|||
exits the cond in the time between read and broadcast, but that is
|
||||
ok since all we want to do is to make the victim thread get out
|
||||
of waiting on current_cond.
|
||||
If we see a non-zero current_cond: it cannot be an old value (because
|
||||
then exit_cond() should have run and it can't because we have mutex); so
|
||||
it is the true value but maybe current_mutex is not yet non-zero (we're
|
||||
in the middle of enter_cond() and there is a "memory order
|
||||
inversion"). So we test the mutex too to not lock 0.
|
||||
Note that there is a small chance we fail to kill. If victim has locked
|
||||
current_mutex, and hasn't entered enter_cond(), then we don't know it's
|
||||
going to wait on cond. Then victim goes into its cond "forever" (until
|
||||
we issue a second KILL). True we have set its thd->killed but it may not
|
||||
see it immediately and so may have time to reach the cond_wait().
|
||||
*/
|
||||
if (mysys_var->current_cond)
|
||||
if (mysys_var->current_cond && mysys_var->current_mutex)
|
||||
{
|
||||
pthread_mutex_lock(mysys_var->current_mutex);
|
||||
pthread_cond_broadcast(mysys_var->current_cond);
|
||||
|
|
|
@ -539,6 +539,7 @@ public:
|
|||
const char* msg)
|
||||
{
|
||||
const char* old_msg = proc_info;
|
||||
safe_mutex_assert_owner(mutex);
|
||||
mysys_var->current_mutex = mutex;
|
||||
mysys_var->current_cond = cond;
|
||||
proc_info = msg;
|
||||
|
|
Loading…
Reference in a new issue