1 | /***************************************************************************** |
2 | |
3 | Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved. |
4 | |
5 | This program is free software; you can redistribute it and/or modify it under |
6 | the terms of the GNU General Public License as published by the Free Software |
7 | Foundation; version 2 of the License. |
8 | |
9 | This program is distributed in the hope that it will be useful, but WITHOUT |
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License along with |
14 | this program; if not, write to the Free Software Foundation, Inc., |
15 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
16 | |
17 | *****************************************************************************/ |
18 | |
19 | /**************************************************//** |
20 | @file lock/lock0iter.cc |
21 | Lock queue iterator. Can iterate over table and record |
22 | lock queues. |
23 | |
24 | Created July 16, 2007 Vasil Dimov |
25 | *******************************************************/ |
26 | |
27 | #define LOCK_MODULE_IMPLEMENTATION |
28 | |
29 | #include "univ.i" |
30 | #include "dict0mem.h" |
31 | #include "lock0iter.h" |
32 | #include "lock0lock.h" |
33 | #include "lock0priv.h" |
34 | |
35 | /*******************************************************************//** |
36 | Initialize lock queue iterator so that it starts to iterate from |
37 | "lock". bit_no specifies the record number within the heap where the |
38 | record is stored. It can be undefined (ULINT_UNDEFINED) in two cases: |
39 | 1. If the lock is a table lock, thus we have a table lock queue; |
40 | 2. If the lock is a record lock and it is a wait lock. In this case |
41 | bit_no is calculated in this function by using |
42 | lock_rec_find_set_bit(). There is exactly one bit set in the bitmap |
43 | of a wait lock. */ |
44 | void |
45 | lock_queue_iterator_reset( |
46 | /*======================*/ |
47 | lock_queue_iterator_t* iter, /*!< out: iterator */ |
48 | const lock_t* lock, /*!< in: lock to start from */ |
49 | ulint bit_no) /*!< in: record number in the |
50 | heap */ |
51 | { |
52 | ut_ad(lock_mutex_own()); |
53 | |
54 | iter->current_lock = lock; |
55 | |
56 | if (bit_no != ULINT_UNDEFINED) { |
57 | |
58 | iter->bit_no = bit_no; |
59 | } else { |
60 | |
61 | switch (lock_get_type_low(lock)) { |
62 | case LOCK_TABLE: |
63 | iter->bit_no = ULINT_UNDEFINED; |
64 | break; |
65 | case LOCK_REC: |
66 | iter->bit_no = lock_rec_find_set_bit(lock); |
67 | ut_a(iter->bit_no != ULINT_UNDEFINED); |
68 | break; |
69 | default: |
70 | ut_error; |
71 | } |
72 | } |
73 | } |
74 | |
75 | /*******************************************************************//** |
76 | Gets the previous lock in the lock queue, returns NULL if there are no |
77 | more locks (i.e. the current lock is the first one). The iterator is |
78 | receded (if not-NULL is returned). |
79 | @return previous lock or NULL */ |
80 | const lock_t* |
81 | lock_queue_iterator_get_prev( |
82 | /*=========================*/ |
83 | lock_queue_iterator_t* iter) /*!< in/out: iterator */ |
84 | { |
85 | const lock_t* prev_lock; |
86 | |
87 | ut_ad(lock_mutex_own()); |
88 | |
89 | switch (lock_get_type_low(iter->current_lock)) { |
90 | case LOCK_REC: |
91 | prev_lock = lock_rec_get_prev( |
92 | iter->current_lock, iter->bit_no); |
93 | break; |
94 | case LOCK_TABLE: |
95 | prev_lock = UT_LIST_GET_PREV( |
96 | un_member.tab_lock.locks, iter->current_lock); |
97 | break; |
98 | default: |
99 | ut_error; |
100 | } |
101 | |
102 | if (prev_lock != NULL) { |
103 | |
104 | iter->current_lock = prev_lock; |
105 | } |
106 | |
107 | return(prev_lock); |
108 | } |
109 | |