diff --git a/config.h.cmake b/config.h.cmake index 5e6c324a07e..460164b38a2 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -384,7 +384,6 @@ #cmakedefine HAVE_GCC_C11_ATOMICS 1 #cmakedefine HAVE_SOLARIS_ATOMIC 1 #cmakedefine NO_FCNTL_NONBLOCK 1 -#cmakedefine NO_ALARM 1 #cmakedefine _LARGE_FILES 1 #cmakedefine _LARGEFILE_SOURCE 1 diff --git a/configure.cmake b/configure.cmake index dbd77a6e00f..64d04ffe27a 100644 --- a/configure.cmake +++ b/configure.cmake @@ -836,7 +836,6 @@ CHECK_CXX_SOURCE_COMPILES(" " HAVE_SOLARIS_STYLE_GETHOST) -SET(NO_ALARM 1 CACHE BOOL "No need to use alarm to implement timeout") # As a consequence of ALARMs no longer being used, thread # notification for KILL must close the socket to wake up diff --git a/include/my_pthread.h b/include/my_pthread.h index 3e68538b424..9d5ace4ec67 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -181,7 +181,6 @@ extern int my_pthread_create_detached; #define PTHREAD_CREATE_DETACHED &my_pthread_create_detached #define PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_GLOBAL #define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_LOCAL -#define USE_ALARM_THREAD #endif /* defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) */ #if defined(_BSDI_VERSION) && _BSDI_VERSION < 199910 diff --git a/include/thr_alarm.h b/include/thr_alarm.h deleted file mode 100644 index e0f3fdd1c25..00000000000 --- a/include/thr_alarm.h +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright (c) 2000, 2011, 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-1335 USA */ - -/* Prototypes when using thr_alarm library functions */ - -#ifndef _thr_alarm_h -#define _thr_alarm_h -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef USE_ALARM_THREAD -#define USE_ONE_SIGNAL_HAND /* One must call process_alarm */ -#endif -#ifdef HAVE_rts_threads -#undef USE_ONE_SIGNAL_HAND -#define USE_ALARM_THREAD -#define THR_SERVER_ALARM SIGUSR1 -#else -#define THR_SERVER_ALARM SIGALRM -#endif - -typedef struct st_alarm_info -{ - time_t next_alarm_time; - uint active_alarms; - uint max_used_alarms; -} ALARM_INFO; - -void thr_alarm_info(ALARM_INFO *info); -extern my_bool my_disable_thr_alarm; - -#ifdef _WIN32 -#define DONT_USE_THR_ALARM -#endif -#if defined(DONT_USE_THR_ALARM) - -#define USE_ALARM_THREAD -#undef USE_ONE_SIGNAL_HAND - -typedef my_bool thr_alarm_t; -typedef my_bool ALARM; - -#define thr_alarm_init(A) (*(A))=0 -#define thr_alarm_in_use(A) (*(A) != 0) -#define thr_end_alarm(A) -#define thr_alarm(A,B,C) ((*(A)=1)-1) -/* The following should maybe be (*(A)) */ -#define thr_got_alarm(A) 0 -#define init_thr_alarm(A) -#define thr_alarm_kill(A) -#define resize_thr_alarm(N) -#define end_thr_alarm(A) - -#else -#if defined(_WIN32) -typedef struct st_thr_alarm_entry -{ - UINT_PTR crono; -} thr_alarm_entry; - -#else /* System with posix threads */ - -typedef int thr_alarm_entry; - -#define thr_got_alarm(thr_alarm) (**(thr_alarm)) - -#endif /* _WIN32 */ - -typedef thr_alarm_entry* thr_alarm_t; - -typedef struct st_alarm { - time_t expire_time; - thr_alarm_entry alarmed; /* set when alarm is due */ - pthread_t thread; - my_thread_id thread_id; - uint index_in_queue; - my_bool malloced; -} ALARM; - -extern uint thr_client_alarm; -extern pthread_t alarm_thread; - -#define thr_alarm_init(A) (*(A))=0 -#define thr_alarm_in_use(A) (*(A)!= 0) -void init_thr_alarm(uint max_alarm); -void resize_thr_alarm(uint max_alarms); -my_bool thr_alarm(thr_alarm_t *alarmed, uint sec, ALARM *buff); -void thr_alarm_kill(my_thread_id thread_id); -void thr_end_alarm(thr_alarm_t *alarmed); -void end_thr_alarm(my_bool free_structures); -sig_handler process_alarm(int); -#ifndef thr_got_alarm -my_bool thr_got_alarm(thr_alarm_t *alrm); -#endif - - -#endif /* DONT_USE_THR_ALARM */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _thr_alarm_h */ diff --git a/mysql-test/suite/sys_vars/r/debug_no_thread_alarm_basic.result b/mysql-test/suite/sys_vars/r/debug_no_thread_alarm_basic.result deleted file mode 100644 index 817c7880d5d..00000000000 --- a/mysql-test/suite/sys_vars/r/debug_no_thread_alarm_basic.result +++ /dev/null @@ -1,21 +0,0 @@ -select @@global.debug_no_thread_alarm; -@@global.debug_no_thread_alarm -0 -select @@session.debug_no_thread_alarm; -ERROR HY000: Variable 'debug_no_thread_alarm' is a GLOBAL variable -show global variables like 'debug_no_thread_alarm'; -Variable_name Value -debug_no_thread_alarm OFF -show session variables like 'debug_no_thread_alarm'; -Variable_name Value -debug_no_thread_alarm OFF -select * from information_schema.global_variables where variable_name='debug_no_thread_alarm'; -VARIABLE_NAME VARIABLE_VALUE -DEBUG_NO_THREAD_ALARM OFF -select * from information_schema.session_variables where variable_name='debug_no_thread_alarm'; -VARIABLE_NAME VARIABLE_VALUE -DEBUG_NO_THREAD_ALARM OFF -set global debug_no_thread_alarm=1; -ERROR HY000: Variable 'debug_no_thread_alarm' is a read only variable -set session debug_no_thread_alarm=1; -ERROR HY000: Variable 'debug_no_thread_alarm' is a read only variable diff --git a/mysql-test/suite/sys_vars/r/sysvars_debug.result b/mysql-test/suite/sys_vars/r/sysvars_debug.result index e929d9000df..a705b1faef6 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_debug.result +++ b/mysql-test/suite/sys_vars/r/sysvars_debug.result @@ -46,21 +46,6 @@ ENUM_VALUE_LIST OFF,ON READ_ONLY YES COMMAND_LINE_ARGUMENT OPTIONAL GLOBAL_VALUE_PATH NULL -VARIABLE_NAME DEBUG_NO_THREAD_ALARM -SESSION_VALUE NULL -GLOBAL_VALUE OFF -GLOBAL_VALUE_ORIGIN COMPILE-TIME -DEFAULT_VALUE OFF -VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE BOOLEAN -VARIABLE_COMMENT Disable system thread alarm calls. Disabling it may be useful in debugging or testing, never do it in production -NUMERIC_MIN_VALUE NULL -NUMERIC_MAX_VALUE NULL -NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST OFF,ON -READ_ONLY YES -COMMAND_LINE_ARGUMENT OPTIONAL -GLOBAL_VALUE_PATH NULL VARIABLE_NAME DEBUG_SYNC SESSION_VALUE ON - current signals: '' GLOBAL_VALUE NULL diff --git a/mysql-test/suite/sys_vars/t/debug_no_thread_alarm_basic.test b/mysql-test/suite/sys_vars/t/debug_no_thread_alarm_basic.test deleted file mode 100644 index 39823ba2bf1..00000000000 --- a/mysql-test/suite/sys_vars/t/debug_no_thread_alarm_basic.test +++ /dev/null @@ -1,21 +0,0 @@ -# bool readonly - -# -# show values; -# -select @@global.debug_no_thread_alarm; ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -select @@session.debug_no_thread_alarm; -show global variables like 'debug_no_thread_alarm'; -show session variables like 'debug_no_thread_alarm'; -select * from information_schema.global_variables where variable_name='debug_no_thread_alarm'; -select * from information_schema.session_variables where variable_name='debug_no_thread_alarm'; - -# -# show that it's read-only -# ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -set global debug_no_thread_alarm=1; ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -set session debug_no_thread_alarm=1; - diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index 5d34cf94b46..db1da49f84b 100644 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -34,7 +34,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c my_default.c my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_basename.c my_write.c ptr_cmp.c queues.c stacktrace.c - string.c thr_alarm.c thr_lock.c thr_mutex.c + string.c thr_lock.c thr_mutex.c thr_rwlock.c thr_timer.c tree.c typelib.c base64.c my_memmem.c my_getpagesize.c diff --git a/mysys/my_init.c b/mysys/my_init.c index 73d767377b4..485ce163765 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -468,7 +468,7 @@ PSI_mutex_key key_LOCK_localtime_r; PSI_mutex_key key_BITMAP_mutex, key_IO_CACHE_append_buffer_lock, key_IO_CACHE_SHARE_mutex, key_KEY_CACHE_cache_lock, - key_LOCK_alarm, key_LOCK_timer, + key_LOCK_timer, key_my_thread_var_mutex, key_THR_LOCK_charset, key_THR_LOCK_heap, key_THR_LOCK_lock, key_THR_LOCK_malloc, key_THR_LOCK_mutex, key_THR_LOCK_myisam, key_THR_LOCK_net, @@ -487,7 +487,6 @@ static PSI_mutex_info all_mysys_mutexes[]= { &key_IO_CACHE_append_buffer_lock, "IO_CACHE::append_buffer_lock", 0}, { &key_IO_CACHE_SHARE_mutex, "IO_CACHE::SHARE_mutex", 0}, { &key_KEY_CACHE_cache_lock, "KEY_CACHE::cache_lock", 0}, - { &key_LOCK_alarm, "LOCK_alarm", PSI_FLAG_GLOBAL}, { &key_LOCK_timer, "LOCK_timer", PSI_FLAG_GLOBAL}, { &key_my_thread_var_mutex, "my_thread_var::mutex", 0}, { &key_THR_LOCK_charset, "THR_LOCK_charset", PSI_FLAG_GLOBAL}, @@ -504,13 +503,12 @@ static PSI_mutex_info all_mysys_mutexes[]= { &key_LOCK_uuid_generator, "LOCK_uuid_generator", PSI_FLAG_GLOBAL } }; -PSI_cond_key key_COND_alarm, key_COND_timer, key_IO_CACHE_SHARE_cond, +PSI_cond_key key_COND_timer, key_IO_CACHE_SHARE_cond, key_IO_CACHE_SHARE_cond_writer, key_my_thread_var_suspend, key_THR_COND_threads, key_WT_RESOURCE_cond; static PSI_cond_info all_mysys_conds[]= { - { &key_COND_alarm, "COND_alarm", PSI_FLAG_GLOBAL}, { &key_COND_timer, "COND_timer", PSI_FLAG_GLOBAL}, { &key_IO_CACHE_SHARE_cond, "IO_CACHE_SHARE::cond", 0}, { &key_IO_CACHE_SHARE_cond_writer, "IO_CACHE_SHARE::cond_writer", 0}, @@ -526,16 +524,10 @@ static PSI_rwlock_info all_mysys_rwlocks[]= { &key_SAFEHASH_mutex, "SAFE_HASH::mutex", 0} }; -#ifdef USE_ALARM_THREAD -PSI_thread_key key_thread_alarm; -#endif PSI_thread_key key_thread_timer; static PSI_thread_info all_mysys_threads[]= { -#ifdef USE_ALARM_THREAD - { &key_thread_alarm, "alarm", PSI_FLAG_GLOBAL}, -#endif { &key_thread_timer, "statement_timer", PSI_FLAG_GLOBAL} }; diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c index 9bedfe36593..d29bbe60d8a 100644 --- a/mysys/my_pthread.c +++ b/mysys/my_pthread.c @@ -20,7 +20,6 @@ #include "mysys_priv.h" #include #include -#include #include #if (defined(__BSD__) || defined(_BSDI_VERSION)) @@ -234,11 +233,7 @@ void *sigwait_thread(void *set_arg) sigaction(i, &sact, (struct sigaction*) 0); } } - /* Ensure that init_thr_alarm() is called */ - DBUG_ASSERT(thr_client_alarm); - sigaddset(set, thr_client_alarm); pthread_sigmask(SIG_UNBLOCK,(sigset_t*) set,(sigset_t*) 0); - alarm_thread=pthread_self(); /* For thr_alarm */ for (;;) { /* Wait for signals */ diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h index e795dbe2f5f..efeb0c65af3 100644 --- a/mysys/mysys_priv.h +++ b/mysys/mysys_priv.h @@ -43,20 +43,17 @@ extern PSI_mutex_key key_LOCK_localtime_r; #endif /* !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) */ extern PSI_mutex_key key_BITMAP_mutex, key_IO_CACHE_append_buffer_lock, - key_IO_CACHE_SHARE_mutex, key_KEY_CACHE_cache_lock, key_LOCK_alarm, + key_IO_CACHE_SHARE_mutex, key_KEY_CACHE_cache_lock, key_my_thread_var_mutex, key_THR_LOCK_charset, key_THR_LOCK_heap, key_THR_LOCK_lock, key_THR_LOCK_malloc, key_THR_LOCK_mutex, key_THR_LOCK_myisam, key_THR_LOCK_net, key_THR_LOCK_open, key_THR_LOCK_threads, key_LOCK_uuid_generator, key_TMPDIR_mutex, key_THR_LOCK_myisam_mmap, key_LOCK_timer; -extern PSI_cond_key key_COND_alarm, key_COND_timer, key_IO_CACHE_SHARE_cond, +extern PSI_cond_key key_COND_timer, key_IO_CACHE_SHARE_cond, key_IO_CACHE_SHARE_cond_writer, key_my_thread_var_suspend, key_THR_COND_threads; -#ifdef USE_ALARM_THREAD -extern PSI_thread_key key_thread_alarm; -#endif /* USE_ALARM_THREAD */ extern PSI_thread_key key_thread_timer; extern PSI_rwlock_key key_SAFEHASH_mutex; diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c deleted file mode 100644 index b98775e1099..00000000000 --- a/mysys/thr_alarm.c +++ /dev/null @@ -1,845 +0,0 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates - Copyright (c) 2012, 2014, SkySQL Ab - - 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-1335 USA */ - -/* To avoid problems with alarms in debug code, we disable DBUG here */ -#define FORCE_DBUG_OFF -#include "mysys_priv.h" -#include - -#if !defined(DONT_USE_THR_ALARM) -#include -#include -#include -#include -#include -#include -#include "thr_alarm.h" - -#ifdef HAVE_SYS_SELECT_H -#include /* AIX needs this for fd_set */ -#endif - -#ifndef ETIME -#define ETIME ETIMEDOUT -#endif - -#ifdef DBUG_OFF -#define reset_index_in_queue(alarm_data) -#else -#define reset_index_in_queue(alarm_data) alarm_data->index_in_queue= 0; -#endif /* DBUG_OFF */ - -#ifndef USE_ONE_SIGNAL_HAND -#define one_signal_hand_sigmask(A,B,C) pthread_sigmask((A), (B), (C)) -#else -#define one_signal_hand_sigmask(A,B,C) -#endif - -my_bool thr_alarm_inited= 0, my_disable_thr_alarm= 0; - -#if !defined(_WIN32) - -uint thr_client_alarm; -static int alarm_aborted=1; /* No alarm thread */ -volatile my_bool alarm_thread_running= 0; -time_t next_alarm_expire_time= ~ (time_t) 0; -static sig_handler process_alarm_part2(int sig); - -static mysql_mutex_t LOCK_alarm; -static mysql_cond_t COND_alarm; -static sigset_t full_signal_set; -static QUEUE alarm_queue; -static uint max_used_alarms=0; -pthread_t alarm_thread; - -#define MY_THR_ALARM_QUEUE_EXTENT 10 - -#ifdef USE_ALARM_THREAD -static void *alarm_handler(void *arg); -#define reschedule_alarms() mysql_cond_signal(&COND_alarm) -#else -#define reschedule_alarms() pthread_kill(alarm_thread,THR_SERVER_ALARM) -#endif - -static sig_handler thread_alarm(int sig __attribute__((unused))); - -static int compare_ulong(void *not_used __attribute__((unused)), - uchar *a_ptr,uchar* b_ptr) -{ - ulong a=*((ulong*) a_ptr),b= *((ulong*) b_ptr); - return (a < b) ? -1 : (a == b) ? 0 : 1; -} - -void init_thr_alarm(uint max_alarms) -{ - sigset_t s; - DBUG_ENTER("init_thr_alarm"); - alarm_aborted=0; - next_alarm_expire_time= ~ (time_t) 0; - init_queue(&alarm_queue, max_alarms+1, offsetof(ALARM,expire_time), 0, - compare_ulong, NullS, offsetof(ALARM, index_in_queue)+1, - MY_THR_ALARM_QUEUE_EXTENT); - sigfillset(&full_signal_set); /* Neaded to block signals */ - mysql_mutex_init(key_LOCK_alarm, &LOCK_alarm, MY_MUTEX_INIT_FAST); - mysql_cond_init(key_COND_alarm, &COND_alarm, NULL); - thr_client_alarm= SIGUSR1; - my_sigset(thr_client_alarm, thread_alarm); - sigemptyset(&s); - sigaddset(&s, THR_SERVER_ALARM); - alarm_thread=pthread_self(); -#if defined(USE_ALARM_THREAD) - { - pthread_attr_t thr_attr; - pthread_attr_init(&thr_attr); - pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS); - pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); - mysql_thread_create(key_thread_alarm, - &alarm_thread, &thr_attr, alarm_handler, NULL); - pthread_attr_destroy(&thr_attr); - } -#elif defined(USE_ONE_SIGNAL_HAND) - pthread_sigmask(SIG_BLOCK, &s, NULL); /* used with sigwait() */ -#else - my_sigset(THR_SERVER_ALARM, process_alarm); - pthread_sigmask(SIG_UNBLOCK, &s, NULL); -#endif - DBUG_VOID_RETURN; -} - - -void resize_thr_alarm(uint max_alarms) -{ - mysql_mutex_lock(&LOCK_alarm); - /* - It's ok not to shrink the queue as there may be more pending alarms than - than max_alarms - */ - if (alarm_queue.elements < max_alarms) - { - resize_queue(&alarm_queue,max_alarms+1); - max_used_alarms= alarm_queue.elements; - } - mysql_mutex_unlock(&LOCK_alarm); -} - - -/* - Request alarm after sec seconds. - - SYNOPSIS - thr_alarm() - alrm Pointer to alarm detection - alarm_data Structure to store in alarm queue - - NOTES - This function can't be called from the alarm-handling thread. - - RETURN VALUES - 0 ok - 1 If no more alarms are allowed (aborted by process) - - Stores in first argument a pointer to a non-zero int which is set to 0 - when the alarm has been given -*/ - -my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data) -{ - time_t now, next; -#ifndef USE_ONE_SIGNAL_HAND - sigset_t old_mask; -#endif - my_bool reschedule; - struct st_my_thread_var *current_my_thread_var= my_thread_var; - DBUG_ENTER("thr_alarm"); - DBUG_PRINT("enter",("thread: %s sec: %d",my_thread_name(),sec)); - - if (my_disable_thr_alarm) - { - (*alrm)= &alarm_data->alarmed; - alarm_data->alarmed= 1; /* Abort if interrupted */ - DBUG_RETURN(0); - } - - if (unlikely(alarm_aborted)) - { /* No signal thread */ - DBUG_PRINT("info", ("alarm aborted")); - if (alarm_aborted > 0) - goto abort_no_unlock; - sec= 1; /* Abort mode */ - } - - now= my_time(0); - if (!alarm_data) - { - if (!(alarm_data=(ALARM*) my_malloc(PSI_INSTRUMENT_ME, sizeof(ALARM), - MYF(MY_WME)))) - goto abort_no_unlock; - alarm_data->malloced= 1; - } - else - alarm_data->malloced= 0; - next= now + sec; - alarm_data->expire_time= next; - alarm_data->alarmed= 0; - alarm_data->thread= current_my_thread_var->pthread_self; - alarm_data->thread_id= current_my_thread_var->id; - - one_signal_hand_sigmask(SIG_BLOCK,&full_signal_set,&old_mask); - mysql_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */ - if (alarm_queue.elements >= max_used_alarms) - { - max_used_alarms=alarm_queue.elements+1; - } - reschedule= (ulong) next_alarm_expire_time > (ulong) next; - queue_insert_safe(&alarm_queue, (uchar*) alarm_data); - assert(alarm_data->index_in_queue > 0); - - /* Reschedule alarm if the current one has more than sec left */ - if (unlikely(reschedule)) - { - DBUG_PRINT("info", ("reschedule")); - if (pthread_equal(pthread_self(),alarm_thread)) - { - alarm(sec); /* purecov: inspected */ - next_alarm_expire_time= next; - } - else - reschedule_alarms(); /* Reschedule alarms */ - } - mysql_mutex_unlock(&LOCK_alarm); - one_signal_hand_sigmask(SIG_SETMASK,&old_mask,NULL); - (*alrm)= &alarm_data->alarmed; - DBUG_RETURN(0); - -abort_no_unlock: - *alrm= 0; /* No alarm */ - DBUG_RETURN(1); -} - - -/* - Remove alarm from list of alarms -*/ - -void thr_end_alarm(thr_alarm_t *alarmed) -{ - ALARM *alarm_data; -#ifndef USE_ONE_SIGNAL_HAND - sigset_t old_mask; -#endif - DBUG_ENTER("thr_end_alarm"); - - if (my_disable_thr_alarm) - DBUG_VOID_RETURN; - one_signal_hand_sigmask(SIG_BLOCK,&full_signal_set,&old_mask); - alarm_data= (ALARM*) ((uchar*) *alarmed - offsetof(ALARM,alarmed)); - mysql_mutex_lock(&LOCK_alarm); - DBUG_ASSERT(alarm_data->index_in_queue != 0); - DBUG_ASSERT((ALARM*) queue_element(&alarm_queue, - alarm_data->index_in_queue) == - alarm_data); - queue_remove(&alarm_queue, alarm_data->index_in_queue); - mysql_mutex_unlock(&LOCK_alarm); - one_signal_hand_sigmask(SIG_SETMASK,&old_mask,NULL); - reset_index_in_queue(alarm_data); - DBUG_VOID_RETURN; -} - -/* - Come here when some alarm in queue is due. - Mark all alarms with are finnished in list. - Schedule alarms to be sent again after 1-10 sec (many alarms at once) - If alarm_aborted is set then all alarms are given and resent - every second. -*/ - -sig_handler process_alarm(int sig __attribute__((unused))) -{ - sigset_t old_mask; -/* - This must be first as we can't call DBUG inside an alarm for a normal thread -*/ - - /* - We have to do do the handling of the alarm in a sub function, - because otherwise we would get problems with two threads calling - DBUG_... functions at the same time (as two threads may call - process_alarm() at the same time - */ - -#ifndef USE_ALARM_THREAD - pthread_sigmask(SIG_SETMASK,&full_signal_set,&old_mask); - mysql_mutex_lock(&LOCK_alarm); -#endif - process_alarm_part2(sig); -#ifndef USE_ALARM_THREAD -#if defined(SIGNAL_HANDLER_RESET_ON_DELIVERY) && !defined(USE_ONE_SIGNAL_HAND) - my_sigset(THR_SERVER_ALARM,process_alarm); -#endif - mysql_mutex_unlock(&LOCK_alarm); - pthread_sigmask(SIG_SETMASK,&old_mask,NULL); -#endif - return; -} - - -static sig_handler process_alarm_part2(int sig __attribute__((unused))) -{ - ALARM *alarm_data; - DBUG_ENTER("process_alarm"); - DBUG_PRINT("info",("sig: %d active alarms: %d",sig,alarm_queue.elements)); - -#if defined(MAIN) && !defined(__bsdi__) - printf("process_alarm\n"); fflush(stdout); -#endif - if (likely(alarm_queue.elements)) - { - if (unlikely(alarm_aborted)) - { - uint i; - for (i= queue_first_element(&alarm_queue) ; - i <= queue_last_element(&alarm_queue) ;) - { - alarm_data=(ALARM*) queue_element(&alarm_queue,i); - alarm_data->alarmed=1; /* Info to thread */ - if (pthread_equal(alarm_data->thread,alarm_thread) || - pthread_kill(alarm_data->thread, thr_client_alarm)) - { -#ifdef MAIN - printf("Warning: pthread_kill couldn't find thread!!!\n"); -#endif - queue_remove(&alarm_queue,i); /* No thread. Remove alarm */ - reset_index_in_queue(alarm_data); - } - else - i++; /* Signal next thread */ - } -#ifndef USE_ALARM_THREAD - if (alarm_queue.elements) - alarm(1); /* Signal soon again */ -#endif - } - else - { - time_t now= my_time(0); - time_t next= now+10-(now%10); - while ((alarm_data=(ALARM*) queue_top(&alarm_queue))->expire_time <= now) - { - alarm_data->alarmed=1; /* Info to thread */ - DBUG_PRINT("info",("sending signal to waiting thread")); - if (pthread_equal(alarm_data->thread,alarm_thread) || - pthread_kill(alarm_data->thread, thr_client_alarm)) - { -#ifdef MAIN - printf("Warning: pthread_kill couldn't find thread!!!\n"); -#endif /* MAIN */ - queue_remove_top(&alarm_queue); /* No thread. Remove alarm */ - reset_index_in_queue(alarm_data); - if (!alarm_queue.elements) - break; - } - else - { - alarm_data->expire_time=next; - queue_replace_top(&alarm_queue); - } - } -#ifndef USE_ALARM_THREAD - if (alarm_queue.elements) - { -#ifdef __bsdi__ - alarm(0); /* Remove old alarm */ -#endif - alarm((uint) (alarm_data->expire_time-now)); - next_alarm_expire_time= alarm_data->expire_time; - } -#endif - } - } - else - { - /* - Ensure that next time we call thr_alarm(), we will schedule a new alarm - */ - next_alarm_expire_time= ~(time_t) 0; - } - DBUG_VOID_RETURN; -} - - -/* - Schedule all alarms now and optionally free all structures - - SYNPOSIS - end_thr_alarm() - free_structures Set to 1 if we should free memory used for - the alarm queue. - When we call this we should KNOW that there - is no active alarms - IMPLEMENTATION - Set alarm_abort to -1 which will change the behavior of alarms as follows: - - All old alarms will be rescheduled at once - - All new alarms will be rescheduled to one second -*/ - -void end_thr_alarm(my_bool free_structures) -{ - DBUG_ENTER("end_thr_alarm"); - if (alarm_aborted != 1) /* If memory not freed */ - { - mysql_mutex_lock(&LOCK_alarm); - DBUG_PRINT("info",("Rescheduling %d waiting alarms",alarm_queue.elements)); - alarm_aborted= -1; /* mark aborted */ - if (alarm_queue.elements || (alarm_thread_running && free_structures)) - { - if (pthread_equal(pthread_self(),alarm_thread)) - alarm(1); /* Shut down everything soon */ - else - reschedule_alarms(); - } - if (free_structures) - { - struct timespec abstime; - - DBUG_ASSERT(!alarm_queue.elements); - - /* Wait until alarm thread dies */ - set_timespec(abstime, 10); /* Wait up to 10 seconds */ - while (alarm_thread_running) - { - int error= mysql_cond_timedwait(&COND_alarm, &LOCK_alarm, &abstime); - if (error == ETIME || error == ETIMEDOUT) - break; /* Don't wait forever */ - } - delete_queue(&alarm_queue); - alarm_aborted= 1; - mysql_mutex_unlock(&LOCK_alarm); - if (!alarm_thread_running) /* Safety */ - { - mysql_mutex_destroy(&LOCK_alarm); - mysql_cond_destroy(&COND_alarm); - } - } - else - mysql_mutex_unlock(&LOCK_alarm); - } - DBUG_VOID_RETURN; -} - - -/* - Remove another thread from the alarm -*/ - -void thr_alarm_kill(my_thread_id thread_id) -{ - uint i; - DBUG_ENTER("thr_alarm_kill"); - - if (alarm_aborted) - return; - mysql_mutex_lock(&LOCK_alarm); - for (i= queue_first_element(&alarm_queue) ; - i <= queue_last_element(&alarm_queue); - i++) - { - ALARM *element= (ALARM*) queue_element(&alarm_queue,i); - if (element->thread_id == thread_id) - { - DBUG_PRINT("info", ("found thread; Killing it")); - element->expire_time= 0; - queue_replace(&alarm_queue, i); - reschedule_alarms(); - break; - } - } - mysql_mutex_unlock(&LOCK_alarm); - DBUG_VOID_RETURN; -} - - -void thr_alarm_info(ALARM_INFO *info) -{ - mysql_mutex_lock(&LOCK_alarm); - info->next_alarm_time= 0; - info->max_used_alarms= max_used_alarms; - if ((info->active_alarms= alarm_queue.elements)) - { - time_t now= my_time(0); - long time_diff; - ALARM *alarm_data= (ALARM*) queue_top(&alarm_queue); - time_diff= (long) (alarm_data->expire_time - now); - info->next_alarm_time= (ulong) (time_diff < 0 ? 0 : time_diff); - } - mysql_mutex_unlock(&LOCK_alarm); -} - -/* - This is here for thread to get interruptet from read/write/fcntl - ARGSUSED -*/ - - -static sig_handler thread_alarm(int sig __attribute__((unused))) -{ -#ifdef MAIN - printf("thread_alarm\n"); fflush(stdout); -#endif -#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY - my_sigset(sig,thread_alarm); /* int. thread system calls */ -#endif -} - - -#ifdef HAVE_TIMESPEC_TS_SEC -#define tv_sec ts_sec -#define tv_nsec ts_nsec -#endif - -/* set up a alarm thread with uses 'sleep' to sleep between alarms */ - -#ifdef USE_ALARM_THREAD -static void *alarm_handler(void *arg __attribute__((unused))) -{ - int error; - struct timespec abstime; -#ifdef MAIN - puts("Starting alarm thread"); -#endif - my_thread_init(); - alarm_thread_running= 1; - mysql_mutex_lock(&LOCK_alarm); - for (;;) - { - if (alarm_queue.elements) - { - time_t sleep_time,now= my_time(0); - if (alarm_aborted) - sleep_time=now+1; - else - sleep_time= ((ALARM*) queue_top(&alarm_queue))->expire_time; - if (sleep_time > now) - { - abstime.tv_sec=sleep_time; - abstime.tv_nsec=0; - next_alarm_expire_time= sleep_time; - if ((error= mysql_cond_timedwait(&COND_alarm, &LOCK_alarm, &abstime)) && - error != ETIME && error != ETIMEDOUT) - { -#ifdef MAIN - printf("Got error: %d from ptread_cond_timedwait (errno: %d)\n", - error,errno); -#endif - } - } - } - else if (alarm_aborted == -1) - break; - else - { - next_alarm_expire_time= ~ (time_t) 0; - if ((error= mysql_cond_wait(&COND_alarm, &LOCK_alarm))) - { -#ifdef MAIN - printf("Got error: %d from ptread_cond_wait (errno: %d)\n", - error,errno); -#endif - } - } - process_alarm(0); - } - bzero((char*) &alarm_thread,sizeof(alarm_thread)); /* For easy debugging */ - alarm_thread_running= 0; - mysql_cond_signal(&COND_alarm); - mysql_mutex_unlock(&LOCK_alarm); - pthread_exit(0); - return 0; /* Impossible */ -} -#endif /* USE_ALARM_THREAD */ -#endif - -/**************************************************************************** - Handling of test case (when compiled with -DMAIN) -***************************************************************************/ - -#ifdef MAIN -#if !defined(DONT_USE_THR_ALARM) - -static mysql_cond_t COND_thread_count; -static mysql_mutex_t LOCK_thread_count; -static uint thread_count; - -#ifdef HPUX10 -typedef int * fd_set_ptr; -#else -typedef fd_set * fd_set_ptr; -#endif /* HPUX10 */ - -static void *test_thread(void *arg) -{ - int i,param=*((int*) arg),wait_time,retry; - time_t start_time; - thr_alarm_t got_alarm; - fd_set fd; - FD_ZERO(&fd); - my_thread_init(); - printf("Thread %d (%s) started\n",param,my_thread_name()); fflush(stdout); - for (i=1 ; i <= 10 ; i++) - { - wait_time=param ? 11-i : i; - start_time= my_time(0); - if (thr_alarm(&got_alarm,wait_time,0)) - { - printf("Thread: %s Alarms aborted\n",my_thread_name()); - break; - } - if (wait_time == 3) - { - printf("Thread: %s Simulation of no alarm needed\n",my_thread_name()); - fflush(stdout); - } - else - { - for (retry=0 ; !thr_got_alarm(&got_alarm) && retry < 10 ; retry++) - { - printf("Thread: %s Waiting %d sec\n",my_thread_name(),wait_time); - select(0,(fd_set_ptr) &fd,0,0,0); - } - if (!thr_got_alarm(&got_alarm)) - { - printf("Thread: %s didn't get an alarm. Aborting!\n", - my_thread_name()); - break; - } - if (wait_time == 7) - { /* Simulate alarm-miss */ - fd_set readFDs; - uint max_connection=fileno(stdin); - FD_ZERO(&readFDs); - FD_SET(max_connection,&readFDs); - retry=0; - for (;;) - { - printf("Thread: %s Simulating alarm miss\n",my_thread_name()); - fflush(stdout); - if (select(max_connection+1, (fd_set_ptr) &readFDs,0,0,0) < 0) - { - if (errno == EINTR) - break; /* Got new interrupt */ - printf("Got errno: %d from select. Retrying..\n",errno); - if (retry++ >= 3) - { - printf("Warning: Interrupt of select() doesn't set errno!\n"); - break; - } - } - else /* This shouldn't happen */ - { - if (!FD_ISSET(max_connection,&readFDs)) - { - printf("Select interrupted, but errno not set\n"); - fflush(stdout); - if (retry++ >= 3) - break; - continue; - } - (void) getchar(); /* Somebody was playing */ - } - } - } - } - printf("Thread: %s Slept for %d (%d) sec\n",my_thread_name(), - (int) (my_time(0)-start_time), wait_time); fflush(stdout); - thr_end_alarm(&got_alarm); - fflush(stdout); - } - mysql_mutex_lock(&LOCK_thread_count); - thread_count--; - mysql_cond_signal(&COND_thread_count); /* Tell main we are ready */ - mysql_mutex_unlock(&LOCK_thread_count); - my_thread_end(); - return 0; -} - - -static void *signal_hand(void *arg __attribute__((unused))) -{ - sigset_t set; - int sig,error,err_count=0;; - - my_thread_init(); - pthread_detach_this_thread(); - init_thr_alarm(10); /* Setup alarm handler */ - mysql_mutex_lock(&LOCK_thread_count); /* Required by bsdi */ - mysql_cond_signal(&COND_thread_count); /* Tell main we are ready */ - mysql_mutex_unlock(&LOCK_thread_count); - - sigemptyset(&set); /* Catch all signals */ - sigaddset(&set,SIGINT); - sigaddset(&set,SIGQUIT); - sigaddset(&set,SIGTERM); - sigaddset(&set,SIGHUP); -#ifdef SIGTSTP - sigaddset(&set,SIGTSTP); -#endif -#ifdef USE_ONE_SIGNAL_HAND - sigaddset(&set,THR_SERVER_ALARM); /* For alarms */ - puts("Starting signal and alarm handling thread"); -#else - puts("Starting signal handling thread"); -#endif - printf("server alarm: %d thread alarm: %d\n", - THR_SERVER_ALARM, thr_client_alarm); - DBUG_PRINT("info",("Starting signal and alarm handling thread")); - for(;;) - { - int code; - while ((error=my_sigwait(&set,&sig,&code)) == EINTR) - printf("sigwait restarted\n"); - if (error) - { - fprintf(stderr,"Got error %d from sigwait\n",error); - if (err_count++ > 5) - exit(1); /* Too many errors in test */ - continue; - } -#ifdef USE_ONE_SIGNAL_HAND - if (sig != THR_SERVER_ALARM) -#endif - printf("Main thread: Got signal %d\n",sig); - switch (sig) { - case SIGINT: - case SIGQUIT: - case SIGTERM: - case SIGHUP: - printf("Aborting nicely\n"); - end_thr_alarm(0); - break; -#ifdef SIGTSTP - case SIGTSTP: - printf("Aborting\n"); - exit(1); - return 0; /* Keep some compilers happy */ -#endif -#ifdef USE_ONE_SIGNAL_HAND - case THR_SERVER_ALARM: - process_alarm(sig); - break; -#endif - } - } -} - - -int main(int argc __attribute__((unused)),char **argv __attribute__((unused))) -{ - pthread_t tid; - pthread_attr_t thr_attr; - int i, param[2], error; - sigset_t set; - ALARM_INFO alarm_info; - MY_INIT(argv[0]); - - if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '#') - { - DBUG_PUSH(argv[1]+2); - } - mysql_mutex_init(0, &LOCK_thread_count, MY_MUTEX_INIT_FAST); - mysql_cond_init(0, &COND_thread_count, NULL); - - /* Start a alarm handling thread */ - sigemptyset(&set); - sigaddset(&set,SIGINT); - sigaddset(&set,SIGQUIT); - sigaddset(&set,SIGTERM); - sigaddset(&set,SIGHUP); - signal(SIGTERM,SIG_DFL); /* If it's blocked by parent */ -#ifdef SIGTSTP - sigaddset(&set,SIGTSTP); -#endif - sigaddset(&set,THR_SERVER_ALARM); - sigdelset(&set, thr_client_alarm); - (void) pthread_sigmask(SIG_SETMASK,&set,NULL); - - pthread_attr_init(&thr_attr); - pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS); - pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&thr_attr,65536L); - - /* Start signal thread and wait for it to start */ - mysql_mutex_lock(&LOCK_thread_count); - mysql_thread_create(0, &tid, &thr_attr, signal_hand, NULL); - mysql_cond_wait(&COND_thread_count, &LOCK_thread_count); - mysql_mutex_unlock(&LOCK_thread_count); - DBUG_PRINT("info",("signal thread created")); - - thr_setconcurrency(3); - pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS); - printf("Main thread: %s\n",my_thread_name()); - for (i=0 ; i < 2 ; i++) - { - param[i]= i; - mysql_mutex_lock(&LOCK_thread_count); - if ((error= mysql_thread_create(0, - &tid, &thr_attr, test_thread, - (void*) ¶m[i]))) - { - printf("Can't create thread %d, error: %d\n",i,error); - exit(1); - } - thread_count++; - mysql_mutex_unlock(&LOCK_thread_count); - } - - pthread_attr_destroy(&thr_attr); - mysql_mutex_lock(&LOCK_thread_count); - thr_alarm_info(&alarm_info); - printf("Main_thread: Alarms: %u max_alarms: %u next_alarm_time: %lu\n", - alarm_info.active_alarms, alarm_info.max_used_alarms, - alarm_info.next_alarm_time); - while (thread_count) - { - mysql_cond_wait(&COND_thread_count, &LOCK_thread_count); - if (thread_count == 1) - { - printf("Calling end_thr_alarm. This should cancel the last thread\n"); - end_thr_alarm(0); - } - } - mysql_mutex_unlock(&LOCK_thread_count); - thr_alarm_info(&alarm_info); - end_thr_alarm(1); - printf("Main_thread: Alarms: %u max_alarms: %u next_alarm_time: %lu\n", - alarm_info.active_alarms, alarm_info.max_used_alarms, - alarm_info.next_alarm_time); - printf("Test succeeded\n"); - mysql_cond_destroy(&COND_thread_count); - mysql_mutex_destroy(&LOCK_thread_count); - my_end(MY_CHECK_ERROR); - return 0; -} - -#else /* !defined(DONT_USE_ALARM_THREAD) */ - -int main(int argc __attribute__((unused)),char **argv __attribute__((unused))) -{ - printf("thr_alarm disabled with DONT_USE_THR_ALARM\n"); - exit(1); -} - -#endif /* !defined(DONT_USE_ALARM_THREAD) */ -#endif /* WIN */ -#endif /* MAIN */ diff --git a/sql/client_settings.h b/sql/client_settings.h index cc4981ec6ae..93aa7f115ca 100644 --- a/sql/client_settings.h +++ b/sql/client_settings.h @@ -20,7 +20,6 @@ #error You have already included an client_settings.h and it should not be included twice #endif /* CLIENT_SETTINGS_INCLUDED */ -#include #include /* diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 89342d76191..2552334d71f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -113,7 +113,6 @@ #include #endif -#include #include #include #include "sp_rcontext.h" @@ -1670,10 +1669,11 @@ static void break_connect_loop() int UNINIT_VAR(error); DBUG_PRINT("info",("Waiting for select thread")); -#ifndef DONT_USE_THR_ALARM - if (pthread_kill(select_thread, thr_client_alarm)) - break; // allready dead -#endif + for(size_t i=0; i < listen_sockets.size(); i++) + { + int fd=mysql_socket_getfd(listen_sockets.at(i)); + shutdown(fd, SHUT_RDWR); + } set_timespec(abstime, 2); for (uint tmp=0 ; tmp < 10 && select_thread_in_use; tmp++) { @@ -1765,8 +1765,6 @@ static void close_connections(void) listen_sockets.free_memory(); mysql_mutex_unlock(&LOCK_start_thread); - end_thr_alarm(0); // Abort old alarms. - while (CONNECT::count) my_sleep(100); @@ -1877,10 +1875,6 @@ extern "C" sig_handler print_signal_warning(int sig) #ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY my_sigset(sig,print_signal_warning); /* int. thread system calls */ #endif -#if !defined(_WIN32) - if (sig == SIGALRM) - alarm(2); /* reschedule alarm */ -#endif } #ifdef _WIN32 @@ -2027,7 +2021,6 @@ static void clean_up(bool print_message) multi_keycache_free(); sp_cache_end(); free_status_vars(); - end_thr_alarm(1); /* Free allocated memory */ end_thr_timer(); my_free_open_file_info(); if (defaults_argv) @@ -3110,8 +3103,6 @@ void init_signals(void) struct sigaction sa; DBUG_ENTER("init_signals"); - my_sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called! - if (opt_stack_trace || (test_flags & TEST_CORE_ON_SIGNAL)) { sa.sa_flags = SA_RESETHAND | SA_NODEFER; @@ -3159,7 +3150,6 @@ void init_signals(void) sa.sa_flags = 0; sa.sa_handler = print_signal_warning; sigaction(SIGHUP, &sa, (struct sigaction*) 0); - sigaddset(&set,THR_SERVER_ALARM); if (test_flags & TEST_SIGINT) { /* Allow SIGINT to break mysqld. This is for debugging with --gdb */ @@ -3220,7 +3210,7 @@ pthread_handler_t kill_server_thread(void *arg __attribute__((unused))) #endif -/** This threads handles all signals and alarms. */ +/** This threads handles all signals */ /* ARGSUSED */ pthread_handler_t signal_hand(void *arg __attribute__((unused))) { @@ -3230,13 +3220,6 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) DBUG_ENTER("signal_hand"); signal_thread_in_use= 1; - /* - Setup alarm handler - This should actually be '+ max_number_of_slaves' instead of +10, - but the +10 should be quite safe. - */ - init_thr_alarm(thread_scheduler->max_threads + extra_max_connections + - global_system_variables.max_insert_delayed_threads + 10); if (test_flags & TEST_SIGINT) { /* Allow SIGINT to break mysqld. This is for debugging with --gdb */ @@ -3245,9 +3228,6 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL); } (void) sigemptyset(&set); // Setup up SIGINT for debug -#ifdef USE_ONE_SIGNAL_HAND - (void) sigaddset(&set,THR_SERVER_ALARM); // For alarms -#endif #ifndef IGNORE_SIGHUP_SIGQUIT (void) sigaddset(&set,SIGQUIT); (void) sigaddset(&set,SIGHUP); @@ -3311,7 +3291,7 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) error); #else my_sigset(sig, SIG_IGN); - break_connect_loop(); // MIT THREAD has a alarm thread + break_connect_loop(); #endif } break; @@ -3341,11 +3321,6 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) opt_log ? fixed_log_output_options : LOG_NONE); } break; -#ifdef USE_ONE_SIGNAL_HAND - case THR_SERVER_ALARM: - process_alarm(sig); // Trigger alarms. - break; -#endif default: #ifdef EXTRA_DEBUG sql_print_warning("Got signal: %d error: %d",sig,error); /* purecov: tested */ @@ -5854,7 +5829,7 @@ int mysqld_main(int argc, char **argv) #endif /* - init signals & alarm + init signals After this we can't quit by a simple unireg_abort */ start_signal_handler(); // Creates pidfile diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 70e71d9a21b..eff03efb858 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -47,6 +47,8 @@ #include "probes_mysql.h" #include #include "proxy_protocol.h" +#include +#include PSI_memory_key key_memory_NET_buff; PSI_memory_key key_memory_NET_compress_packet; @@ -62,13 +64,9 @@ PSI_memory_key key_memory_NET_compress_packet; */ #ifdef EXTRA_DEBUG #define EXTRA_DEBUG_fprintf fprintf -#define EXTRA_DEBUG_fflush fflush #define EXTRA_DEBUG_ASSERT DBUG_ASSERT #else static void inline EXTRA_DEBUG_fprintf(...) {} -#ifndef MYSQL_SERVER -static int inline EXTRA_DEBUG_fflush(...) { return 0; } -#endif #endif /* EXTRA_DEBUG */ #ifdef MYSQL_SERVER @@ -92,22 +90,6 @@ static void inline MYSQL_SERVER_my_error(...) {} the client should have a bigger max_allowed_packet. */ -#if defined(_WIN32) || !defined(MYSQL_SERVER) - /* The following is because alarms doesn't work on windows. */ -#ifndef NO_ALARM -#define NO_ALARM -#endif -#endif - -#ifndef NO_ALARM -#include "my_pthread.h" -void sql_print_error(const char *format,...); -#else -#define DONT_USE_THR_ALARM -#endif /* NO_ALARM */ - -#include "thr_alarm.h" - #ifdef MYSQL_SERVER /* The following variables/functions should really not be declared @@ -158,22 +140,18 @@ my_bool my_net_init(NET *net, Vio *vio, void *thd, uint my_flags) net->last_errno=0; net->thread_specific_malloc= MY_TEST(my_flags & MY_THREAD_SPECIFIC); net->thd= 0; -#ifdef MYSQL_SERVER net->extension= NULL; net->thd= thd; -#endif if (vio) { /* For perl DBI/DBD. */ net->fd= vio_fd(vio); -#if defined(MYSQL_SERVER) && !defined(_WIN32) if (!(test_flags & TEST_BLOCKING)) { my_bool old_mode; vio_blocking(vio, FALSE, &old_mode); } -#endif vio_fastsend(vio); } DBUG_RETURN(0); @@ -646,12 +624,7 @@ net_real_write(NET *net,const uchar *packet, size_t len) { size_t length; const uchar *pos,*end; - thr_alarm_t alarmed; -#ifndef NO_ALARM - ALARM alarm_buff; -#endif uint retry_count=0; - my_bool net_blocking = vio_is_blocking(net->vio); DBUG_ENTER("net_real_write"); #if defined(MYSQL_SERVER) @@ -707,62 +680,21 @@ net_real_write(NET *net,const uchar *packet, size_t len) #ifdef DEBUG_DATA_PACKETS DBUG_DUMP("data_written", packet, len); #endif - -#ifndef NO_ALARM - thr_alarm_init(&alarmed); - if (net_blocking) - thr_alarm(&alarmed, net->write_timeout, &alarm_buff); -#else - alarmed=0; - /* Write timeout is set in my_net_set_write_timeout */ -#endif /* NO_ALARM */ - pos= packet; end=pos+len; while (pos != end) { - if ((long) (length= vio_write(net->vio,pos,(size_t) (end-pos))) <= 0) + length= vio_write(net->vio, pos, (size_t) (end - pos)); + if (ssize_t(length) <= 0) { - my_bool interrupted = vio_should_retry(net->vio); -#if !defined(_WIN32) - if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed)) + bool interrupted= vio_should_retry(net->vio); + if (interrupted || !length) { - if (!thr_alarm(&alarmed, net->write_timeout, &alarm_buff)) - { /* Always true for client */ - my_bool old_mode; - while (vio_blocking(net->vio, TRUE, &old_mode) < 0) - { - if (vio_should_retry(net->vio) && retry_count++ < net->retry_count) - continue; - EXTRA_DEBUG_fprintf(stderr, - "%s: my_net_write: fcntl returned error %d, aborting thread\n", - my_progname,vio_errno(net->vio)); - net->error= 2; /* Close socket */ - net->last_errno= ER_NET_PACKET_TOO_LARGE; - MYSQL_SERVER_my_error(ER_NET_PACKET_TOO_LARGE, MYF(0)); - goto end; - } - retry_count=0; - continue; - } + if (retry_count++ < net->retry_count) + continue; } - else -#endif /* !defined(_WIN32) */ - if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) && - interrupted) - { - if (retry_count++ < net->retry_count) - continue; - EXTRA_DEBUG_fprintf(stderr, "%s: write looped, aborting thread\n", - my_progname); - } -#ifndef MYSQL_SERVER - if (vio_errno(net->vio) == SOCKET_EINTR) - { - DBUG_PRINT("warning",("Interrupted write. Retrying...")); - continue; - } -#endif /* !defined(MYSQL_SERVER) */ + EXTRA_DEBUG_fprintf(stderr, "%s: write looped, aborting thread\n", + my_progname); net->error= 2; /* Close socket */ net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED : ER_NET_ERROR_ON_WRITE); @@ -772,112 +704,14 @@ net_real_write(NET *net,const uchar *packet, size_t len) pos+=length; update_statistics(thd_increment_bytes_sent(net->thd, length)); } -#ifndef _WIN32 - end: -#endif #ifdef HAVE_COMPRESS if (net->compress) my_free((void*) packet); #endif - if (thr_alarm_in_use(&alarmed)) - { - my_bool old_mode; - thr_end_alarm(&alarmed); - if (!net_blocking) - vio_blocking(net->vio, net_blocking, &old_mode); - } - net->reading_or_writing=0; - DBUG_RETURN(((int) (pos != end))); + net->reading_or_writing= 0; + DBUG_RETURN(pos != end); } - -/***************************************************************************** -** Read something from server/clinet -*****************************************************************************/ - -#ifndef NO_ALARM - -static my_bool net_safe_read(NET *net, uchar *buff, size_t length, - thr_alarm_t *alarmed) -{ - uint retry_count=0; - while (length > 0) - { - size_t tmp; - if ((long) (tmp= vio_read(net->vio, buff, length)) <= 0) - { - my_bool interrupted = vio_should_retry(net->vio); - if (!thr_got_alarm(alarmed) && interrupted) - { /* Probably in MIT threads */ - if (retry_count++ < net->retry_count) - continue; - } - return 1; - } - length-= tmp; - buff+= tmp; - } - return 0; -} - -/** - Help function to clear the commuication buffer when we get a too big packet. - - @param net Communication handle - @param remain Bytes to read - @param alarmed Parameter for thr_alarm() - @param alarm_buff Parameter for thr_alarm() - - @retval - 0 Was able to read the whole packet - @retval - 1 Got mailformed packet from client -*/ - -static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed, - ALARM *alarm_buff) -{ - longlong limit= net->max_packet_size*net->net_skip_rest_factor; - uint32 old=remain; - DBUG_ENTER("my_net_skip_rest"); - DBUG_PRINT("enter",("bytes_to_skip: %u", (uint) remain)); - - /* The following is good for debugging */ - update_statistics(thd_increment_net_big_packet_count(net->thd, 1)); - - if (!thr_alarm_in_use(alarmed)) - { - my_bool old_mode; - if (thr_alarm(alarmed,net->read_timeout, alarm_buff) || - vio_blocking(net->vio, TRUE, &old_mode) < 0) - DBUG_RETURN(1); /* Can't setup, abort */ - } - for (;;) - { - while (remain > 0) - { - size_t length= MY_MIN(remain, net->max_packet); - if (net_safe_read(net, net->buff, length, alarmed)) - DBUG_RETURN(1); - update_statistics(thd_increment_bytes_received(net->thd, length)); - remain -= (uint32) length; - limit-= length; - if (limit < 0) - DBUG_RETURN(1); - } - if (old != MAX_PACKET_LENGTH) - break; - if (net_safe_read(net, net->buff, NET_HEADER_SIZE, alarmed)) - DBUG_RETURN(1); - limit-= NET_HEADER_SIZE; - old=remain= uint3korr(net->buff); - net->pkt_nr++; - } - DBUG_RETURN(0); -} -#endif /* NO_ALARM */ - - /** Try to parse and process proxy protocol header. @@ -951,26 +785,17 @@ static handle_proxy_header_result handle_proxy_header(NET *net) Returns length of packet. */ -static ulong -my_real_read(NET *net, size_t *complen, - my_bool header __attribute__((unused))) +static ulong my_real_read(NET *net, size_t *complen, + my_bool header __attribute__((unused))) { uchar *pos; size_t length; uint i,retry_count=0; ulong len=packet_error; - my_bool expect_error_packet __attribute__((unused))= 0; - thr_alarm_t alarmed; -#ifndef NO_ALARM - ALARM alarm_buff; -#endif - retry: - my_bool net_blocking=vio_is_blocking(net->vio); uint32 remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE : NET_HEADER_SIZE); -#ifdef MYSQL_SERVER size_t count= remain; struct st_net_server *server_extension= 0; @@ -983,254 +808,143 @@ retry: server_extension->m_before_header(net, user_data, count); } } -#endif *complen = 0; net->reading_or_writing=1; - thr_alarm_init(&alarmed); -#ifndef NO_ALARM - if (net_blocking) - thr_alarm(&alarmed,net->read_timeout,&alarm_buff); -#else - /* Read timeout is set in my_net_set_read_timeout */ -#endif /* NO_ALARM */ - - pos = net->buff + net->where_b; /* net->packet -4 */ - for (i=0 ; i < 2 ; i++) + pos = net->buff + net->where_b; + for (i=0; i < 2 ; i++) + { + while (remain > 0) { - while (remain > 0) + length= vio_read(net->vio, pos, remain); + if ((ssize_t) length <= 0) { - /* First read is done with non blocking mode */ - if ((long) (length= vio_read(net->vio, pos, remain)) <= 0L) + DBUG_PRINT("info", ("vio_read returned %lld errno: %d", + (long long) length, vio_errno(net->vio))); + if (i == 0 && unlikely(thd_net_is_killed((THD *) net->thd))) { - my_bool interrupted = vio_should_retry(net->vio); - - DBUG_PRINT("info",("vio_read returned %ld errno: %d", - (long) length, vio_errno(net->vio))); - - if (i== 0 && unlikely(thd_net_is_killed((THD*) net->thd))) - { - DBUG_PRINT("info", ("thd is killed")); - len= packet_error; - net->error= 0; - net->last_errno= ER_CONNECTION_KILLED; - MYSQL_SERVER_my_error(net->last_errno, MYF(0)); - goto end; - } - -#if !defined(_WIN32) && defined(MYSQL_SERVER) - /* - We got an error that there was no data on the socket. We now set up - an alarm to not 'read forever', change the socket to the blocking - mode and try again - */ - if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed)) - { - if (!thr_alarm(&alarmed,net->read_timeout,&alarm_buff)) /* Don't wait too long */ - { - my_bool old_mode; - while (vio_blocking(net->vio, TRUE, &old_mode) < 0) - { - if (vio_should_retry(net->vio) && - retry_count++ < net->retry_count) - continue; - DBUG_PRINT("error", - ("fcntl returned error %d, aborting thread", - vio_errno(net->vio))); - EXTRA_DEBUG_fprintf(stderr, - "%s: read: fcntl returned error %d, aborting thread\n", - my_progname,vio_errno(net->vio)); - len= packet_error; - net->error= 2; /* Close socket */ - net->last_errno= ER_NET_FCNTL_ERROR; - MYSQL_SERVER_my_error(ER_NET_FCNTL_ERROR, MYF(0)); - goto end; - } - retry_count=0; - continue; - } - } -#endif /* (!defined(_WIN32) && defined(MYSQL_SERVER) */ - if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) && - interrupted) - { /* Probably in MIT threads */ - if (retry_count++ < net->retry_count) - continue; - EXTRA_DEBUG_fprintf(stderr, "%s: read looped with error %d, aborting thread\n", - my_progname,vio_errno(net->vio)); - } -#ifndef MYSQL_SERVER - if (length != 0 && vio_errno(net->vio) == SOCKET_EINTR) - { - DBUG_PRINT("warning",("Interrupted read. Retrying...")); - continue; - } -#endif - DBUG_PRINT("error",("Couldn't read packet: remain: %u errno: %d length: %ld", - remain, vio_errno(net->vio), (long) length)); - len= packet_error; - net->error= 2; /* Close socket */ - net->last_errno= (vio_was_timeout(net->vio) ? - ER_NET_READ_INTERRUPTED : - ER_NET_READ_ERROR); + DBUG_PRINT("info", ("thd is killed")); + len= packet_error; + net->error= 0; + net->last_errno= ER_CONNECTION_KILLED; MYSQL_SERVER_my_error(net->last_errno, MYF(0)); - goto end; - } - remain -= (uint32) length; - pos+= length; - update_statistics(thd_increment_bytes_received(net->thd, length)); + goto end; + } + if (vio_should_retry(net->vio) && retry_count++ < net->retry_count) + continue; + EXTRA_DEBUG_fprintf(stderr, + "%s: read looped with error %d, aborting thread\n", + my_progname, vio_errno(net->vio)); + DBUG_PRINT("error", + ("Couldn't read packet: remain: %u errno: %d length: %ld", + remain, vio_errno(net->vio), (long) length)); + len= packet_error; + net->error= 2; + net->last_errno= (vio_was_timeout(net->vio) ? ER_NET_READ_INTERRUPTED + : ER_NET_READ_ERROR); + MYSQL_SERVER_my_error(net->last_errno, MYF(0)); + goto end; } - + remain-= (uint32) length; + pos+= length; + update_statistics(thd_increment_bytes_received(net->thd, length)); + } #ifdef DEBUG_DATA_PACKETS - DBUG_DUMP("data_read", net->buff+net->where_b, length); + DBUG_DUMP("data_read", net->buff + net->where_b, length); #endif - if (i == 0) - { /* First parts is packet length */ - size_t helping; + if (i == 0) + { + /* First part is packet length */ + size_t helping; #ifndef DEBUG_DATA_PACKETS - DBUG_DUMP("packet_header", net->buff+net->where_b, - NET_HEADER_SIZE); -#endif - if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr) - { -#ifndef MYSQL_SERVER - if (net->buff[net->where_b + 3] == (uchar) (net->pkt_nr -1)) - { - /* - If the server was killed then the server may have missed the - last sent client packet and the packet numbering may be one off. - */ - DBUG_PRINT("warning", ("Found possible out of order packets")); - expect_error_packet= 1; - } - else -#endif - goto packets_out_of_order; - } - net->compress_pkt_nr= ++net->pkt_nr; -#ifdef HAVE_COMPRESS - if (net->compress) - { - /* - The following uint3korr() may read 4 bytes, so make sure we don't - read unallocated or uninitialized memory. The right-hand expression - must match the size of the buffer allocated in net_realloc(). - */ - DBUG_ASSERT(net->where_b + NET_HEADER_SIZE + sizeof(uint32) <= - net->max_packet + NET_HEADER_SIZE + COMP_HEADER_SIZE + 1); - /* - If the packet is compressed then complen > 0 and contains the - number of bytes in the uncompressed packet - */ - *complen=uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE])); - } -#endif - - len=uint3korr(net->buff+net->where_b); - if (!len) /* End of big multi-packet */ - goto end; - helping = MY_MAX(len,*complen) + net->where_b; - /* The necessary size of net->buff */ - if (helping >= net->max_packet) - { - if (net_realloc(net,helping)) - { -#if defined(MYSQL_SERVER) && !defined(NO_ALARM) - if (!net->compress && - !my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff)) - net->error= 3; /* Successfully skiped packet */ -#endif - len= packet_error; /* Return error and close connection */ - goto end; - } - } - pos=net->buff + net->where_b; - remain = (uint32) len; -#ifdef MYSQL_SERVER - if (server_extension != NULL) - { - void *user_data= server_extension->m_user_data; - server_extension->m_after_header(net, user_data, count, 0); - server_extension= NULL; - } + DBUG_DUMP("packet_header", net->buff + net->where_b, NET_HEADER_SIZE); #endif + if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr) + { + goto packets_out_of_order; } -#ifndef MYSQL_SERVER - else if (expect_error_packet) + net->compress_pkt_nr= ++net->pkt_nr; +#ifdef HAVE_COMPRESS + if (net->compress) { /* - This check is safe both for compressed and not compressed protocol - as for the compressed protocol errors are not compressed anymore. + The following uint3korr() may read 4 bytes, so make sure we don't + read unallocated or uninitialized memory. The right-hand expression + must match the size of the buffer allocated in net_realloc(). */ - if (net->buff[net->where_b] != (uchar) 255) - { - /* Restore pkt_nr to original value */ - net->pkt_nr--; - goto packets_out_of_order; - } + DBUG_ASSERT(net->where_b + NET_HEADER_SIZE + sizeof(uint32) <= + net->max_packet + NET_HEADER_SIZE + COMP_HEADER_SIZE + 1); + /* + If the packet is compressed then complen > 0 and contains the + number of bytes in the uncompressed packet + */ + *complen= uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE])); } #endif + + len= uint3korr(net->buff + net->where_b); + if (!len) /* End of big multi-packet */ + goto end; + helping= MY_MAX(len, *complen) + net->where_b; + /* The necessary size of net->buff */ + if (helping >= net->max_packet) + { + if (net_realloc(net, helping)) + { + len= packet_error; /* Return error and close connection */ + goto end; + } + } + pos= net->buff + net->where_b; + remain= (uint32) len; + if (server_extension != NULL) + { + void *user_data= server_extension->m_user_data; + server_extension->m_after_header(net, user_data, count, 0); + server_extension= NULL; + } } + } end: - if (thr_alarm_in_use(&alarmed)) - { - my_bool old_mode; - thr_end_alarm(&alarmed); - if (!net_blocking) - vio_blocking(net->vio, net_blocking, &old_mode); - } net->reading_or_writing=0; #ifdef DEBUG_DATA_PACKETS if (len != packet_error) DBUG_DUMP("data_read", net->buff+net->where_b, len); #endif -#ifdef MYSQL_SERVER if (server_extension != NULL) { void *user_data= server_extension->m_user_data; server_extension->m_after_header(net, user_data, count, 1); DBUG_ASSERT(len == packet_error || len == 0); } -#endif return(len); -packets_out_of_order: +packets_out_of_order : + switch (handle_proxy_header(net)) { - switch (handle_proxy_header(net)) { - case ABORT: - /* error happened, message is already written. */ - len= packet_error; - goto end; - case RETRY: - goto retry; - case IGNORE: - break; - } - - DBUG_PRINT("error", - ("Packets out of order (Found: %d, expected %u)", - (int) net->buff[net->where_b + 3], - net->pkt_nr)); - EXTRA_DEBUG_ASSERT(0); - /* - We don't make noise server side, since the client is expected - to break the protocol for e.g. --send LOAD DATA .. LOCAL where - the server expects the client to send a file, but the client - may reply with a new command instead. - */ -#ifndef MYSQL_SERVER - EXTRA_DEBUG_fflush(stdout); - EXTRA_DEBUG_fprintf(stderr,"Error: Packets out of order (Found: %d, expected %d)\n", - (int) net->buff[net->where_b + 3], - (uint) (uchar) net->pkt_nr); - EXTRA_DEBUG_fflush(stderr); -#endif + case ABORT: + /* error happened, message is already written. */ len= packet_error; - MYSQL_SERVER_my_error(ER_NET_PACKETS_OUT_OF_ORDER, MYF(0)); goto end; + case RETRY: + goto retry; + case IGNORE: + break; } + DBUG_PRINT("error", ("Packets out of order (Found: %d, expected %u)", + (int) net->buff[net->where_b + 3], net->pkt_nr)); + EXTRA_DEBUG_ASSERT(0); + /* + We don't make noise server side, since the client is expected + to break the protocol for e.g. --send LOAD DATA .. LOCAL where + the server expects the client to send a file, but the client + may reply with a new command instead. + */ + len= packet_error; + MYSQL_SERVER_my_error(ER_NET_PACKETS_OUT_OF_ORDER, MYF(0)); + goto end; } diff --git a/sql/slave.cc b/sql/slave.cc index ea34e33338f..0a15cc55146 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -36,7 +36,6 @@ #include "rpl_filter.h" #include "repl_failsafe.h" #include "transaction.h" -#include #include #include #include @@ -1075,24 +1074,11 @@ terminate_slave_thread(THD *thd, mysql_mutex_lock(&thd->LOCK_thd_kill); mysql_mutex_lock(&thd->LOCK_thd_data); -#ifndef DONT_USE_THR_ALARM - /* - Error codes from pthread_kill are: - EINVAL: invalid signal number (can't happen) - ESRCH: thread already killed (can happen, should be ignored) - */ - int err __attribute__((unused))= pthread_kill(thd->real_id, thr_client_alarm); - DBUG_ASSERT(err != EINVAL); -#endif thd->awake_no_mutex(NOT_KILLED); mysql_mutex_unlock(&thd->LOCK_thd_kill); mysql_mutex_unlock(&thd->LOCK_thd_data); - /* - There is a small chance that slave thread might miss the first - alarm. To protect againts it, resend the signal until it reacts - */ struct timespec abstime; set_timespec(abstime,2); error= mysql_cond_timedwait(term_cond, term_lock, &abstime); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index ccd690d98a8..a2414de645b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -48,7 +48,6 @@ #include "sql_audit.h" #include #include -#include #include #include @@ -1903,9 +1902,6 @@ void THD::awake_no_mutex(killed_state state_to_set) } #endif - /* Mark the target thread's alarm request expired, and signal alarm. */ - thr_alarm_kill(thread_id); - /* Send an event to the scheduler that a thread should be killed. */ if (!slave_thread) MYSQL_CALLBACK(scheduler, post_kill_notification, (this)); diff --git a/sql/sql_test.cc b/sql/sql_test.cc index a0b445f3bea..11d0dcf4ce0 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -26,7 +26,6 @@ #include "keycaches.h" #include "my_json_writer.h" #include -#include #include "sql_connect.h" #include "thread_cache.h" #if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_H) @@ -611,17 +610,6 @@ Open streams: %10lu\n", my_file_opened, my_stream_opened); -#ifndef DONT_USE_THR_ALARM - ALARM_INFO alarm_info; - thr_alarm_info(&alarm_info); - printf("\nAlarm status:\n\ -Active alarms: %u\n\ -Max used alarms: %u\n\ -Next alarm time: %lu\n", - alarm_info.active_alarms, - alarm_info.max_used_alarms, - (ulong)alarm_info.next_alarm_time); -#endif display_table_locks(); #if defined(HAVE_MALLINFO2) struct mallinfo2 info = mallinfo2(); diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 9a712fad44c..b06e7ddedcc 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -38,7 +38,6 @@ #include "my_sys.h" #include "events.h" -#include #include "slave.h" #include "rpl_mi.h" #include "rpl_filter.h" @@ -1735,10 +1734,6 @@ Sys_max_binlog_size( static bool fix_max_connections(sys_var *self, THD *thd, enum_var_type type) { -#ifndef EMBEDDED_LIBRARY - resize_thr_alarm(max_connections + extra_max_connections + - global_system_variables.max_insert_delayed_threads + 10); -#endif return false; } @@ -6753,13 +6748,6 @@ static Sys_var_enum Sys_histogram_type( SESSION_VAR(histogram_type), CMD_LINE(REQUIRED_ARG), histogram_types, DEFAULT(2)); -static Sys_var_mybool Sys_no_thread_alarm( - "debug_no_thread_alarm", - "Disable system thread alarm calls. Disabling it may be useful " - "in debugging or testing, never do it in production", - READ_ONLY GLOBAL_VAR(my_disable_thr_alarm), CMD_LINE(OPT_ARG), - DEFAULT(FALSE)); - static Sys_var_mybool Sys_query_cache_strip_comments( "query_cache_strip_comments", "Strip all comments from a query before storing it "