Commit a2bd936c authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-33161 Function pointer signature mismatch in LF_HASH

In cmake -DWITH_UBSAN=ON builds with clang but not with GCC,
-fsanitize=undefined will flag several runtime errors on
function pointer mismatch related to the lock-free hash table LF_HASH.

Let us use matching function signatures and remove function pointer
casts in order to avoid potential bugs due to undefined behaviour.

These errors could be caught at compilation time by
-Wcast-function-type-strict, which is available starting with clang-16,
but not available in any version of GCC as of now. The old GCC flag
-Wcast-function-type is enabled as part of -Wextra, but it specifically
does not catch these errors.

Reviewed by: Vladislav Vaintroub
parent 246c0b3a
......@@ -242,8 +242,10 @@ void lf_pinbox_put_pins(LF_PINS *pins)
return;
}
static int ptr_cmp(void **a, void **b)
static int ptr_cmp(const void *pa, const void *pb)
{
const void *const*a= pa;
const void *const*b= pb;
return *a < *b ? -1 : *a == *b ? 0 : 1;
}
......@@ -283,8 +285,10 @@ struct st_harvester {
callback forlf_dynarray_iterate:
scan all pins of all threads and accumulate all pins
*/
static int harvest_pins(LF_PINS *el, struct st_harvester *hv)
static int harvest_pins(void *e, void *h)
{
LF_PINS *el= e;
struct st_harvester *hv= h;
int i;
LF_PINS *el_end= el+MY_MIN(hv->npins, LF_DYNARRAY_LEVEL_LENGTH);
for (; el < el_end; el++)
......@@ -310,8 +314,9 @@ static int harvest_pins(LF_PINS *el, struct st_harvester *hv)
callback forlf_dynarray_iterate:
scan all pins of all threads and see if addr is present there
*/
static int match_pins(LF_PINS *el, void *addr)
static int match_pins(void *e, void *addr)
{
LF_PINS *el= e;
int i;
LF_PINS *el_end= el+LF_DYNARRAY_LEVEL_LENGTH;
for (; el < el_end; el++)
......@@ -352,13 +357,12 @@ static void lf_pinbox_real_free(LF_PINS *pins)
hv.granary= addr;
hv.npins= npins;
/* scan the dynarray and accumulate all pinned addresses */
lf_dynarray_iterate(&pinbox->pinarray,
(lf_dynarray_func)harvest_pins, &hv);
lf_dynarray_iterate(&pinbox->pinarray, harvest_pins, &hv);
npins= (int)(hv.granary-addr);
/* and sort them */
if (npins)
qsort(addr, npins, sizeof(void *), (qsort_cmp)ptr_cmp);
qsort(addr, npins, sizeof(void *), ptr_cmp);
}
}
#endif
......@@ -387,8 +391,7 @@ static void lf_pinbox_real_free(LF_PINS *pins)
}
else /* no alloca - no cookie. linear search here */
{
if (lf_dynarray_iterate(&pinbox->pinarray,
(lf_dynarray_func)match_pins, cur))
if (lf_dynarray_iterate(&pinbox->pinarray, match_pins, cur))
goto found;
}
}
......@@ -416,10 +419,11 @@ static void lf_pinbox_real_free(LF_PINS *pins)
'first' and 'last' are the ends of the linked list of nodes:
first->el->el->....->el->last. Use first==last to free only one element.
*/
static void alloc_free(uchar *first,
uchar volatile *last,
LF_ALLOCATOR *allocator)
static void alloc_free(void *f, void *l, void *alloc)
{
uchar *first= f;
uchar volatile *last= l;
LF_ALLOCATOR *allocator= alloc;
/*
we need a union here to access type-punned pointer reliably.
otherwise gcc -fstrict-aliasing will not see 'tmp' changed in the loop
......@@ -448,8 +452,7 @@ static void alloc_free(uchar *first,
*/
void lf_alloc_init(LF_ALLOCATOR *allocator, uint size, uint free_ptr_offset)
{
lf_pinbox_init(&allocator->pinbox, free_ptr_offset,
(lf_pinbox_free_func *)alloc_free, allocator);
lf_pinbox_init(&allocator->pinbox, free_ptr_offset, alloc_free, allocator);
allocator->top= 0;
allocator->mallocs= 0;
allocator->element_size= size;
......
......@@ -62,14 +62,10 @@ my_bool safe_mutex_deadlock_detector= 1; /* On by default */
static struct st_safe_mutex_create_info_t *safe_mutex_create_root= NULL;
#endif
static my_bool add_used_to_locked_mutex(safe_mutex_t *used_mutex,
safe_mutex_deadlock_t *locked_mutex);
static my_bool add_to_locked_mutex(safe_mutex_deadlock_t *locked_mutex,
safe_mutex_t *current_mutex);
static my_bool remove_from_locked_mutex(safe_mutex_t *mp,
safe_mutex_t *delete_mutex);
static my_bool remove_from_used_mutex(safe_mutex_deadlock_t *locked_mutex,
safe_mutex_t *mutex);
static my_bool add_used_to_locked_mutex(void *used, void *locked);
static my_bool add_to_locked_mutex(void *locked, void *current);
static my_bool remove_from_locked_mutex(void *m, void* remove);
static my_bool remove_from_used_mutex(void *locked, void *m);
static void print_deadlock_warning(safe_mutex_t *new_mutex,
safe_mutex_t *conflicting_mutex);
#endif
......@@ -373,8 +369,7 @@ int safe_mutex_lock(safe_mutex_t *mp, myf my_flags, const char *file,
are now locking (C) in B->C, then we would add C into
B->locked_mutex and A->locked_mutex
*/
my_hash_iterate(mutex_root->used_mutex,
(my_hash_walk_action) add_used_to_locked_mutex,
my_hash_iterate(mutex_root->used_mutex, add_used_to_locked_mutex,
deadlock);
/*
......@@ -654,12 +649,8 @@ void safe_mutex_free_deadlock_data(safe_mutex_t *mp)
if (!(mp->create_flags & MYF_NO_DEADLOCK_DETECTION) && mp->used_mutex != NULL)
{
pthread_mutex_lock(&THR_LOCK_mutex);
my_hash_iterate(mp->used_mutex,
(my_hash_walk_action) remove_from_locked_mutex,
mp);
my_hash_iterate(mp->locked_mutex,
(my_hash_walk_action) remove_from_used_mutex,
mp);
my_hash_iterate(mp->used_mutex, remove_from_locked_mutex, mp);
my_hash_iterate(mp->locked_mutex, remove_from_used_mutex, mp);
pthread_mutex_unlock(&THR_LOCK_mutex);
my_hash_free(mp->used_mutex);
......@@ -709,15 +700,15 @@ void safe_mutex_end(FILE *file __attribute__((unused)))
#endif /* SAFE_MUTEX_DETECT_DESTROY */
}
static my_bool add_used_to_locked_mutex(safe_mutex_t *used_mutex,
safe_mutex_deadlock_t *locked_mutex)
static my_bool add_used_to_locked_mutex(void *used, void *locked)
{
safe_mutex_t *used_mutex= used;
safe_mutex_deadlock_t *locked_mutex= locked;
/* Add mutex to all parent of the current mutex */
if (!locked_mutex->warning_only)
{
(void) my_hash_iterate(locked_mutex->mutex->locked_mutex,
(my_hash_walk_action) add_to_locked_mutex,
used_mutex);
add_to_locked_mutex, used_mutex);
/* mark that locked_mutex is locked after used_mutex */
(void) add_to_locked_mutex(locked_mutex, used_mutex);
}
......@@ -729,12 +720,13 @@ static my_bool add_used_to_locked_mutex(safe_mutex_t *used_mutex,
register that locked_mutex was locked after current_mutex
*/
static my_bool add_to_locked_mutex(safe_mutex_deadlock_t *locked_mutex,
safe_mutex_t *current_mutex)
static my_bool add_to_locked_mutex(void *locked, void *current)
{
safe_mutex_deadlock_t *locked_mutex= locked;
safe_mutex_t *current_mutex= current;
DBUG_ENTER("add_to_locked_mutex");
DBUG_PRINT("info", ("inserting 0x%lx into 0x%lx (id: %lu -> %lu)",
(ulong) locked_mutex, (long) current_mutex,
DBUG_PRINT("info", ("inserting %p into %p (id: %lu -> %lu)",
locked_mutex, current_mutex,
locked_mutex->id, current_mutex->id));
if (my_hash_insert(current_mutex->locked_mutex, (uchar*) locked_mutex))
{
......@@ -762,13 +754,14 @@ static my_bool add_to_locked_mutex(safe_mutex_deadlock_t *locked_mutex,
When counter goes to 0, we delete the safe_mutex_deadlock_t entry.
*/
static my_bool remove_from_locked_mutex(safe_mutex_t *mp,
safe_mutex_t *delete_mutex)
static my_bool remove_from_locked_mutex(void *m, void *remove)
{
safe_mutex_t *mp= m;
safe_mutex_t *delete_mutex= remove;
safe_mutex_deadlock_t *found;
DBUG_ENTER("remove_from_locked_mutex");
DBUG_PRINT("enter", ("delete_mutex: 0x%lx mutex: 0x%lx (id: %lu <- %lu)",
(ulong) delete_mutex, (ulong) mp,
DBUG_PRINT("enter", ("delete_mutex: %p mutex: %p (id: %lu <- %lu)",
delete_mutex, mp,
delete_mutex->id, mp->id));
found= (safe_mutex_deadlock_t *) my_hash_search(mp->locked_mutex,
......@@ -786,12 +779,13 @@ static my_bool remove_from_locked_mutex(safe_mutex_t *mp,
DBUG_RETURN(0);
}
static my_bool remove_from_used_mutex(safe_mutex_deadlock_t *locked_mutex,
safe_mutex_t *mutex)
static my_bool remove_from_used_mutex(void *locked, void *m)
{
safe_mutex_deadlock_t *locked_mutex= locked;
safe_mutex_t *mutex= m;
DBUG_ENTER("remove_from_used_mutex");
DBUG_PRINT("enter", ("delete_mutex: 0x%lx mutex: 0x%lx (id: %lu <- %lu)",
(ulong) mutex, (ulong) locked_mutex,
DBUG_PRINT("enter", ("delete_mutex: %p mutex: %p (id: %lu <- %lu)",
mutex, locked_mutex,
mutex->id, locked_mutex->id));
if (my_hash_delete(locked_mutex->mutex->used_mutex, (uchar*) mutex))
{
......
......@@ -424,8 +424,10 @@ static void wt_resource_destroy(uchar *arg)
It's called from lf_hash when an element is inserted.
*/
static void wt_resource_init(LF_HASH *hash __attribute__((unused)),
WT_RESOURCE *rc, WT_RESOURCE_ID *id)
void *resource, const void *ident)
{
WT_RESOURCE *rc= resource;
const WT_RESOURCE_ID *id= ident;
DBUG_ENTER("wt_resource_init");
rc->id= *id;
rc->waiter_count= 0;
......
......@@ -762,8 +762,10 @@ struct mdl_iterate_arg
};
static my_bool mdl_iterate_lock(MDL_lock *lock, mdl_iterate_arg *arg)
static my_bool mdl_iterate_lock(void *lk, void *a)
{
MDL_lock *lock= static_cast<MDL_lock*>(lk);
mdl_iterate_arg *arg= static_cast<mdl_iterate_arg*>(a);
/*
We can skip check for m_strategy here, becase m_granted
must be empty for such locks anyway.
......@@ -786,14 +788,13 @@ int mdl_iterate(mdl_iterator_callback callback, void *arg)
{
DBUG_ENTER("mdl_iterate");
mdl_iterate_arg argument= { callback, arg };
LF_PINS *pins= mdl_locks.get_pins();
int res= 1;
if (pins)
if (LF_PINS *pins= mdl_locks.get_pins())
{
res= mdl_iterate_lock(mdl_locks.m_backup_lock, &argument) ||
lf_hash_iterate(&mdl_locks.m_locks, pins,
(my_hash_walk_action) mdl_iterate_lock, &argument);
lf_hash_iterate(&mdl_locks.m_locks, pins, mdl_iterate_lock,
&argument);
lf_hash_put_pins(pins);
}
DBUG_RETURN(res);
......
......@@ -252,9 +252,10 @@ class list_open_tables_arg
};
static my_bool list_open_tables_callback(TDC_element *element,
list_open_tables_arg *arg)
static my_bool list_open_tables_callback(void *el, void *a)
{
TDC_element *element= static_cast<TDC_element*>(el);
list_open_tables_arg *arg= static_cast<list_open_tables_arg*>(a);
const Lex_ident_db
db= Lex_ident_db(Lex_cstring_strlen((const char*) element->m_key));
const char *table_name= db.str + db.length + 1;
......@@ -302,8 +303,7 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd,
DBUG_ENTER("list_open_tables");
list_open_tables_arg argument(thd, db, wild);
if (tdc_iterate(thd, (my_hash_walk_action) list_open_tables_callback,
&argument, true))
if (tdc_iterate(thd, list_open_tables_callback, &argument, true))
DBUG_RETURN(0);
DBUG_RETURN(argument.open_list);
......@@ -462,9 +462,10 @@ struct tc_collect_arg
flush_tables_type flush_type;
};
static my_bool tc_collect_used_shares(TDC_element *element,
tc_collect_arg *arg)
static my_bool tc_collect_used_shares(void *el, void *a)
{
TDC_element *element= static_cast<TDC_element*>(el);
tc_collect_arg *arg= static_cast<tc_collect_arg*>(a);
my_bool result= FALSE;
DYNAMIC_ARRAY *shares= &arg->shares;
......@@ -573,8 +574,7 @@ bool flush_tables(THD *thd, flush_tables_type flag)
my_init_dynamic_array(PSI_INSTRUMENT_ME, &collect_arg.shares,
sizeof(TABLE_SHARE*), 100, 100, MYF(0));
collect_arg.flush_type= flag;
if (tdc_iterate(thd, (my_hash_walk_action) tc_collect_used_shares,
&collect_arg, true))
if (tdc_iterate(thd, tc_collect_used_shares, &collect_arg, true))
{
/* Release already collected shares */
for (uint i= 0 ; i < collect_arg.shares.elements ; i++)
......
......@@ -133,9 +133,10 @@ struct close_cached_connection_tables_arg
};
static my_bool close_cached_connection_tables_callback(
TDC_element *element, close_cached_connection_tables_arg *arg)
static my_bool close_cached_connection_tables_callback(void *el, void *a)
{
TDC_element *element= static_cast<TDC_element*>(el);
auto arg= static_cast<close_cached_connection_tables_arg*>(a);
TABLE_LIST *tmp;
mysql_mutex_lock(&element->LOCK_table_share);
......@@ -188,9 +189,7 @@ static bool close_cached_connection_tables(THD *thd, LEX_CSTRING *connection)
close_cached_connection_tables_arg argument= { thd, connection, 0 };
DBUG_ENTER("close_cached_connections");
if (tdc_iterate(thd,
(my_hash_walk_action) close_cached_connection_tables_callback,
&argument))
if (tdc_iterate(thd, close_cached_connection_tables_callback, &argument))
DBUG_RETURN(true);
DBUG_RETURN(argument.tables ?
......
......@@ -116,7 +116,7 @@ static void print_cached_tables(void)
/* purecov: begin tested */
puts("DB Table Version Thread Open Lock");
tdc_iterate(0, (my_hash_walk_action) print_cached_tables_callback, NULL, true);
tdc_iterate(0, print_cached_tables_callback, NULL, true);
fflush(stdout);
/* purecov: end */
......
......@@ -309,7 +309,7 @@ void tc_purge()
{
Share_free_tables::List purge_tables;
tdc_iterate(0, (my_hash_walk_action) tc_purge_callback, &purge_tables);
tdc_iterate(0, tc_purge_callback, &purge_tables);
while (auto table= purge_tables.pop_front())
intern_close_table(table);
}
......@@ -1126,7 +1126,7 @@ struct eliminate_duplicates_arg
static uchar *eliminate_duplicates_get_key(const uchar *element, size_t *length,
my_bool not_used __attribute__((unused)))
my_bool)
{
LEX_STRING *key= (LEX_STRING *) element;
*length= key->length;
......@@ -1134,9 +1134,10 @@ static uchar *eliminate_duplicates_get_key(const uchar *element, size_t *length,
}
static my_bool eliminate_duplicates(TDC_element *element,
eliminate_duplicates_arg *arg)
static my_bool eliminate_duplicates(void *el, void *a)
{
TDC_element *element= static_cast<TDC_element*>(el);
eliminate_duplicates_arg *arg= static_cast<eliminate_duplicates_arg*>(a);
LEX_STRING *key= (LEX_STRING *) alloc_root(&arg->root, sizeof(LEX_STRING));
if (!key || !(key->str= (char*) memdup_root(&arg->root, element->m_key,
......@@ -1182,7 +1183,7 @@ int tdc_iterate(THD *thd, my_hash_walk_action action, void *argument,
hash_flags);
no_dups_argument.action= action;
no_dups_argument.argument= argument;
action= (my_hash_walk_action) eliminate_duplicates;
action= eliminate_duplicates;
argument= &no_dups_argument;
}
......
......@@ -126,10 +126,11 @@ class XID_cache_element
}
return true;
}
static void lf_hash_initializer(LF_HASH *hash __attribute__((unused)),
XID_cache_element *element,
XID_cache_insert_element *new_element)
static void lf_hash_initializer(LF_HASH *, void *el, const void *ie)
{
XID_cache_element *element= static_cast<XID_cache_element*>(el);
XID_cache_insert_element *new_element=
static_cast<XID_cache_insert_element*>(const_cast<void*>(ie));
DBUG_ASSERT(!element->is_set(ACQUIRED | RECOVERED));
element->rm_error= 0;
element->xa_state= new_element->xa_state;
......@@ -146,11 +147,11 @@ class XID_cache_element
DBUG_ASSERT(!reinterpret_cast<XID_cache_element*>(ptr + LF_HASH_OVERHEAD)
->is_set(ACQUIRED));
}
static uchar *key(const XID_cache_element *element, size_t *length,
my_bool not_used __attribute__((unused)))
static uchar *key(const unsigned char *el, size_t *length, my_bool)
{
*length= element->xid.key_length();
return element->xid.key();
const XID &xid= reinterpret_cast<const XID_cache_element*>(el)->xid;
*length= xid.key_length();
return xid.key();
}
};
......@@ -221,11 +222,10 @@ void xid_cache_init()
{
xid_cache_inited= true;
lf_hash_init(&xid_cache, sizeof(XID_cache_element), LF_HASH_UNIQUE, 0, 0,
(my_hash_get_key) XID_cache_element::key, &my_charset_bin);
XID_cache_element::key, &my_charset_bin);
xid_cache.alloc.constructor= XID_cache_element::lf_alloc_constructor;
xid_cache.alloc.destructor= XID_cache_element::lf_alloc_destructor;
xid_cache.initializer=
(lf_hash_initializer) XID_cache_element::lf_hash_initializer;
xid_cache.initializer= XID_cache_element::lf_hash_initializer;
}
......@@ -331,9 +331,10 @@ struct xid_cache_iterate_arg
void *argument;
};
static my_bool xid_cache_iterate_callback(XID_cache_element *element,
xid_cache_iterate_arg *arg)
static my_bool xid_cache_iterate_callback(void *el, void *a)
{
XID_cache_element *element= static_cast<XID_cache_element*>(el);
xid_cache_iterate_arg *arg= static_cast<xid_cache_iterate_arg*>(a);
my_bool res= FALSE;
if (element->lock())
{
......@@ -348,8 +349,7 @@ static int xid_cache_iterate(THD *thd, my_hash_walk_action action, void *arg)
xid_cache_iterate_arg argument= { action, arg };
return thd->fix_xid_hash_pins() ? -1 :
lf_hash_iterate(&xid_cache, thd->xid_hash_pins,
(my_hash_walk_action) xid_cache_iterate_callback,
&argument);
xid_cache_iterate_callback, &argument);
}
......@@ -1039,17 +1039,19 @@ static my_bool xa_recover_callback(XID_cache_element *xs, Protocol *protocol,
}
static my_bool xa_recover_callback_short(XID_cache_element *xs,
Protocol *protocol)
static my_bool xa_recover_callback_short(void *x, void *p)
{
XID_cache_element *xs= static_cast<XID_cache_element*>(x);
Protocol *protocol= static_cast<Protocol*>(p);
return xa_recover_callback(xs, protocol, xs->xid.data,
xs->xid.gtrid_length + xs->xid.bqual_length, &my_charset_bin);
}
static my_bool xa_recover_callback_verbose(XID_cache_element *xs,
Protocol *protocol)
static my_bool xa_recover_callback_verbose(void *x, void *p)
{
XID_cache_element *xs= static_cast<XID_cache_element*>(x);
Protocol *protocol= static_cast<Protocol*>(p);
char buf[SQL_XIDSIZE];
uint len= get_sql_xid(&xs->xid, buf);
return xa_recover_callback(xs, protocol, buf, len,
......@@ -1082,13 +1084,13 @@ bool mysql_xa_recover(THD *thd)
{
len= SQL_XIDSIZE;
cs= &my_charset_utf8mb3_general_ci;
action= (my_hash_walk_action) xa_recover_callback_verbose;
action= xa_recover_callback_verbose;
}
else
{
len= XIDDATASIZE;
cs= &my_charset_bin;
action= (my_hash_walk_action) xa_recover_callback_short;
action= xa_recover_callback_short;
}
field_list.push_back(new (mem_root)
......
......@@ -453,10 +453,10 @@ class rw_trx_hash_t
not accessible by concurrent threads.
*/
static void rw_trx_hash_initializer(LF_HASH *,
rw_trx_hash_element_t *element,
trx_t *trx)
static void rw_trx_hash_initializer(LF_HASH *, void *el, const void *t)
{
rw_trx_hash_element_t *element= static_cast<rw_trx_hash_element_t*>(el);
trx_t *trx= static_cast<trx_t*>(const_cast<void*>(t));
ut_ad(element->trx == 0);
element->trx= trx;
element->id= trx->id;
......@@ -470,7 +470,7 @@ class rw_trx_hash_t
Pins are used to protect object from being destroyed or reused. They are
normally stored in trx object for quick access. If caller doesn't have trx
available, we try to get it using currnet_trx(). If caller doesn't have trx
available, we try to get it using current_trx(). If caller doesn't have trx
at all, temporary pins are allocated.
*/
......@@ -496,9 +496,10 @@ class rw_trx_hash_t
template <typename T>
static my_bool eliminate_duplicates(rw_trx_hash_element_t *element,
eliminate_duplicates_arg<T> *arg)
static my_bool eliminate_duplicates(void *el, void *a)
{
rw_trx_hash_element_t *element= static_cast<rw_trx_hash_element_t*>(el);
auto arg= static_cast<eliminate_duplicates_arg<T>*>(a);
for (trx_ids_t::iterator it= arg->ids.begin(); it != arg->ids.end(); it++)
{
if (*it == element->id)
......@@ -524,17 +525,17 @@ class rw_trx_hash_t
}
template <typename T> struct debug_iterator_arg
struct debug_iterator_arg
{
walk_action<T> *action;
T *argument;
my_hash_walk_action action;
void *argument;
};
template <typename T>
static my_bool debug_iterator(rw_trx_hash_element_t *element,
debug_iterator_arg<T> *arg)
static my_bool debug_iterator(void *el, void *a)
{
rw_trx_hash_element_t *element= static_cast<rw_trx_hash_element_t*>(el);
debug_iterator_arg *arg= static_cast<debug_iterator_arg*>(a);
mutex_enter(&element->mutex);
if (element->trx)
validate_element(element->trx);
......@@ -744,7 +745,7 @@ class rw_trx_hash_t
@param caller_trx used to get/set pins
@param action called for every element in hash
@param argument opque argument passed to action
@param argument opaque argument passed to action
May return the same element multiple times if hash is under contention.
If caller doesn't like to see the same transaction multiple times, it has
......@@ -767,28 +768,24 @@ class rw_trx_hash_t
@retval 1 iteration was interrupted (action returned 1)
*/
template <typename T>
int iterate(trx_t *caller_trx, walk_action<T> *action, T *argument= nullptr)
int iterate(trx_t *caller_trx, my_hash_walk_action action,
void *argument= nullptr)
{
LF_PINS *pins= caller_trx ? get_pins(caller_trx) : lf_hash_get_pins(&hash);
ut_a(pins);
#ifdef UNIV_DEBUG
debug_iterator_arg<T> debug_arg= { action, argument };
action= reinterpret_cast<decltype(action)>(debug_iterator<T>);
argument= reinterpret_cast<T*>(&debug_arg);
debug_iterator_arg debug_arg= { action, argument };
action= debug_iterator;
argument= reinterpret_cast<void*>(&debug_arg);
#endif
int res= lf_hash_iterate(&hash, pins,
reinterpret_cast<my_hash_walk_action>(action),
const_cast<void*>(static_cast<const void*>
(argument)));
int res= lf_hash_iterate(&hash, pins, action, argument);
if (!caller_trx)
lf_hash_put_pins(pins);
return res;
}
template <typename T>
int iterate(walk_action<T> *action, T *argument= nullptr)
int iterate(my_hash_walk_action action, void *argument= nullptr)
{
return iterate(current_trx(), action, argument);
}
......@@ -1176,9 +1173,10 @@ class trx_sys_t
}
private:
static my_bool get_min_trx_id_callback(rw_trx_hash_element_t *element,
trx_id_t *id)
static my_bool get_min_trx_id_callback(void *el, void *i)
{
auto element= static_cast<rw_trx_hash_element_t *>(el);
auto id= static_cast<trx_id_t*>(i);
if (element->id < *id)
{
mutex_enter(&element->mutex);
......@@ -1200,9 +1198,10 @@ class trx_sys_t
};
static my_bool copy_one_id(rw_trx_hash_element_t *element,
snapshot_ids_arg *arg)
static my_bool copy_one_id(void* el, void *a)
{
auto element= static_cast<const rw_trx_hash_element_t *>(el);
auto arg= static_cast<snapshot_ids_arg*>(a);
if (element->id < arg->m_id)
{
trx_id_t no= element->no;
......
......@@ -5234,8 +5234,9 @@ static void lock_rec_block_validate(const page_id_t page_id)
}
static my_bool lock_validate_table_locks(rw_trx_hash_element_t *element, void*)
static my_bool lock_validate_table_locks(void *el, void*)
{
rw_trx_hash_element_t *element= static_cast<rw_trx_hash_element_t*>(el);
ut_ad(lock_mutex_own());
mutex_enter(&element->mutex);
if (element->trx)
......@@ -5499,10 +5500,10 @@ struct lock_rec_other_trx_holds_expl_arg
};
static my_bool lock_rec_other_trx_holds_expl_callback(
rw_trx_hash_element_t *element,
lock_rec_other_trx_holds_expl_arg *arg)
static my_bool lock_rec_other_trx_holds_expl_callback(void *el, void *a)
{
auto element= static_cast<rw_trx_hash_element_t*>(el);
auto arg= static_cast<lock_rec_other_trx_holds_expl_arg*>(a);
mutex_enter(&element->mutex);
if (element->trx)
{
......@@ -6325,13 +6326,14 @@ lock_table_get_n_locks(
/**
Do an exhaustive check for any locks (table or rec) against the table.
@param[in] table check if there are any locks held on records in this table
or on the table itself
@param t check if there are any locks held on records in this table
or on the table itself
*/
static my_bool lock_table_locks_lookup(rw_trx_hash_element_t *element,
const dict_table_t *table)
static my_bool lock_table_locks_lookup(void *el, void *t)
{
auto element= static_cast<rw_trx_hash_element_t*>(el);
const dict_table_t *table= static_cast<const dict_table_t*>(t);
ut_ad(lock_mutex_own());
mutex_enter(&element->mutex);
if (element->trx)
......@@ -6381,7 +6383,9 @@ lock_table_has_locks(
#ifdef UNIV_DEBUG
if (!has_locks) {
trx_sys.rw_trx_hash.iterate(lock_table_locks_lookup, table);
trx_sys.rw_trx_hash.iterate(lock_table_locks_lookup,
const_cast<void*>
(static_cast<const void*>(table)));
}
#endif /* UNIV_DEBUG */
......
......@@ -2053,9 +2053,9 @@ static my_bool trx_recover_for_mysql_callback(rw_trx_hash_element_t *element,
}
static my_bool trx_recover_reset_callback(rw_trx_hash_element_t *element,
void*)
static my_bool trx_recover_reset_callback(void *el, void*)
{
rw_trx_hash_element_t *element= static_cast<rw_trx_hash_element_t*>(el);
mutex_enter(&element->mutex);
if (trx_t *trx= element->trx)
{
......@@ -2107,9 +2107,10 @@ struct trx_get_trx_by_xid_callback_arg
};
static my_bool trx_get_trx_by_xid_callback(rw_trx_hash_element_t *element,
trx_get_trx_by_xid_callback_arg *arg)
static my_bool trx_get_trx_by_xid_callback(void *el, void *a)
{
auto element= static_cast<rw_trx_hash_element_t*>(el);
auto arg= static_cast<trx_get_trx_by_xid_callback_arg*>(a);
my_bool found= 0;
mutex_enter(&element->mutex);
if (trx_t *trx= element->trx)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment