diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-02-05 17:03:41 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-02-05 17:03:41 +0200 |
commit | 5eb3e4d83c793713aabe2e09b8cd8069f46f2f0e (patch) | |
tree | 368533a4ad1f3756897928014baeec7edb4aae04 | |
parent | 4c490d6df63695dc97b2c808e59954e6877d3a51 (diff) | |
download | mariadb-git-5eb3e4d83c793713aabe2e09b8cd8069f46f2f0e.tar.gz |
MDEV-15798 Mutex leak on accessing INFORMATION_SCHEMA.INNODB_MUTEXES
i_s_innodb_mutexes_fill_table(): Use the C++ RAII pattern
to ensure that the mutexes are released if an OK()
macro returns from the function prematurely.
-rw-r--r-- | storage/innobase/handler/i_s.cc | 147 | ||||
-rw-r--r-- | storage/xtradb/handler/i_s.cc | 147 |
2 files changed, 174 insertions, 120 deletions
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 5b471c8cd05..ed6133c172f 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. +Copyright (c) 2014, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -8819,78 +8819,105 @@ i_s_innodb_mutexes_fill_table( DBUG_RETURN(0); } - mutex_enter(&mutex_list_mutex); + { + struct Locking + { + Locking() { mutex_enter(&mutex_list_mutex); } + ~Locking() { mutex_exit(&mutex_list_mutex); } + } locking; + + for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL; + mutex = UT_LIST_GET_NEXT(list, mutex)) { + if (mutex->count_os_wait == 0) { + continue; + } - for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL; - mutex = UT_LIST_GET_NEXT(list, mutex)) { - if (mutex->count_os_wait == 0) { - continue; - } + if (buf_pool_is_block_mutex(mutex)) { + block_mutex = mutex; + block_mutex_oswait_count + += mutex->count_os_wait; + continue; + } - if (buf_pool_is_block_mutex(mutex)) { - block_mutex = mutex; - block_mutex_oswait_count += mutex->count_os_wait; - continue; + OK(field_store_string(fields[MUTEXES_NAME], + mutex->cmutex_name)); + OK(field_store_string( + fields[MUTEXES_CREATE_FILE], + innobase_basename(mutex->cfile_name))); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + mutex->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + mutex->count_os_wait)); + OK(schema_table_store_record(thd, tables->table)); } - OK(field_store_string(fields[MUTEXES_NAME], mutex->cmutex_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], innobase_basename(mutex->cfile_name))); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], mutex->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)mutex->count_os_wait)); - OK(schema_table_store_record(thd, tables->table)); - } - - if (block_mutex) { - char buf1[IO_SIZE]; - - my_snprintf(buf1, sizeof buf1, "combined %s", - innobase_basename(block_mutex->cfile_name)); - - OK(field_store_string(fields[MUTEXES_NAME], block_mutex->cmutex_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1)); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], block_mutex->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)block_mutex_oswait_count)); - OK(schema_table_store_record(thd, tables->table)); + if (block_mutex) { + char buf1[IO_SIZE]; + + my_snprintf(buf1, sizeof buf1, "combined %s", + innobase_basename(block_mutex->cfile_name)); + + OK(field_store_string(fields[MUTEXES_NAME], + block_mutex->cmutex_name)); + OK(field_store_string(fields[MUTEXES_CREATE_FILE], + buf1)); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + block_mutex->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + block_mutex_oswait_count)); + OK(schema_table_store_record(thd, tables->table)); + } } - mutex_exit(&mutex_list_mutex); + { + struct Locking + { + Locking() { mutex_enter(&rw_lock_list_mutex); } + ~Locking() { mutex_exit(&rw_lock_list_mutex); } + } locking; + + for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL; + lock = UT_LIST_GET_NEXT(list, lock)) { + if (lock->count_os_wait == 0) { + continue; + } - mutex_enter(&rw_lock_list_mutex); + if (buf_pool_is_block_lock(lock)) { + block_lock = lock; + block_lock_oswait_count += lock->count_os_wait; + continue; + } - for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL; - lock = UT_LIST_GET_NEXT(list, lock)) { - if (lock->count_os_wait == 0) { - continue; + OK(field_store_string(fields[MUTEXES_NAME], + lock->lock_name)); + OK(field_store_string( + fields[MUTEXES_CREATE_FILE], + innobase_basename(lock->cfile_name))); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + lock->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + lock->count_os_wait)); + OK(schema_table_store_record(thd, tables->table)); } - if (buf_pool_is_block_lock(lock)) { - block_lock = lock; - block_lock_oswait_count += lock->count_os_wait; - continue; + if (block_lock) { + char buf1[IO_SIZE]; + + my_snprintf(buf1, sizeof buf1, "combined %s", + innobase_basename(block_lock->cfile_name)); + + OK(field_store_string(fields[MUTEXES_NAME], + block_lock->lock_name)); + OK(field_store_string(fields[MUTEXES_CREATE_FILE], + buf1)); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + block_lock->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + block_lock_oswait_count)); + OK(schema_table_store_record(thd, tables->table)); } - - OK(field_store_string(fields[MUTEXES_NAME], lock->lock_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], innobase_basename(lock->cfile_name))); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], lock->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)lock->count_os_wait)); - OK(schema_table_store_record(thd, tables->table)); } - if (block_lock) { - char buf1[IO_SIZE]; - - my_snprintf(buf1, sizeof buf1, "combined %s", - innobase_basename(block_lock->cfile_name)); - - OK(field_store_string(fields[MUTEXES_NAME], block_lock->lock_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1)); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], block_lock->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)block_lock_oswait_count)); - OK(schema_table_store_record(thd, tables->table)); - } - - mutex_exit(&rw_lock_list_mutex); - DBUG_RETURN(0); } diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index 201d2ad13a5..5c2d65e5799 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. +Copyright (c) 2014, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -9120,78 +9120,105 @@ i_s_innodb_mutexes_fill_table( DBUG_RETURN(0); } - mutex_enter(&mutex_list_mutex); + { + struct Locking + { + Locking() { mutex_enter(&mutex_list_mutex); } + ~Locking() { mutex_exit(&mutex_list_mutex); } + } locking; + + for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL; + mutex = UT_LIST_GET_NEXT(list, mutex)) { + if (mutex->count_os_wait == 0) { + continue; + } - for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL; - mutex = UT_LIST_GET_NEXT(list, mutex)) { - if (mutex->count_os_wait == 0) { - continue; - } + if (buf_pool_is_block_mutex(mutex)) { + block_mutex = mutex; + block_mutex_oswait_count + += mutex->count_os_wait; + continue; + } - if (buf_pool_is_block_mutex(mutex)) { - block_mutex = mutex; - block_mutex_oswait_count += mutex->count_os_wait; - continue; + OK(field_store_string(fields[MUTEXES_NAME], + mutex->cmutex_name)); + OK(field_store_string( + fields[MUTEXES_CREATE_FILE], + innobase_basename(mutex->cfile_name))); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + mutex->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + mutex->count_os_wait)); + OK(schema_table_store_record(thd, tables->table)); } - OK(field_store_string(fields[MUTEXES_NAME], mutex->cmutex_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], innobase_basename(mutex->cfile_name))); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], mutex->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)mutex->count_os_wait)); - OK(schema_table_store_record(thd, tables->table)); - } - - if (block_mutex) { - char buf1[IO_SIZE]; - - my_snprintf(buf1, sizeof buf1, "combined %s", - innobase_basename(block_mutex->cfile_name)); - - OK(field_store_string(fields[MUTEXES_NAME], block_mutex->cmutex_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1)); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], block_mutex->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)block_mutex_oswait_count)); - OK(schema_table_store_record(thd, tables->table)); + if (block_mutex) { + char buf1[IO_SIZE]; + + my_snprintf(buf1, sizeof buf1, "combined %s", + innobase_basename(block_mutex->cfile_name)); + + OK(field_store_string(fields[MUTEXES_NAME], + block_mutex->cmutex_name)); + OK(field_store_string(fields[MUTEXES_CREATE_FILE], + buf1)); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + block_mutex->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + block_mutex_oswait_count)); + OK(schema_table_store_record(thd, tables->table)); + } } - mutex_exit(&mutex_list_mutex); + { + struct Locking + { + Locking() { mutex_enter(&rw_lock_list_mutex); } + ~Locking() { mutex_exit(&rw_lock_list_mutex); } + } locking; + + for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL; + lock = UT_LIST_GET_NEXT(list, lock)) { + if (lock->count_os_wait == 0) { + continue; + } - mutex_enter(&rw_lock_list_mutex); + if (buf_pool_is_block_lock(lock)) { + block_lock = lock; + block_lock_oswait_count += lock->count_os_wait; + continue; + } - for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL; - lock = UT_LIST_GET_NEXT(list, lock)) { - if (lock->count_os_wait == 0) { - continue; + OK(field_store_string(fields[MUTEXES_NAME], + lock->lock_name)); + OK(field_store_string( + fields[MUTEXES_CREATE_FILE], + innobase_basename(lock->cfile_name))); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + lock->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + lock->count_os_wait)); + OK(schema_table_store_record(thd, tables->table)); } - if (buf_pool_is_block_lock(lock)) { - block_lock = lock; - block_lock_oswait_count += lock->count_os_wait; - continue; + if (block_lock) { + char buf1[IO_SIZE]; + + my_snprintf(buf1, sizeof buf1, "combined %s", + innobase_basename(block_lock->cfile_name)); + + OK(field_store_string(fields[MUTEXES_NAME], + block_lock->lock_name)); + OK(field_store_string(fields[MUTEXES_CREATE_FILE], + buf1)); + OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], + block_lock->cline)); + OK(field_store_ulint(fields[MUTEXES_OS_WAITS], + block_lock_oswait_count)); + OK(schema_table_store_record(thd, tables->table)); } - - OK(field_store_string(fields[MUTEXES_NAME], lock->lock_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], innobase_basename(lock->cfile_name))); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], lock->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)lock->count_os_wait)); - OK(schema_table_store_record(thd, tables->table)); - } - - if (block_lock) { - char buf1[IO_SIZE]; - - my_snprintf(buf1, sizeof buf1, "combined %s", - innobase_basename(block_lock->cfile_name)); - - OK(field_store_string(fields[MUTEXES_NAME], block_lock->lock_name)); - OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1)); - OK(field_store_ulint(fields[MUTEXES_CREATE_LINE], block_lock->cline)); - OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)block_lock_oswait_count)); - OK(schema_table_store_record(thd, tables->table)); } - mutex_exit(&rw_lock_list_mutex); - DBUG_RETURN(0); } |