summaryrefslogtreecommitdiffstats
path: root/mysys
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-07-01 18:15:00 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-07-01 18:15:00 +0000
commita2a2e32c02643a0cec111511220227703fda1cd5 (patch)
tree69cc2b631234c2a8e026b9cd4d72676c61c594df /mysys
parentReleasing progress-linux version 1:10.11.8-1~progress7.99u1. (diff)
downloadmariadb-a2a2e32c02643a0cec111511220227703fda1cd5.tar.xz
mariadb-a2a2e32c02643a0cec111511220227703fda1cd5.zip
Merging upstream version 1:11.4.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mysys')
-rw-r--r--mysys/CMakeLists.txt16
-rw-r--r--mysys/array.c43
-rw-r--r--mysys/crc32/crc32_arm64.c28
-rw-r--r--mysys/errors.c2
-rw-r--r--mysys/mf_iocache2.c35
-rw-r--r--mysys/mf_radix.c2
-rw-r--r--mysys/mf_sort.c2
-rw-r--r--mysys/my_alarm.c33
-rw-r--r--mysys/my_alloc.c13
-rw-r--r--mysys/my_bitmap.c25
-rw-r--r--mysys/my_getopt.c2
-rw-r--r--mysys/my_init.c44
-rw-r--r--mysys/my_lock.c26
-rw-r--r--mysys/my_malloc.c1
-rw-r--r--mysys/my_pthread.c5
-rw-r--r--mysys/my_static.c5
-rw-r--r--mysys/my_symlink.c4
-rw-r--r--mysys/my_timezone.cc247
-rw-r--r--mysys/my_winfile.c63
-rw-r--r--mysys/mysys_priv.h7
-rw-r--r--mysys/thr_alarm.c844
-rw-r--r--mysys/thr_lock.c46
22 files changed, 456 insertions, 1037 deletions
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index ab6d9edf..646a8bae 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
@@ -45,7 +45,8 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c my_default.c
my_uuid.c wqueue.c waiting_threads.c ma_dyncol.c ../sql-common/my_time.c
my_rdtsc.c psi_noop.c
my_atomic_writes.c my_cpu.c my_likely.c my_largepage.c
- file_logger.c my_dlerror.c crc32/crc32c.cc)
+ file_logger.c my_dlerror.c crc32/crc32c.cc
+ my_timezone.cc)
IF (WIN32)
SET (MYSYS_SOURCES ${MYSYS_SOURCES}
@@ -63,6 +64,9 @@ IF(MSVC_INTEL)
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
SET (MYSYS_SOURCES ${MYSYS_SOURCES} crc32/crc32c_amd64.cc)
ENDIF()
+ELSEIF(MSVC_ARM64)
+ SET (MYSYS_SOURCES ${MYSYS_SOURCES} crc32/crc32_arm64.c)
+ ADD_DEFINITIONS(-DHAVE_ARMV8_CRC -DHAVE_ARMV8_CRC_CRYPTO_INTRINSICS)
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|i386|i686")
SET(MYSYS_SOURCES ${MYSYS_SOURCES} crc32/crc32_x86.c crc32/crc32c_x86.cc)
IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "5")
@@ -146,10 +150,6 @@ IF(UNIX)
SET (MYSYS_SOURCES ${MYSYS_SOURCES} my_addr_resolve.c my_setuser.c)
ENDIF()
-IF(HAVE_ALARM)
- SET(MYSYS_SOURCES ${MYSYS_SOURCES} my_alarm.c)
-ENDIF()
-
IF(HAVE_MLOCK)
SET(MYSYS_SOURCES ${MYSYS_SOURCES} my_lockmem.c)
ENDIF()
@@ -159,7 +159,9 @@ MAYBE_DISABLE_IPO(mysys)
TARGET_LINK_LIBRARIES(mysys dbug strings ${ZLIB_LIBRARIES}
${LIBNSL} ${LIBM} ${LIBRT} ${CMAKE_DL_LIBS} ${LIBSOCKET} ${LIBEXECINFO})
DTRACE_INSTRUMENT(mysys)
-
+IF(WIN32)
+ TARGET_LINK_LIBRARIES(mysys icuuc icuin)
+ENDIF()
IF (HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
TARGET_LINK_LIBRARIES(mysys atomic)
ENDIF()
diff --git a/mysys/array.c b/mysys/array.c
index 6e871ee6..02a54d44 100644
--- a/mysys/array.c
+++ b/mysys/array.c
@@ -92,7 +92,7 @@ my_bool init_dynamic_array2(PSI_memory_key psi_key, DYNAMIC_ARRAY *array,
my_bool insert_dynamic(DYNAMIC_ARRAY *array, const void * element)
{
void *buffer;
- if (array->elements == array->max_element)
+ if (unlikely(array->elements == array->max_element))
{ /* Call only when necessary */
if (!(buffer=alloc_dynamic(array)))
return TRUE;
@@ -102,7 +102,42 @@ my_bool insert_dynamic(DYNAMIC_ARRAY *array, const void * element)
buffer=array->buffer+(array->elements * array->size_of_element);
array->elements++;
}
- memcpy(buffer,element,(size_t) array->size_of_element);
+ memcpy(buffer, element, array->size_of_element);
+ return FALSE;
+}
+
+
+/* Fast version of appending to dynamic array */
+
+void init_append_dynamic(DYNAMIC_ARRAY_APPEND *append,
+ DYNAMIC_ARRAY *array)
+{
+ append->array= array;
+ append->pos= array->buffer + array->elements * array->size_of_element;
+ append->end= array->buffer + array->max_element * array->size_of_element;
+}
+
+
+my_bool append_dynamic(DYNAMIC_ARRAY_APPEND *append,
+ const void *element)
+{
+ DYNAMIC_ARRAY *array= append->array;
+ size_t size_of_element= array->size_of_element;
+ if (unlikely(append->pos == append->end))
+ {
+ void *buffer;
+ if (!(buffer=alloc_dynamic(array)))
+ return TRUE;
+ append->pos= (uchar*)buffer + size_of_element;
+ append->end= array->buffer + array->max_element * size_of_element;
+ memcpy(buffer, element, size_of_element);
+ }
+ else
+ {
+ array->elements++;
+ memcpy(append->pos, element, size_of_element);
+ append->pos+= size_of_element;
+ }
return FALSE;
}
@@ -281,7 +316,7 @@ my_bool allocate_dynamic(DYNAMIC_ARRAY *array, size_t max_elements)
void get_dynamic(DYNAMIC_ARRAY *array, void *element, size_t idx)
{
- if (idx >= array->elements)
+ if (unlikely(idx >= array->elements))
{
DBUG_PRINT("warning",("To big array idx: %d, array size is %d",
idx,array->elements));
@@ -306,7 +341,7 @@ void delete_dynamic(DYNAMIC_ARRAY *array)
/*
Just mark as empty if we are using a static buffer
*/
- if (!(array->malloc_flags & MY_INIT_BUFFER_USED) && array->buffer)
+ if (array->buffer && !(array->malloc_flags & MY_INIT_BUFFER_USED))
my_free(array->buffer);
array->buffer= 0;
diff --git a/mysys/crc32/crc32_arm64.c b/mysys/crc32/crc32_arm64.c
index 6588606a..df7e6936 100644
--- a/mysys/crc32/crc32_arm64.c
+++ b/mysys/crc32/crc32_arm64.c
@@ -7,7 +7,23 @@ typedef unsigned (*my_crc32_t)(unsigned, const void *, size_t);
#ifdef HAVE_ARMV8_CRC
-# ifdef HAVE_ARMV8_CRYPTO
+#ifdef _WIN32
+#include <windows.h>
+int crc32_aarch64_available(void)
+{
+ return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE);
+}
+
+const char *crc32c_aarch64_available(void)
+{
+ if (crc32_aarch64_available() == 0)
+ return NULL;
+ /* TODO : pmull seems supported, but does not compile*/
+ return "Using ARMv8 crc32 instructions";
+}
+#endif /* _WIN32 */
+
+#ifdef HAVE_ARMV8_CRYPTO
static unsigned crc32c_aarch64_pmull(unsigned, const void *, size_t);
# endif
@@ -31,7 +47,8 @@ my_crc32_t crc32c_aarch64_available(void)
# endif
return NULL;
}
-# else
+
+# else /* __APPLE__ */
# include <sys/auxv.h>
# ifdef __FreeBSD__
static unsigned long getauxval(unsigned int key)
@@ -61,7 +78,7 @@ int crc32_aarch64_available(void)
unsigned long auxv= getauxval(AT_HWCAP);
return (auxv & HWCAP_CRC32) != 0;
}
-# endif
+# endif /* __APPLE__ */
# ifndef __APPLE__
static unsigned crc32c_aarch64(unsigned, const void *, size_t);
@@ -78,7 +95,7 @@ my_crc32_t crc32c_aarch64_available(void)
# endif
return crc32c_aarch64;
}
-# endif
+# endif /* __APPLE__ */
const char *crc32c_aarch64_impl(my_crc32_t c)
{
@@ -123,7 +140,10 @@ asm(".arch_extension crypto");
#else /* HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */
/* Intrinsics header*/
+#ifndef _WIN32
#include <arm_acle.h>
+#endif
+
#include <arm_neon.h>
#define CRC32CX(crc, value) (crc) = __crc32cd((crc), (value))
diff --git a/mysys/errors.c b/mysys/errors.c
index a8be37bf..76ca70fc 100644
--- a/mysys/errors.c
+++ b/mysys/errors.c
@@ -60,6 +60,7 @@ const char *globerrs[GLOBERRS]=
"Lock Pages in memory access rights required",
"Memcntl %s cmd %s error",
"Warning: Charset id '%d' csname '%s' trying to replace existing csname '%s'",
+ "Deprecated program name. It will be removed in a future release, use '%s' instead"
};
void init_glob_errs(void)
@@ -109,6 +110,7 @@ void init_glob_errs()
EE(EE_PERM_LOCK_MEMORY)= "Lock Pages in memory access rights required";
EE(EE_MEMCNTL) = "Memcntl %s cmd %s error";
EE(EE_DUPLICATE_CHARSET)= "Warning: Charset id %d trying to replace csname %s with %s";
+ EE(EE_NAME_DEPRECATED) = "Notice: %s is deprecated and will be removed in a future release, use command '%s'"
}
#endif
diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c
index 4622b686..e134524a 100644
--- a/mysys/mf_iocache2.c
+++ b/mysys/mf_iocache2.c
@@ -74,6 +74,41 @@ int my_b_copy_all_to_file(IO_CACHE *cache, FILE *file)
DBUG_RETURN(my_b_copy_to_file(cache, file, SIZE_T_MAX));
}
+/**
+ Similar to above my_b_copy_to_file(), but destination is another IO_CACHE.
+*/
+int
+my_b_copy_to_cache(IO_CACHE *from_cache, IO_CACHE *to_cache,
+ size_t count)
+{
+ size_t curr_write, bytes_in_cache;
+ DBUG_ENTER("my_b_copy_to_cache");
+
+ bytes_in_cache= my_b_bytes_in_cache(from_cache);
+ do
+ {
+ curr_write= MY_MIN(bytes_in_cache, count);
+ if (my_b_write(to_cache, from_cache->read_pos, curr_write))
+ DBUG_RETURN(1);
+
+ from_cache->read_pos += curr_write;
+ count -= curr_write;
+ } while (count && (bytes_in_cache= my_b_fill(from_cache)));
+ if(from_cache->error == -1)
+ DBUG_RETURN(1);
+ DBUG_RETURN(0);
+}
+
+int my_b_copy_all_to_cache(IO_CACHE *from_cache, IO_CACHE *to_cache)
+{
+ DBUG_ENTER("my_b_copy_all_to_cache");
+ /* Reinit the cache to read from the beginning of the cache */
+ if (reinit_io_cache(from_cache, READ_CACHE, 0L, FALSE, FALSE))
+ DBUG_RETURN(1);
+ DBUG_RETURN(my_b_copy_to_cache(from_cache, to_cache,
+ from_cache->end_of_file));
+}
+
my_off_t my_b_append_tell(IO_CACHE* info)
{
/*
diff --git a/mysys/mf_radix.c b/mysys/mf_radix.c
index 8f044cf9..89a3c4ac 100644
--- a/mysys/mf_radix.c
+++ b/mysys/mf_radix.c
@@ -26,7 +26,7 @@
/* Radixsort */
-my_bool radixsort_is_appliccable(uint n_items, size_t size_of_element)
+my_bool radixsort_is_applicable(uint n_items, size_t size_of_element)
{
return size_of_element <= 20 && n_items >= 1000 && n_items < 100000;
}
diff --git a/mysys/mf_sort.c b/mysys/mf_sort.c
index 24e875b8..79bdfdd2 100644
--- a/mysys/mf_sort.c
+++ b/mysys/mf_sort.c
@@ -23,7 +23,7 @@ void my_string_ptr_sort(uchar *base, uint items, size_t size)
#if INT_MAX > 65536L
uchar **ptr=0;
- if (radixsort_is_appliccable(items, size) &&
+ if (radixsort_is_applicable(items, size) &&
(ptr= (uchar**) my_malloc(PSI_NOT_INSTRUMENTED,
items * sizeof(char*),MYF(0))))
{
diff --git a/mysys/my_alarm.c b/mysys/my_alarm.c
deleted file mode 100644
index ee11dc9c..00000000
--- a/mysys/my_alarm.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (C) 2000 MySQL AB
- Use is subject to license terms
-
- 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 Street, Fifth Floor, Boston, MA 02110-1335 USA */
-
-/* Function to set a varible when we got a alarm */
-/* Used by my_lock samt functions in m_alarm.h */
-
-
-#include "mysys_priv.h"
-#include "my_alarm.h"
-
-#ifdef HAVE_ALARM
-
- /* ARGSUSED */
-sig_handler my_set_alarm_variable(int signo __attribute__((unused)))
-{
- my_have_got_alarm=1; /* Tell program that time expired */
- return;
-}
-
-#endif /* HAVE_ALARM */
diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c
index 22ec265e..39c11365 100644
--- a/mysys/my_alloc.c
+++ b/mysys/my_alloc.c
@@ -677,3 +677,16 @@ LEX_CSTRING safe_lexcstrdup_root(MEM_ROOT *root, const LEX_CSTRING str)
res.length= str.length;
return res;
}
+
+
+LEX_STRING lex_string_casedn_root(MEM_ROOT *root, CHARSET_INFO *cs,
+ const char *str, size_t length)
+{
+ size_t nbytes= length * cs->cset->casedn_multiply(cs);
+ LEX_STRING res= {NULL, 0};
+ if (!(res.str= alloc_root(root, nbytes + 1)))
+ return res;
+ res.length= cs->cset->casedn(cs, str, length, res.str, nbytes);
+ res.str[res.length]= '\0';
+ return res;
+}
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index c9bbcc4b..af102ab0 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -544,9 +544,9 @@ uint bitmap_bits_set(const MY_BITMAP *map)
/**
- Copy bitmaps
+ Copy bitmaps (if source bigger tail is left unchanged)
- @param map1 to-bitmap
+ @param map to-bitmap
@param map2 from-bitmap
@notes
@@ -554,18 +554,19 @@ uint bitmap_bits_set(const MY_BITMAP *map)
In this case, only up to to->n_bits will be copied.
*/
-void bitmap_copy(MY_BITMAP *map1, const MY_BITMAP *map2)
+void bitmap_copy(MY_BITMAP *map, const MY_BITMAP *map2)
{
- my_bitmap_map *to= map1->bitmap, *from= map2->bitmap;
- uint map1_length= no_words_in_map(map1)*sizeof(my_bitmap_map);
- uint map2_length= no_words_in_map(map2)*sizeof(my_bitmap_map);
- uint length= MY_MIN(map1_length, map2_length);
- DBUG_ASSERT_DIFFERENT_BITMAPS(map1,map2);
+ my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end;
+ uint len= no_words_in_map(map), len2 = no_words_in_map(map2);
+ DBUG_ASSERT_DIFFERENT_BITMAPS(map, map2);
- memcpy(to, from, length);
- if (length < map1_length)
- bzero(to + length, map1_length - length);
- *map1->last_word_ptr&= ~map1->last_bit_mask;
+ end= to + MY_MIN(len, len2 - 1);
+ while (to < end)
+ *to++ = *from++;
+
+ if (len2 <= len)
+ *to= (*from & ~map2->last_bit_mask) | (*to & map2->last_bit_mask);
+ *(map->last_word_ptr)&= ~map->last_bit_mask;
}
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index 6b480dae..449302a9 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -907,7 +907,9 @@ static int setval(const struct my_option *opts, void *value, char *argument,
goto ret;
};
}
+
validate_value(opts->name, argument, option_file);
+
DBUG_RETURN(0);
ret:
diff --git a/mysys/my_init.c b/mysys/my_init.c
index 44488e58..485ce163 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -43,6 +43,13 @@ static void setup_codepages();
#define _SC_PAGESIZE _SC_PAGE_SIZE
#endif
+#if defined(__linux__)
+#define EXE_LINKPATH "/proc/self/exe"
+#elif defined(__FreeBSD__)
+/* unfortunately, not mounted by default */
+#define EXE_LINKPATH "/proc/curproc/file"
+#endif
+
extern pthread_key(struct st_my_thread_var*, THR_KEY_mysys);
#define SCALE_SEC 100
@@ -169,15 +176,34 @@ my_bool my_init(void)
mysql_stdin= & instrumented_stdin;
my_progname_short= "unknown";
- if (my_progname)
- my_progname_short= my_progname + dirname_length(my_progname);
-
/* Initialize our mutex handling */
my_mutex_init();
if (my_thread_global_init())
return 1;
+ if (my_progname)
+ {
+ char link_name[FN_REFLEN];
+ my_progname_short= my_progname + dirname_length(my_progname);
+ /*
+ if my_progname_short doesn't start from "mariadb", but it's
+ a symlink to an actual executable, that does - warn the user.
+ First try to find the actual name via /proc, but if it's unmounted
+ (which it usually is on FreeBSD) resort to my_progname
+ */
+ if (strncmp(my_progname_short, "mariadb", 7))
+ {
+ int res= 1;
+#ifdef EXE_LINKPATH
+ res= my_readlink(link_name, EXE_LINKPATH, MYF(0));
+#endif
+ if ((res == 0 || my_readlink(link_name, my_progname, MYF(0)) == 0) &&
+ strncmp(link_name + dirname_length(link_name), "mariadb", 7) == 0)
+ my_error(EE_NAME_DEPRECATED, MYF(MY_WME), link_name);
+ }
+ }
+
#if defined(SAFEMALLOC) && !defined(DBUG_OFF)
dbug_sanity= sf_sanity;
#endif
@@ -442,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,
@@ -461,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},
@@ -478,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},
@@ -500,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_lock.c b/mysys/my_lock.c
index 7597436f..35e159dd 100644
--- a/mysys/my_lock.c
+++ b/mysys/my_lock.c
@@ -16,12 +16,8 @@
#include "mysys_priv.h"
#include "mysys_err.h"
#include <errno.h>
-#undef MY_HOW_OFTEN_TO_ALARM
-#define MY_HOW_OFTEN_TO_ALARM ((int) my_time_to_wait_for_lock)
-#ifdef NO_ALARM_LOOP
-#undef NO_ALARM_LOOP
-#endif
-#include <my_alarm.h>
+/* Wait timeout for short lock (2 seconds) */
+#define NANOSECONDS_TO_WAIT_FOR_LOCK 2000000000ULL
#ifdef _WIN32
#define WIN_LOCK_INFINITE -1
@@ -139,7 +135,6 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
{
#ifdef HAVE_FCNTL
int value;
- ALARM_VARIABLES;
#endif
DBUG_ENTER("my_lock");
@@ -171,6 +166,7 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
if (MyFlags & (MY_NO_WAIT | MY_SHORT_WAIT))
{
+ ulonglong end_time;
if (fcntl(fd,F_SETLK,&lock) != -1) /* Check if we can lock */
DBUG_RETURN(0); /* Ok, file locked */
if (MyFlags & MY_NO_WAIT)
@@ -179,14 +175,16 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
DBUG_RETURN(-1);
}
- DBUG_PRINT("info",("Was locked, trying with alarm"));
- ALARM_INIT;
- while ((value=fcntl(fd,F_SETLKW,&lock)) && ! ALARM_TEST &&
- errno == EINTR)
- { /* Setup again so we don`t miss it */
- ALARM_REINIT;
+ DBUG_PRINT("info",("Was locked, trying with timeout"));
+ end_time= my_interval_timer() + NANOSECONDS_TO_WAIT_FOR_LOCK;
+ while ((value= fcntl(fd, F_SETLKW, &lock)) == -1)
+ {
+ if (errno != EACCES && errno != EAGAIN && errno != EINTR)
+ break;
+ if (my_interval_timer() > end_time)
+ break;
+ my_sleep(1000);
}
- ALARM_END;
if (value != -1)
DBUG_RETURN(0);
if (errno == EINTR)
diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c
index 5a5ed6c8..64c888ff 100644
--- a/mysys/my_malloc.c
+++ b/mysys/my_malloc.c
@@ -66,6 +66,7 @@ void set_malloc_size_cb(MALLOC_SIZE_CB func)
@return A pointer to the allocated memory block, or NULL on failure.
*/
+ATTRIBUTE_MALLOC
void *my_malloc(PSI_memory_key key, size_t size, myf my_flags)
{
my_memory_header *mh;
diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c
index 9bedfe36..d29bbe60 100644
--- a/mysys/my_pthread.c
+++ b/mysys/my_pthread.c
@@ -20,7 +20,6 @@
#include "mysys_priv.h"
#include <signal.h>
#include <m_string.h>
-#include <thr_alarm.h>
#include <my_pthread.h>
#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/my_static.c b/mysys/my_static.c
index d0f20a5c..35e67693 100644
--- a/mysys/my_static.c
+++ b/mysys/my_static.c
@@ -21,8 +21,6 @@
#include "mysys_priv.h"
#include "my_static.h"
-#include "my_alarm.h"
-
PSI_memory_key key_memory_DYNAMIC_STRING;
PSI_memory_key key_memory_IO_CACHE;
@@ -95,9 +93,6 @@ const char *soundex_map= "01230120022455012623010202";
USED_MEM* my_once_root_block=0; /* pointer to first block */
uint my_once_extra=ONCE_ALLOC_INIT; /* Memory to alloc / block */
- /* from my_alarm */
-int volatile my_have_got_alarm=0; /* declare variable to reset */
-ulong my_time_to_wait_for_lock=2; /* In seconds */
/* from errors.c */
#ifdef SHARED_LIBRARY
diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c
index 8238e501..a07f67a1 100644
--- a/mysys/my_symlink.c
+++ b/mysys/my_symlink.c
@@ -45,7 +45,7 @@ int (*mysys_test_invalid_symlink)(const char *filename)= always_valid;
int my_readlink(char *to, const char *filename, myf MyFlags)
{
#ifndef HAVE_READLINK
- strmov(to,filename);
+ strnmov(to, filename, FN_REFLEN);
return 1;
#else
int result=0;
@@ -58,7 +58,7 @@ int my_readlink(char *to, const char *filename, myf MyFlags)
if ((my_errno=errno) == EINVAL)
{
result= 1;
- strmov(to,filename);
+ strnmov(to, filename, FN_REFLEN);
}
else
{
diff --git a/mysys/my_timezone.cc b/mysys/my_timezone.cc
new file mode 100644
index 00000000..d155f014
--- /dev/null
+++ b/mysys/my_timezone.cc
@@ -0,0 +1,247 @@
+/*
+ Copyright (c) 2023 MariaDB
+
+ 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 */
+
+#include <config.h>
+#include <my_global.h>
+#include <my_sys.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+
+#ifdef _WIN32
+#include <icu.h>
+#include <objbase.h>
+#define MAX_TZ_ABBR 64
+
+static bool use_icu_for_tzinfo;
+
+/*
+ Retrieve GMT offset and timezone abbreviation using ICU.
+*/
+static void icu_get_tzinfo(time_t t, my_tz* tz)
+{
+ UErrorCode status= U_ZERO_ERROR;
+ const char *locale= nullptr;
+ UCalendar* cal= ucal_open(nullptr, -1, locale, UCAL_GREGORIAN, &status);
+ ucal_setMillis(cal, 1000.0 * t, &status);
+ int32_t zone_offset= ucal_get(cal, UCAL_ZONE_OFFSET, &status);
+ int32_t dst_offset= ucal_get(cal, UCAL_DST_OFFSET, &status);
+ tz->seconds_offset= (zone_offset + dst_offset) / 1000;
+
+ UChar u_tz_abbr[MAX_TZ_ABBR];
+ ucal_getTimeZoneDisplayName(cal,
+ dst_offset ? UCAL_SHORT_DST : UCAL_SHORT_STANDARD,
+ locale, u_tz_abbr, MAX_TZ_ABBR, &status);
+ ucal_close(cal);
+ size_t num;
+ wcstombs_s(&num, tz->abbreviation, sizeof(tz->abbreviation),
+ (wchar_t *) u_tz_abbr, sizeof(u_tz_abbr));
+}
+
+#define MAX_TIMEZONE_LEN 128
+
+/*
+ Synchronizes C runtime timezone with ICU timezone.
+
+ Must be called after tzset().
+
+ If TZ environment variable is set, tries to find ICU
+ timezone matching the variable value.If such timezone
+ is found, it is set as default timezone for ICU.
+
+ @return 0 success
+ -1 otherwise
+*/
+static int sync_icu_timezone()
+{
+ const char *tz_env= getenv("TZ");
+ UErrorCode ec= U_ZERO_ERROR;
+ UEnumeration *en= nullptr;
+ int ret= -1;
+
+ if (!tz_env)
+ {
+ /* TZ environment variable not set - use default timezone*/
+ return 0;
+ }
+
+ int timezone_offset_ms = -1000 * _timezone;
+ int dst_offset_ms = -1000 * _dstbias *(_daylight != 0);
+
+ /*
+ Find ICU timezone with the same UTC and DST offsets
+ and name as C runtime.
+ */
+ en= ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_ANY, nullptr,
+ &timezone_offset_ms, &ec);
+ if (U_FAILURE(ec))
+ return -1;
+
+ for (;;)
+ {
+ int32_t len;
+ const char *tzid= uenum_next(en, &len, &ec);
+ if (U_FAILURE(ec))
+ break;
+
+ if (!tzid)
+ break;
+ UChar u_tzid[MAX_TIMEZONE_LEN];
+ u_uastrncpy(u_tzid, tzid, MAX_TIMEZONE_LEN);
+ int32_t dst_savings= ucal_getDSTSavings(u_tzid, &ec);
+ if (U_FAILURE(ec))
+ break;
+
+ if (dst_savings == dst_offset_ms)
+ {
+ if (tz_env && !strcmp(tzid, tz_env))
+ {
+ /*
+ Found timezone ID that matches TZ env.var
+ exactly, e.g PST8PDT
+ */
+ UChar u_tzid[MAX_TIMEZONE_LEN];
+ u_uastrncpy(u_tzid, tzid, MAX_TIMEZONE_LEN);
+ ucal_setDefaultTimeZone(u_tzid, &ec);
+ ret= 0;
+ break;
+ }
+ }
+ }
+ uenum_close(en);
+ return ret;
+}
+#endif /* _WIN32 */
+
+/**
+ Initialize time conversion information
+
+ @param[out] sys_timezone name of the current timezone
+ @param[in] sys_timezone_len length of the 'sys_timezone' buffer
+
+*/
+extern "C" void my_tzset()
+{
+ tzset();
+#ifdef _WIN32
+ /*
+ CoInitializeEx is needed by ICU on older Windows 10, until
+ version 1903.
+ */
+ (void) CoInitializeEx(NULL, COINITBASE_MULTITHREADED);
+ use_icu_for_tzinfo= !sync_icu_timezone();
+#endif
+}
+
+/**
+ Retrieve current timezone name
+ @param[out] sys_timezone - buffer to receive timezone name
+ @param[in] size - size of sys_timezone buffer
+*/
+extern "C" void my_tzname(char* sys_timezone, size_t size)
+{
+#ifdef _WIN32
+ if (use_icu_for_tzinfo)
+ {
+ /* TZ environment variable not set - return default timezone name*/
+ UChar default_tzname[MAX_TIMEZONE_LEN];
+ UErrorCode ec;
+ int32_t len=
+ ucal_getDefaultTimeZone(default_tzname, MAX_TIMEZONE_LEN, &ec);
+ if (U_SUCCESS(ec))
+ {
+ u_austrncpy(sys_timezone, default_tzname, (int32_t) size);
+ return;
+ }
+ use_icu_for_tzinfo= false;
+ }
+#endif
+ struct tm tm;
+ time_t t;
+ tzset();
+ t= time(NULL);
+ localtime_r(&t, &tm);
+ const char *tz_name= tzname[tm.tm_isdst != 0 ? 1 : 0];
+ snprintf(sys_timezone, size, "%s", tz_name);
+}
+
+#ifndef STRUCT_TM_HAS_TM_GMTOFF
+/*
+ Portable timegm()
+
+ Based on http://howardhinnant.github.io/date_algorithms.html
+ by Howard Hinnant, of the C++ <chrono> library fame.
+*/
+
+/** Returns number of days since Unix epoch. */
+static int days_from_epoch(int y, int m, int d)
+{
+ y-= m <= 2;
+ int era= y / 400;
+ int yoe= y - era * 400; // [0, 399]
+ int doy= (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1; // [0, 365]
+ int doe= yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096]
+ return era * 146097 + doe - 719468;
+}
+
+/**
+ Converts a UTC time represented by a struct tm to time_t.
+
+ Unlike libc's timegm() or Windows' _mkgmtime(), this function
+ does not modify the input struct.
+*/
+static time_t my_timegm(const struct tm *t)
+{
+ longlong days, hours, minutes, seconds;
+ days= (longlong) days_from_epoch(t->tm_year+1900, t->tm_mon+1, t->tm_mday);
+ hours= 24LL * days + t->tm_hour;
+ minutes= 60LL * hours + t->tm_min;
+ seconds= 60LL * minutes + t->tm_sec;
+ return (time_t) seconds;
+}
+#endif /* STRUCT_TM_HAS_TM_GMTOFF */
+
+/**
+ Return timezone information (GMT offset, timezone abbreviation)
+ corresponding to specific timestamp.
+
+ @param[in] t timestamp (seconds since Unix epoch)
+ @param[out] gmt_offset offset from GMT, in seconds
+ @param[out] abbr buffer to receive time zone abbreviation
+ @param[in] abbr_size size of the abbr buffer
+*/
+void my_tzinfo(time_t t, struct my_tz* tz)
+{
+#ifdef _WIN32
+ if (use_icu_for_tzinfo)
+ {
+ icu_get_tzinfo(t, tz);
+ return;
+ }
+#endif
+
+ struct tm loc_time;
+ localtime_r(&t, &loc_time);
+#ifdef STRUCT_TM_HAS_TM_GMTOFF
+ tz->seconds_offset= loc_time.tm_gmtoff;
+ snprintf(tz->abbreviation, sizeof(tz->abbreviation), "%s", loc_time.tm_zone);
+#else
+ tz->seconds_offset= (long) (my_timegm(&loc_time) - t);
+ int is_dst= loc_time.tm_isdst ? 1 : 0;
+ snprintf(tz->abbreviation, sizeof(tz->abbreviation), "%s", tzname[is_dst]);
+#endif
+}
diff --git a/mysys/my_winfile.c b/mysys/my_winfile.c
index 35bc6b35..7a1e3e60 100644
--- a/mysys/my_winfile.c
+++ b/mysys/my_winfile.c
@@ -89,17 +89,15 @@ static void invalidate_fd(File fd)
/* Get Windows handle for a file descriptor */
HANDLE my_get_osfhandle(File fd)
{
- DBUG_ENTER("my_get_osfhandle");
DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit);
- DBUG_RETURN(my_file_info[fd].fhandle);
+ return (my_file_info[fd].fhandle);
}
static int my_get_open_flags(File fd)
{
- DBUG_ENTER("my_get_open_flags");
DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit);
- DBUG_RETURN(my_file_info[fd].oflag);
+ return (my_file_info[fd].oflag);
}
/*
@@ -347,10 +345,8 @@ size_t my_win_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset)
OVERLAPPED ov= {0};
LARGE_INTEGER li;
- DBUG_ENTER("my_win_pread");
-
if(!Count)
- DBUG_RETURN(0);
+ return(0);
#ifdef _WIN64
if(Count > UINT_MAX)
Count= UINT_MAX;
@@ -369,11 +365,11 @@ size_t my_win_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset)
through e.g. a command pipe in windows : see MSDN on ReadFile.
*/
if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE)
- DBUG_RETURN(0); /*return 0 at EOF*/
+ return(0); /*return 0 at EOF*/
my_osmaperr(lastError);
- DBUG_RETURN((size_t)-1);
+ return((size_t)-1);
}
- DBUG_RETURN(nBytesRead);
+ return(nBytesRead);
}
@@ -382,9 +378,8 @@ size_t my_win_read(File Filedes, uchar *Buffer, size_t Count)
DWORD nBytesRead;
HANDLE hFile;
- DBUG_ENTER("my_win_read");
if(!Count)
- DBUG_RETURN(0);
+ return(0);
#ifdef _WIN64
if(Count > UINT_MAX)
Count= UINT_MAX;
@@ -400,11 +395,11 @@ size_t my_win_read(File Filedes, uchar *Buffer, size_t Count)
through e.g. a command pipe in windows : see MSDN on ReadFile.
*/
if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE)
- DBUG_RETURN(0); /*return 0 at EOF*/
+ return(0); /*return 0 at EOF*/
my_osmaperr(lastError);
- DBUG_RETURN((size_t)-1);
+ return((size_t)-1);
}
- DBUG_RETURN(nBytesRead);
+ return(nBytesRead);
}
@@ -416,12 +411,8 @@ size_t my_win_pwrite(File Filedes, const uchar *Buffer, size_t Count,
OVERLAPPED ov= {0};
LARGE_INTEGER li;
- DBUG_ENTER("my_win_pwrite");
- DBUG_PRINT("my",("Filedes: %d, Buffer: %p, Count: %llu, offset: %llu",
- Filedes, Buffer, (ulonglong)Count, (ulonglong)offset));
-
if(!Count)
- DBUG_RETURN(0);
+ return(0);
#ifdef _WIN64
if(Count > UINT_MAX)
@@ -436,10 +427,10 @@ size_t my_win_pwrite(File Filedes, const uchar *Buffer, size_t Count,
if(!WriteFile(hFile, Buffer, (DWORD)Count, &nBytesWritten, &ov))
{
my_osmaperr(GetLastError());
- DBUG_RETURN((size_t)-1);
+ return((size_t)-1);
}
else
- DBUG_RETURN(nBytesWritten);
+ return(nBytesWritten);
}
@@ -448,11 +439,9 @@ my_off_t my_win_lseek(File fd, my_off_t pos, int whence)
LARGE_INTEGER offset;
LARGE_INTEGER newpos;
- DBUG_ENTER("my_win_lseek");
-
/* Check compatibility of Windows and Posix seek constants */
- compile_time_assert(FILE_BEGIN == SEEK_SET && FILE_CURRENT == SEEK_CUR
- && FILE_END == SEEK_END);
+ compile_time_assert(FILE_BEGIN == SEEK_SET && FILE_CURRENT == SEEK_CUR &&
+ FILE_END == SEEK_END);
offset.QuadPart= pos;
if(!SetFilePointerEx(my_get_osfhandle(fd), offset, &newpos, whence))
@@ -460,7 +449,7 @@ my_off_t my_win_lseek(File fd, my_off_t pos, int whence)
my_osmaperr(GetLastError());
newpos.QuadPart= -1;
}
- DBUG_RETURN(newpos.QuadPart);
+ return(newpos.QuadPart);
}
@@ -474,12 +463,8 @@ size_t my_win_write(File fd, const uchar *Buffer, size_t Count)
OVERLAPPED *pov= NULL;
HANDLE hFile;
- DBUG_ENTER("my_win_write");
- DBUG_PRINT("my",("Filedes: %d, Buffer: %p, Count %llu", fd, Buffer,
- (ulonglong)Count));
-
if(!Count)
- DBUG_RETURN(0);
+ return(0);
#ifdef _WIN64
if(Count > UINT_MAX)
@@ -502,9 +487,9 @@ size_t my_win_write(File fd, const uchar *Buffer, size_t Count)
if(!WriteFile(hFile, Buffer, (DWORD)Count, &nWritten, pov))
{
my_osmaperr(GetLastError());
- DBUG_RETURN((size_t)-1);
+ return((size_t)-1);
}
- DBUG_RETURN(nWritten);
+ return(nWritten);
}
@@ -512,7 +497,6 @@ int my_win_chsize(File fd, my_off_t newlength)
{
HANDLE hFile;
LARGE_INTEGER length;
- DBUG_ENTER("my_win_chsize");
hFile= (HANDLE) my_get_osfhandle(fd);
length.QuadPart= newlength;
@@ -520,11 +504,11 @@ int my_win_chsize(File fd, my_off_t newlength)
goto err;
if (!SetEndOfFile(hFile))
goto err;
- DBUG_RETURN(0);
+ return(0);
err:
my_osmaperr(GetLastError());
my_errno= errno;
- DBUG_RETURN(-1);
+ return(-1);
}
@@ -555,7 +539,6 @@ File my_win_handle2File(HANDLE hFile)
{
int retval= -1;
uint i;
-
DBUG_ENTER("my_win_handle2File");
for(i= MY_FILE_MIN; i < my_file_limit; i++)
@@ -623,7 +606,6 @@ FILE * my_win_fdopen(File fd, const char *type)
FILE *file;
int crt_fd;
int flags= 0;
-
DBUG_ENTER("my_win_fdopen");
if(strchr(type,'a') != NULL)
@@ -641,8 +623,8 @@ FILE * my_win_fdopen(File fd, const char *type)
int my_win_fclose(FILE *file)
{
File fd;
-
DBUG_ENTER("my_win_fclose");
+
fd= my_fileno(file);
if(fd < 0)
DBUG_RETURN(-1);
@@ -665,7 +647,6 @@ int my_win_fstat(File fd, struct _stati64 *buf)
int crt_fd;
int retval;
HANDLE hFile, hDup;
-
DBUG_ENTER("my_win_fstat");
hFile= my_get_osfhandle(fd);
diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h
index e795dbe2..efeb0c65 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 4e2db203..00000000
--- a/mysys/thr_alarm.c
+++ /dev/null
@@ -1,844 +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 <my_global.h>
-
-#if !defined(DONT_USE_THR_ALARM)
-#include <errno.h>
-#include <my_pthread.h>
-#include <signal.h>
-#include <my_sys.h>
-#include <m_string.h>
-#include <queues.h>
-#include "thr_alarm.h"
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h> /* 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"));
-
- 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*) &param[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/mysys/thr_lock.c b/mysys/thr_lock.c
index 214ff01b..de982806 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -1386,52 +1386,6 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id)
}
-/*
- Downgrade a WRITE_* to a lower WRITE level
- SYNOPSIS
- thr_downgrade_write_lock()
- in_data Lock data of thread downgrading its lock
- new_lock_type New write lock type
- RETURN VALUE
- NONE
- DESCRIPTION
- This can be used to downgrade a lock already owned. When the downgrade
- occurs also other waiters, both readers and writers can be allowed to
- start.
- The previous lock is often TL_WRITE_ONLY but can also be
- TL_WRITE. The normal downgrade variants are:
- TL_WRITE_ONLY => TL_WRITE after a short exclusive lock while holding a
- write table lock
- TL_WRITE_ONLY => TL_WRITE_ALLOW_WRITE After a short exclusive lock after
- already earlier having dongraded lock to TL_WRITE_ALLOW_WRITE
- The implementation is conservative and rather don't start rather than
- go on unknown paths to start, the common cases are handled.
-
- NOTE:
- In its current implementation it is only allowed to downgrade from
- TL_WRITE_ONLY. In this case there are no waiters. Thus no wake up
- logic is required.
-*/
-
-void thr_downgrade_write_lock(THR_LOCK_DATA *in_data,
- enum thr_lock_type new_lock_type)
-{
- THR_LOCK *lock=in_data->lock;
-#ifdef DBUG_ASSERT_EXISTS
- enum thr_lock_type old_lock_type= in_data->type;
-#endif
- DBUG_ENTER("thr_downgrade_write_only_lock");
-
- mysql_mutex_lock(&lock->mutex);
- DBUG_ASSERT(old_lock_type == TL_WRITE_ONLY);
- DBUG_ASSERT(old_lock_type > new_lock_type);
- in_data->type= new_lock_type;
- check_locks(lock,"after downgrading lock", old_lock_type, 0);
-
- mysql_mutex_unlock(&lock->mutex);
- DBUG_VOID_RETURN;
-}
-
/* Upgrade a WRITE_DELAY lock to a WRITE_LOCK */
my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data,