summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-02-05 17:03:41 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2019-02-05 17:03:41 +0200
commit5eb3e4d83c793713aabe2e09b8cd8069f46f2f0e (patch)
tree368533a4ad1f3756897928014baeec7edb4aae04
parent4c490d6df63695dc97b2c808e59954e6877d3a51 (diff)
downloadmariadb-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.cc147
-rw-r--r--storage/xtradb/handler/i_s.cc147
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);
}