mirror of
https://github.com/MariaDB/server.git
synced 2025-12-09 08:01:34 +03:00
Introduce a lock queue iterator for easy (and opaque) traversing of lock
queues. Supports table and record lock queues via the same interface. There is only "get previous" method because currently there is no need for "get next" - it would be unused. Feel free to add one if needed. Approved by: Heikki
This commit is contained in:
@@ -55,6 +55,7 @@ noinst_HEADERS = include/btr0btr.h include/btr0btr.ic \
|
|||||||
include/ha0ha.ic include/hash0hash.h \
|
include/ha0ha.ic include/hash0hash.h \
|
||||||
include/hash0hash.ic include/ibuf0ibuf.h \
|
include/hash0hash.ic include/ibuf0ibuf.h \
|
||||||
include/ibuf0ibuf.ic include/ibuf0types.h \
|
include/ibuf0ibuf.ic include/ibuf0types.h \
|
||||||
|
include/lock0iter.h \
|
||||||
include/lock0lock.h include/lock0lock.ic \
|
include/lock0lock.h include/lock0lock.ic \
|
||||||
include/lock0priv.h include/lock0priv.ic \
|
include/lock0priv.h include/lock0priv.ic \
|
||||||
include/lock0types.h include/log0log.h \
|
include/lock0types.h include/log0log.h \
|
||||||
@@ -130,7 +131,8 @@ libinnobase_a_SOURCES = btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \
|
|||||||
eval/eval0eval.c eval/eval0proc.c \
|
eval/eval0eval.c eval/eval0proc.c \
|
||||||
fil/fil0fil.c fsp/fsp0fsp.c fut/fut0fut.c \
|
fil/fil0fil.c fsp/fsp0fsp.c fut/fut0fut.c \
|
||||||
fut/fut0lst.c ha/ha0ha.c ha/hash0hash.c \
|
fut/fut0lst.c ha/ha0ha.c ha/hash0hash.c \
|
||||||
ibuf/ibuf0ibuf.c lock/lock0lock.c \
|
ibuf/ibuf0ibuf.c lock/lock0iter.c \
|
||||||
|
lock/lock0lock.c \
|
||||||
log/log0log.c log/log0recv.c mach/mach0data.c \
|
log/log0log.c log/log0recv.c mach/mach0data.c \
|
||||||
mem/mem0mem.c mem/mem0pool.c mtr/mtr0log.c \
|
mem/mem0mem.c mem/mem0pool.c mtr/mtr0log.c \
|
||||||
mtr/mtr0mtr.c os/os0file.c os/os0proc.c \
|
mtr/mtr0mtr.c os/os0file.c os/os0proc.c \
|
||||||
|
|||||||
52
include/lock0iter.h
Normal file
52
include/lock0iter.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/******************************************************
|
||||||
|
Lock queue iterator type and function prototypes.
|
||||||
|
|
||||||
|
(c) 2007 Innobase Oy
|
||||||
|
|
||||||
|
Created July 16, 2007 Vasil Dimov
|
||||||
|
*******************************************************/
|
||||||
|
|
||||||
|
#ifndef lock0iter_h
|
||||||
|
#define lock0iter_h
|
||||||
|
|
||||||
|
#include "univ.i"
|
||||||
|
#include "lock0types.h"
|
||||||
|
|
||||||
|
typedef struct lock_queue_iterator_struct {
|
||||||
|
lock_t* current_lock;
|
||||||
|
/* In case this is a record lock queue (not table lock queue)
|
||||||
|
then bit_no is the record number within the heap in which the
|
||||||
|
record is stored. */
|
||||||
|
ulint bit_no;
|
||||||
|
} lock_queue_iterator_t;
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
Initialize lock queue iterator so that it starts to iterate from
|
||||||
|
"lock". bit_no specifies the record number within the heap where the
|
||||||
|
record is stored. It can be undefined (ULINT_UNDEFINED) in two cases:
|
||||||
|
1. If the lock is a table lock, thus we have a table lock queue;
|
||||||
|
2. If the lock is a record lock and it is a wait lock. In this case
|
||||||
|
bit_no is calculated in this function by using
|
||||||
|
lock_rec_find_set_bit(). There is exactly one bit set in the bitmap
|
||||||
|
of a wait lock. */
|
||||||
|
|
||||||
|
void
|
||||||
|
lock_queue_iterator_reset(
|
||||||
|
/*======================*/
|
||||||
|
lock_queue_iterator_t* iter, /* out: iterator */
|
||||||
|
lock_t* lock, /* in: lock to start from */
|
||||||
|
ulint bit_no);/* in: record number in the
|
||||||
|
heap */
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
Gets the previous lock in the lock queue, returns NULL if there are no
|
||||||
|
more locks (i.e. the current lock is the first one). The iterator is
|
||||||
|
receded (if not-NULL is returned). */
|
||||||
|
|
||||||
|
lock_t*
|
||||||
|
lock_queue_iterator_get_prev(
|
||||||
|
/*=========================*/
|
||||||
|
/* out: previous lock or NULL */
|
||||||
|
lock_queue_iterator_t* iter); /* in/out: iterator */
|
||||||
|
|
||||||
|
#endif /* lock0iter_h */
|
||||||
91
lock/lock0iter.c
Normal file
91
lock/lock0iter.c
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/******************************************************
|
||||||
|
Lock queue iterator. Can iterate over table and record
|
||||||
|
lock queues.
|
||||||
|
|
||||||
|
(c) 2007 Innobase Oy
|
||||||
|
|
||||||
|
Created July 16, 2007 Vasil Dimov
|
||||||
|
*******************************************************/
|
||||||
|
|
||||||
|
#define LOCK_MODULE_IMPLEMENTATION
|
||||||
|
|
||||||
|
#include "univ.i"
|
||||||
|
#include "lock0iter.h"
|
||||||
|
#include "lock0lock.h"
|
||||||
|
#include "lock0priv.h"
|
||||||
|
#include "ut0dbg.h"
|
||||||
|
#include "ut0lst.h"
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
Initialize lock queue iterator so that it starts to iterate from
|
||||||
|
"lock". bit_no specifies the record number within the heap where the
|
||||||
|
record is stored. It can be undefined (ULINT_UNDEFINED) in two cases:
|
||||||
|
1. If the lock is a table lock, thus we have a table lock queue;
|
||||||
|
2. If the lock is a record lock and it is a wait lock. In this case
|
||||||
|
bit_no is calculated in this function by using
|
||||||
|
lock_rec_find_set_bit(). There is exactly one bit set in the bitmap
|
||||||
|
of a wait lock. */
|
||||||
|
|
||||||
|
void
|
||||||
|
lock_queue_iterator_reset(
|
||||||
|
/*======================*/
|
||||||
|
lock_queue_iterator_t* iter, /* out: iterator */
|
||||||
|
lock_t* lock, /* in: lock to start from */
|
||||||
|
ulint bit_no) /* in: record number in the
|
||||||
|
heap */
|
||||||
|
{
|
||||||
|
iter->current_lock = lock;
|
||||||
|
|
||||||
|
if (bit_no != ULINT_UNDEFINED) {
|
||||||
|
|
||||||
|
iter->bit_no = bit_no;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
switch (lock_get_type(lock)) {
|
||||||
|
case LOCK_TABLE:
|
||||||
|
iter->bit_no = ULINT_UNDEFINED;
|
||||||
|
break;
|
||||||
|
case LOCK_REC:
|
||||||
|
iter->bit_no = lock_rec_find_set_bit(lock);
|
||||||
|
ut_a(iter->bit_no != ULINT_UNDEFINED);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ut_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
Gets the previous lock in the lock queue, returns NULL if there are no
|
||||||
|
more locks (i.e. the current lock is the first one). The iterator is
|
||||||
|
receded (if not-NULL is returned). */
|
||||||
|
|
||||||
|
lock_t*
|
||||||
|
lock_queue_iterator_get_prev(
|
||||||
|
/*=========================*/
|
||||||
|
/* out: previous lock or NULL */
|
||||||
|
lock_queue_iterator_t* iter) /* in/out: iterator */
|
||||||
|
{
|
||||||
|
ulint bit_no;
|
||||||
|
lock_t* prev_lock;
|
||||||
|
|
||||||
|
switch (lock_get_type(iter->current_lock)) {
|
||||||
|
case LOCK_REC:
|
||||||
|
prev_lock = lock_rec_get_prev(
|
||||||
|
iter->current_lock, iter->bit_no);
|
||||||
|
break;
|
||||||
|
case LOCK_TABLE:
|
||||||
|
prev_lock = UT_LIST_GET_PREV(
|
||||||
|
un_member.tab_lock.locks, iter->current_lock);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ut_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prev_lock != NULL) {
|
||||||
|
|
||||||
|
iter->current_lock = prev_lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(prev_lock);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user