summaryrefslogtreecommitdiff
path: root/mysql/mysys/my_thr_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'mysql/mysys/my_thr_init.c')
-rw-r--r--mysql/mysys/my_thr_init.c459
1 files changed, 0 insertions, 459 deletions
diff --git a/mysql/mysys/my_thr_init.c b/mysql/mysys/my_thr_init.c
deleted file mode 100644
index db0881c..0000000
--- a/mysql/mysys/my_thr_init.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/* Copyright (c) 2000, 2015, 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 as published by
- the Free Software Foundation; version 2 of the License.
-
- 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 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 */
-
-/*
- Functions to handle initializating and allocationg of all mysys & debug
- thread variables.
-*/
-
-#include "mysys_priv.h"
-#include "my_sys.h"
-#include <m_string.h>
-#include <signal.h>
-#include "my_thread_local.h"
-
-static my_bool THR_KEY_mysys_initialized= FALSE;
-static my_bool my_thread_global_init_done= FALSE;
-#ifndef DBUG_OFF
-static uint THR_thread_count= 0;
-static uint my_thread_end_wait_time= 5;
-static my_thread_id thread_id= 0;
-static thread_local_key_t THR_KEY_mysys;
-#endif
-static thread_local_key_t THR_KEY_myerrno;
-#ifdef _WIN32
-static thread_local_key_t THR_KEY_winerrno;
-#endif
-
-mysql_mutex_t THR_LOCK_malloc, THR_LOCK_open,
- THR_LOCK_lock, THR_LOCK_myisam, THR_LOCK_heap,
- THR_LOCK_net, THR_LOCK_charset,
- THR_LOCK_myisam_mmap;
-#ifndef DBUG_OFF
-mysql_mutex_t THR_LOCK_threads;
-mysql_cond_t THR_COND_threads;
-#endif
-
-#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
-native_mutexattr_t my_fast_mutexattr;
-#endif
-#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
-native_mutexattr_t my_errorcheck_mutexattr;
-#endif
-#ifdef _WIN32
-static void install_sigabrt_handler();
-#endif
-
-#ifndef DBUG_OFF
-struct st_my_thread_var
-{
- my_thread_id id;
- struct _db_code_state_ *dbug;
-};
-
-static struct st_my_thread_var *mysys_thread_var()
-{
- DBUG_ASSERT(THR_KEY_mysys_initialized);
- return (struct st_my_thread_var*)my_get_thread_local(THR_KEY_mysys);
-}
-
-
-static int set_mysys_thread_var(struct st_my_thread_var *mysys_var)
-{
- DBUG_ASSERT(THR_KEY_mysys_initialized);
- return my_set_thread_local(THR_KEY_mysys, mysys_var);
-}
-#endif
-
-
-/**
- Re-initialize components initialized early with @c my_thread_global_init.
- Some mutexes were initialized before the instrumentation.
- Destroy + create them again, now that the instrumentation
- is in place.
- This is safe, since this function() is called before creating new threads,
- so the mutexes are not in use.
-*/
-
-void my_thread_global_reinit()
-{
- DBUG_ASSERT(my_thread_global_init_done);
-
-#ifdef HAVE_PSI_INTERFACE
- my_init_mysys_psi_keys();
-#endif
-
- mysql_mutex_destroy(&THR_LOCK_heap);
- mysql_mutex_init(key_THR_LOCK_heap, &THR_LOCK_heap, MY_MUTEX_INIT_FAST);
-
- mysql_mutex_destroy(&THR_LOCK_net);
- mysql_mutex_init(key_THR_LOCK_net, &THR_LOCK_net, MY_MUTEX_INIT_FAST);
-
- mysql_mutex_destroy(&THR_LOCK_myisam);
- mysql_mutex_init(key_THR_LOCK_myisam, &THR_LOCK_myisam, MY_MUTEX_INIT_SLOW);
-
- mysql_mutex_destroy(&THR_LOCK_malloc);
- mysql_mutex_init(key_THR_LOCK_malloc, &THR_LOCK_malloc, MY_MUTEX_INIT_FAST);
-
- mysql_mutex_destroy(&THR_LOCK_open);
- mysql_mutex_init(key_THR_LOCK_open, &THR_LOCK_open, MY_MUTEX_INIT_FAST);
-
- mysql_mutex_destroy(&THR_LOCK_charset);
- mysql_mutex_init(key_THR_LOCK_charset, &THR_LOCK_charset, MY_MUTEX_INIT_FAST);
-
-#ifndef DBUG_OFF
- mysql_mutex_destroy(&THR_LOCK_threads);
- mysql_mutex_init(key_THR_LOCK_threads, &THR_LOCK_threads, MY_MUTEX_INIT_FAST);
-
- mysql_cond_destroy(&THR_COND_threads);
- mysql_cond_init(key_THR_COND_threads, &THR_COND_threads);
-#endif
-}
-
-
-/**
- initialize thread environment
-
- @retval FALSE ok
- @retval TRUE error (Couldn't create THR_KEY_mysys)
-*/
-
-my_bool my_thread_global_init()
-{
- int pth_ret;
-
- if (my_thread_global_init_done)
- return FALSE;
- my_thread_global_init_done= TRUE;
-
-#if defined(SAFE_MUTEX)
- safe_mutex_global_init(); /* Must be called early */
-#endif
-
-#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
- /*
- Set mutex type to "fast" a.k.a "adaptive"
-
- In this case the thread may steal the mutex from some other thread
- that is waiting for the same mutex. This will save us some
- context switches but may cause a thread to 'starve forever' while
- waiting for the mutex (not likely if the code within the mutex is
- short).
- */
- pthread_mutexattr_init(&my_fast_mutexattr);
- pthread_mutexattr_settype(&my_fast_mutexattr,
- PTHREAD_MUTEX_ADAPTIVE_NP);
-#endif
-
-#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
- /*
- Set mutex type to "errorcheck"
- */
- pthread_mutexattr_init(&my_errorcheck_mutexattr);
- pthread_mutexattr_settype(&my_errorcheck_mutexattr,
- PTHREAD_MUTEX_ERRORCHECK);
-#endif
-
- DBUG_ASSERT(! THR_KEY_mysys_initialized);
-#ifndef DBUG_OFF
- if ((pth_ret= my_create_thread_local_key(&THR_KEY_mysys, NULL)) != 0)
- { /* purecov: begin inspected */
- my_message_local(ERROR_LEVEL, "Can't initialize threads: error %d",
- pth_ret);
- /* purecov: end */
- return TRUE;
- }
-#endif
- if ((pth_ret= my_create_thread_local_key(&THR_KEY_myerrno, NULL)) != 0)
- { /* purecov: begin inspected */
- my_message_local(ERROR_LEVEL, "Can't initialize threads: error %d",
- pth_ret);
- /* purecov: end */
- return TRUE;
- }
-#ifdef _WIN32
- if ((pth_ret= my_create_thread_local_key(&THR_KEY_winerrno, NULL)) != 0)
- { /* purecov: begin inspected */
- my_message_local(ERROR_LEVEL, "Can't initialize threads: error %d",
- pth_ret);
- /* purecov: end */
- return TRUE;
- }
-#endif
- THR_KEY_mysys_initialized= TRUE;
-
- mysql_mutex_init(key_THR_LOCK_malloc, &THR_LOCK_malloc, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_THR_LOCK_open, &THR_LOCK_open, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_THR_LOCK_charset, &THR_LOCK_charset, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_THR_LOCK_lock, &THR_LOCK_lock, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_THR_LOCK_myisam, &THR_LOCK_myisam, MY_MUTEX_INIT_SLOW);
- mysql_mutex_init(key_THR_LOCK_myisam_mmap, &THR_LOCK_myisam_mmap, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_THR_LOCK_heap, &THR_LOCK_heap, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_THR_LOCK_net, &THR_LOCK_net, MY_MUTEX_INIT_FAST);
-#ifndef DBUG_OFF
- mysql_mutex_init(key_THR_LOCK_threads, &THR_LOCK_threads, MY_MUTEX_INIT_FAST);
- mysql_cond_init(key_THR_COND_threads, &THR_COND_threads);
-#endif
-
- return FALSE;
-}
-
-
-void my_thread_global_end()
-{
-#ifndef DBUG_OFF
- struct timespec abstime;
- my_bool all_threads_killed= TRUE;
-
- set_timespec(&abstime, my_thread_end_wait_time);
- mysql_mutex_lock(&THR_LOCK_threads);
- while (THR_thread_count > 0)
- {
- int error= mysql_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads,
- &abstime);
- if (error == ETIMEDOUT || error == ETIME)
- {
-#ifndef _WIN32
- /*
- We shouldn't give an error here, because if we don't have
- pthread_kill(), programs like mysqld can't ensure that all threads
- are killed when we enter here.
- */
- if (THR_thread_count)
- /* purecov: begin inspected */
- my_message_local(ERROR_LEVEL, "Error in my_thread_global_end(): "
- "%d threads didn't exit", THR_thread_count);
- /* purecov: end */
-#endif
- all_threads_killed= FALSE;
- break;
- }
- }
- mysql_mutex_unlock(&THR_LOCK_threads);
-#endif
-
- DBUG_ASSERT(THR_KEY_mysys_initialized);
-#ifndef DBUG_OFF
- my_delete_thread_local_key(THR_KEY_mysys);
-#endif
- my_delete_thread_local_key(THR_KEY_myerrno);
-#ifdef _WIN32
- my_delete_thread_local_key(THR_KEY_winerrno);
-#endif
- THR_KEY_mysys_initialized= FALSE;
-#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
- pthread_mutexattr_destroy(&my_fast_mutexattr);
-#endif
-#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
- pthread_mutexattr_destroy(&my_errorcheck_mutexattr);
-#endif
- mysql_mutex_destroy(&THR_LOCK_malloc);
- mysql_mutex_destroy(&THR_LOCK_open);
- mysql_mutex_destroy(&THR_LOCK_lock);
- mysql_mutex_destroy(&THR_LOCK_myisam);
- mysql_mutex_destroy(&THR_LOCK_myisam_mmap);
- mysql_mutex_destroy(&THR_LOCK_heap);
- mysql_mutex_destroy(&THR_LOCK_net);
- mysql_mutex_destroy(&THR_LOCK_charset);
-#ifndef DBUG_OFF
- if (all_threads_killed)
- {
- mysql_mutex_destroy(&THR_LOCK_threads);
- mysql_cond_destroy(&THR_COND_threads);
- }
-#endif
-
- my_thread_global_init_done= FALSE;
-}
-
-
-/**
- Allocate thread specific memory for the thread, used by mysys and dbug
-
- @note This function may called multiple times for a thread, for example
- if one uses my_init() followed by mysql_server_init().
-
- @retval FALSE ok
- @retval TRUE Fatal error; mysys/dbug functions can't be used
-*/
-
-my_bool my_thread_init()
-{
-#ifndef DBUG_OFF
- struct st_my_thread_var *tmp;
-#endif
-
- if (!my_thread_global_init_done)
- return TRUE; /* cannot proceed with unintialized library */
-
-#ifdef _WIN32
- install_sigabrt_handler();
-#endif
-
-#ifndef DBUG_OFF
- if (mysys_thread_var())
- return FALSE;
-
- if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp))))
- return TRUE;
-
- mysql_mutex_lock(&THR_LOCK_threads);
- tmp->id= ++thread_id;
- ++THR_thread_count;
- mysql_mutex_unlock(&THR_LOCK_threads);
- set_mysys_thread_var(tmp);
-#endif
-
- return FALSE;
-}
-
-
-/**
- Deallocate memory used by the thread for book-keeping
-
- @note This may be called multiple times for a thread.
- This happens for example when one calls 'mysql_server_init()'
- mysql_server_end() and then ends with a mysql_end().
-*/
-
-void my_thread_end()
-{
-#ifndef DBUG_OFF
- struct st_my_thread_var *tmp= mysys_thread_var();
-#endif
-
-#ifdef HAVE_PSI_INTERFACE
- /*
- Remove the instrumentation for this thread.
- This must be done before trashing st_my_thread_var,
- because the LF_HASH depends on it.
- */
- PSI_THREAD_CALL(delete_current_thread)();
-#endif
-
-#if !defined(DBUG_OFF)
- if (tmp)
- {
- /* tmp->dbug is allocated inside DBUG library */
- if (tmp->dbug)
- {
- DBUG_POP();
- free(tmp->dbug);
- tmp->dbug= NULL;
- }
- free(tmp);
-
- /*
- Decrement counter for number of running threads. We are using this
- in my_thread_global_end() to wait until all threads have called
- my_thread_end and thus freed all memory they have allocated in
- my_thread_init() and DBUG_xxxx
- */
- mysql_mutex_lock(&THR_LOCK_threads);
- DBUG_ASSERT(THR_thread_count != 0);
- if (--THR_thread_count == 0)
- mysql_cond_signal(&THR_COND_threads);
- mysql_mutex_unlock(&THR_LOCK_threads);
- }
- set_mysys_thread_var(NULL);
-#endif
-}
-
-
-int my_errno()
-{
- if (THR_KEY_mysys_initialized)
- return (int)(intptr)my_get_thread_local(THR_KEY_myerrno);
- return 0;
-}
-
-
-void set_my_errno(int my_errno)
-{
- if (THR_KEY_mysys_initialized)
- (void) my_set_thread_local(THR_KEY_myerrno, (void*)(intptr)my_errno);
-}
-
-
-#ifdef _WIN32
-int thr_winerr()
-{
- if (THR_KEY_mysys_initialized)
- return (int)(intptr)my_get_thread_local(THR_KEY_winerrno);
- return 0;
-}
-
-
-void set_thr_winerr(int winerr)
-{
- if (THR_KEY_mysys_initialized)
- (void) my_set_thread_local(THR_KEY_winerrno, (void*)(intptr)winerr);
-}
-#endif
-
-
-#ifndef DBUG_OFF
-my_thread_id my_thread_var_id()
-{
- return mysys_thread_var()->id;
-}
-
-
-void set_my_thread_var_id(my_thread_id id)
-{
- mysys_thread_var()->id= id;
-}
-
-
-struct _db_code_state_ **my_thread_var_dbug()
-{
- struct st_my_thread_var *tmp;
- /*
- Instead of enforcing DBUG_ASSERT(THR_KEY_mysys_initialized) here,
- which causes any DBUG_ENTER and related traces to fail when
- used in init / cleanup code, we are more tolerant:
- using DBUG_ENTER / DBUG_PRINT / DBUG_RETURN
- when the dbug instrumentation is not in place will do nothing.
- */
- if (! THR_KEY_mysys_initialized)
- return NULL;
- tmp= mysys_thread_var();
- return tmp ? &tmp->dbug : NULL;
-}
-#endif /* DBUG_OFF */
-
-
-#ifdef _WIN32
-/*
- In Visual Studio 2005 and later, default SIGABRT handler will overwrite
- any unhandled exception filter set by the application and will try to
- call JIT debugger. This is not what we want, this we calling __debugbreak
- to stop in debugger, if process is being debugged or to generate
- EXCEPTION_BREAKPOINT and then handle_segfault will do its magic.
-*/
-
-static void my_sigabrt_handler(int sig)
-{
- __debugbreak();
-}
-
-static void install_sigabrt_handler()
-{
- /*abort() should not override our exception filter*/
- _set_abort_behavior(0,_CALL_REPORTFAULT);
- signal(SIGABRT,my_sigabrt_handler);
-}
-#endif
-