diff --git a/include/thread_local_service.h b/include/thread_local_service.h new file mode 100644 index 00000000000..ef9ca815446 --- /dev/null +++ b/include/thread_local_service.h @@ -0,0 +1,33 @@ +/* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2.0, + as published by the Free Software Foundation. + + This program is also distributed with certain software (including + but not limited to OpenSSL) that is licensed under separate terms, + as designated in a particular file or component or in included license + documentation. The authors of MySQL hereby grant you an additional + permission to link the program and your derivative works with the + separately licensed software that they have included with MySQL. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License, version 2.0, for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef THREAD_LOCAL_SERVICE_H_INCLUDED +#define THREAD_LOCAL_SERVICE_H_INCLUDED + +typedef void (*tls_destructor_callback)(void); + +extern void tls_thread_init(); + +extern void tls_thread_end(); + +extern void register_tls_destructor(tls_destructor_callback func); +#endif diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index 4852c1f53c5..898843e9c91 100644 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -110,6 +110,7 @@ SET(MYSYS_SOURCES thr_rwlock.cc tree.cc typelib.cc + thread_local_service.cc ) IF (WIN32) diff --git a/mysys/my_thr_init.cc b/mysys/my_thr_init.cc index b041de35c42..62df10ba383 100644 --- a/mysys/my_thr_init.cc +++ b/mysys/my_thr_init.cc @@ -55,6 +55,8 @@ #include "mysys_err.h" #include "thr_mutex.h" +#include "thread_local_service.h" + static bool my_thread_global_init_done = false; #ifndef DBUG_OFF static uint THR_thread_count = 0; @@ -289,6 +291,8 @@ extern "C" bool my_thread_init() { set_mysys_thread_var(tmp); #endif + tls_thread_init(); + return false; } @@ -337,6 +341,8 @@ extern "C" void my_thread_end() { } set_mysys_thread_var(NULL); #endif + + tls_thread_end(); } int my_errno() { return THR_myerrno; } diff --git a/mysys/thread_local_service.cc b/mysys/thread_local_service.cc new file mode 100644 index 00000000000..a5b80176379 --- /dev/null +++ b/mysys/thread_local_service.cc @@ -0,0 +1,56 @@ +/* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2.0, + as published by the Free Software Foundation. + + This program is also distributed with certain software (including + but not limited to OpenSSL) that is licensed under separate terms, + as designated in a particular file or component or in included license + documentation. The authors of MySQL hereby grant you an additional + permission to link the program and your derivative works with the + separately licensed software that they have included with MySQL. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License, version 2.0, for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include + +#include "thread_local_service.h" + + +static thread_local std::vector *tls_callback_array = + nullptr; + +void iterate_tls_destructor() { + for (auto it = tls_callback_array->cbegin(); it != tls_callback_array->cend(); + ++it) { + tls_destructor_callback func = *it; + (*func)(); + } +} + +void tls_thread_init() { + if (tls_callback_array == nullptr) + tls_callback_array = new std::vector(); +} + +void tls_thread_end() { + if (tls_callback_array != nullptr) { + iterate_tls_destructor(); + tls_callback_array->clear(); + delete tls_callback_array; + tls_callback_array = nullptr; + } +} + +void register_tls_destructor(tls_destructor_callback destructor) { + tls_callback_array->emplace_back(destructor); +} + diff --git a/storage/temptable/include/temptable/allocator.h b/storage/temptable/include/temptable/allocator.h index 814e1ef213a..83badf4ef8b 100644 --- a/storage/temptable/include/temptable/allocator.h +++ b/storage/temptable/include/temptable/allocator.h @@ -72,6 +72,8 @@ https://msdn.microsoft.com/en-us/library/windows/desktop/aa366891(v=vs.85).aspx #include "storage/temptable/include/temptable/result.h" #include "storage/temptable/include/temptable/misc.h" +#include "thread_local_service.h" + #ifdef HAVE_LIBNUMA #define TEMPTABLE_USE_LINUX_NUMA #endif /* HAVE_LIBNUMA */ @@ -508,6 +510,8 @@ inline bool Allocator::operator!=(const Allocator &rhs) const { return !(*this == rhs); } +inline void allocator_tls_destructor() { Allocator::end_thread(); } + template inline T *Allocator::allocate(size_t n_elements) { static_assert(sizeof(T) > 0, "Zero sized objects are not supported"); @@ -528,6 +532,7 @@ inline T *Allocator::allocate(size_t n_elements) { if (shared_block == nullptr) { shared_block = block_create(size_bytes); + register_tls_destructor(allocator_tls_destructor); b = shared_block; } else if (block_can_accommodate(shared_block, size_bytes)) { b = shared_block;