1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Merge from mysql-5.5-runtime to mysql-5.5-bugteam

No conflicts
This commit is contained in:
Jon Olav Hauglid
2010-11-18 16:01:58 +01:00
95 changed files with 6696 additions and 1876 deletions

View File

@ -1179,36 +1179,70 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
}
/**
Awake a thread.
@param[in] state_to_set value for THD::killed
This is normally called from another thread's THD object.
@note Do always call this while holding LOCK_thd_data.
*/
void THD::awake(THD::killed_state state_to_set)
{
DBUG_ENTER("THD::awake");
DBUG_PRINT("enter", ("this: 0x%lx", (long) this));
DBUG_PRINT("enter", ("this: %p current_thd: %p", this, current_thd));
THD_CHECK_SENTRY(this);
mysql_mutex_assert_owner(&LOCK_thd_data);
/* Set the 'killed' flag of 'this', which is the target THD object. */
killed= state_to_set;
if (state_to_set != THD::KILL_QUERY)
{
thr_alarm_kill(thread_id);
if (!slave_thread)
MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (this));
#ifdef SIGNAL_WITH_VIO_CLOSE
if (this != current_thd)
{
/*
In addition to a signal, let's close the socket of the thread that
is being killed. This is to make sure it does not block if the
signal is lost. This needs to be done only on platforms where
signals are not a reliable interruption mechanism.
Before sending a signal, let's close the socket of the thread
that is being killed ("this", which is not the current thread).
This is to make sure it does not block if the signal is lost.
This needs to be done only on platforms where signals are not
a reliable interruption mechanism.
If we're killing ourselves, we know that we're not blocked, so this
hack is not used.
Note that the downside of this mechanism is that we could close
the connection while "this" target thread is in the middle of
sending a result to the application, thus violating the client-
server protocol.
On the other hand, without closing the socket we have a race
condition. If "this" target thread passes the check of
thd->killed, and then the current thread runs through
THD::awake(), sets the 'killed' flag and completes the
signaling, and then the target thread runs into read(), it will
block on the socket. As a result of the discussions around
Bug#37780, it has been decided that we accept the race
condition. A second KILL awakes the target from read().
If we are killing ourselves, we know that we are not blocked.
We also know that we will check thd->killed before we go for
reading the next statement.
*/
close_active_vio();
}
#endif
#endif
/* Mark the target thread's alarm request expired, and signal alarm. */
thr_alarm_kill(thread_id);
/* Send an event to the scheduler that a thread should be killed. */
if (!slave_thread)
MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (this));
}
/* Broadcast a condition to kick the target if it is waiting on it. */
if (mysys_var)
{
mysql_mutex_lock(&mysys_var->mutex);
@ -1232,6 +1266,11 @@ void THD::awake(THD::killed_state state_to_set)
we issue a second KILL or the status it's waiting for happens).
It's true that we have set its thd->killed but it may not
see it immediately and so may have time to reach the cond_wait().
However, where possible, we test for killed once again after
enter_cond(). This should make the signaling as safe as possible.
However, there is still a small chance of failure on platforms with
instruction or memory write reordering.
*/
if (mysys_var->current_cond && mysys_var->current_mutex)
{
@ -3456,11 +3495,15 @@ void THD::set_mysys_var(struct st_my_thread_var *new_mysys_var)
void THD::leave_locked_tables_mode()
{
locked_tables_mode= LTM_NONE;
/* Make sure we don't release the global read lock when leaving LTM. */
mdl_context.reset_trans_sentinel(global_read_lock.global_shared_lock());
mdl_context.set_transaction_duration_for_all_locks();
/*
Make sure we don't release the global read lock and commit blocker
when leaving LTM.
*/
global_read_lock.set_explicit_lock_duration(this);
/* Also ensure that we don't release metadata locks for open HANDLERs. */
if (handler_tables_hash.records)
mysql_ha_move_tickets_after_trans_sentinel(this);
mysql_ha_set_explicit_lock_duration(this);
}
void THD::get_definer(LEX_USER *definer)