summaryrefslogtreecommitdiff
path: root/sql/lock.cc
diff options
context:
space:
mode:
authorKonstantin Osipov <kostja@sun.com>2009-12-10 11:41:03 +0300
committerKonstantin Osipov <kostja@sun.com>2009-12-10 11:41:03 +0300
commitf12936728885621bad57e0c21e2c0b35447742d2 (patch)
tree1af99bc4bb290dd6389f05386dda02b151f85ece /sql/lock.cc
parentf26f632b44dfe9a6cc239a10f8697ba0ba50675d (diff)
parent0bd574102208166774c79c8ffda40c6fc3779389 (diff)
downloadmariadb-git-f12936728885621bad57e0c21e2c0b35447742d2.tar.gz
Merge with next-4284.
Diffstat (limited to 'sql/lock.cc')
-rw-r--r--sql/lock.cc93
1 files changed, 93 insertions, 0 deletions
diff --git a/sql/lock.cc b/sql/lock.cc
index 648fecf9b69..b64f7b0b44c 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -1099,6 +1099,19 @@ static volatile uint waiting_for_read_lock=0;
#define GOT_GLOBAL_READ_LOCK 1
#define MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT 2
+/**
+ Take global read lock, wait if there is protection against lock.
+
+ If the global read lock is already taken by this thread, then nothing is done.
+
+ See also "Handling of global read locks" above.
+
+ @param thd Reference to thread.
+
+ @retval False Success, global read lock set, commits are NOT blocked.
+ @retval True Failure, thread was killed.
+*/
+
bool lock_global_read_lock(THD *thd)
{
DBUG_ENTER("lock_global_read_lock");
@@ -1165,6 +1178,16 @@ bool lock_global_read_lock(THD *thd)
}
+/**
+ Unlock global read lock.
+
+ Commits may or may not be blocked when this function is called.
+
+ See also "Handling of global read locks" above.
+
+ @param thd Reference to thread.
+*/
+
void unlock_global_read_lock(THD *thd)
{
uint tmp;
@@ -1191,6 +1214,25 @@ void unlock_global_read_lock(THD *thd)
DBUG_VOID_RETURN;
}
+/**
+ Wait if the global read lock is set, and optionally seek protection against
+ global read lock.
+
+ See also "Handling of global read locks" above.
+
+ @param thd Reference to thread.
+ @param abort_on_refresh If True, abort waiting if a refresh occurs,
+ do NOT seek protection against GRL.
+ If False, wait until the GRL is released and seek
+ protection against GRL.
+ @param is_not_commit If False, called from a commit operation,
+ wait only if commit blocking is also enabled.
+
+ @retval False Success, protection against global read lock is set
+ (if !abort_on_refresh)
+ @retval True Failure, wait was aborted or thread was killed.
+*/
+
#define must_wait (global_read_lock && \
(is_not_commit || \
global_read_lock_blocks_commit))
@@ -1203,6 +1245,16 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
DBUG_ENTER("wait_if_global_read_lock");
/*
+ If we already have protection against global read lock,
+ just increment the counter.
+ */
+ if (unlikely(thd->global_read_lock_protection > 0))
+ {
+ if (!abort_on_refresh)
+ thd->global_read_lock_protection++;
+ DBUG_RETURN(FALSE);
+ }
+ /*
Assert that we do not own LOCK_open. If we would own it, other
threads could not close their tables. This would make a pretty
deadlock.
@@ -1238,7 +1290,12 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
result=1;
}
if (!abort_on_refresh && !result)
+ {
+ thd->global_read_lock_protection++;
protect_against_global_read_lock++;
+ DBUG_PRINT("sql_lock", ("protect_against_global_read_lock incr: %u",
+ protect_against_global_read_lock));
+ }
/*
The following is only true in case of a global read locks (which is rare)
and if old_message is set
@@ -1251,10 +1308,31 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
}
+/**
+ Release protection against global read lock and restart
+ global read lock waiters.
+
+ Should only be called if we have protection against global read lock.
+
+ See also "Handling of global read locks" above.
+
+ @param thd Reference to thread.
+*/
+
void start_waiting_global_read_lock(THD *thd)
{
bool tmp;
DBUG_ENTER("start_waiting_global_read_lock");
+ /*
+ Ignore request if we do not have protection against global read lock.
+ (Note that this is a violation of the interface contract, hence the assert).
+ */
+ DBUG_ASSERT(thd->global_read_lock_protection > 0);
+ if (unlikely(thd->global_read_lock_protection == 0))
+ DBUG_VOID_RETURN;
+ /* Decrement local read lock protection counter, return if we still have it */
+ if (unlikely(--thd->global_read_lock_protection > 0))
+ DBUG_VOID_RETURN;
if (unlikely(thd->global_read_lock))
DBUG_VOID_RETURN;
(void) pthread_mutex_lock(&LOCK_global_read_lock);
@@ -1268,6 +1346,21 @@ void start_waiting_global_read_lock(THD *thd)
}
+/**
+ Make global read lock also block commits.
+
+ The scenario is:
+ - This thread has the global read lock.
+ - Global read lock blocking of commits is not set.
+
+ See also "Handling of global read locks" above.
+
+ @param thd Reference to thread.
+
+ @retval False Success, global read lock set, commits are blocked.
+ @retval True Failure, thread was killed.
+*/
+
bool make_global_read_lock_block_commit(THD *thd)
{
bool error;