summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
Diffstat (limited to 'mysys')
-rw-r--r--mysys/.cvsignore10
-rw-r--r--mysys/CMakeLists.txt98
-rw-r--r--mysys/Makefile.am156
-rw-r--r--mysys/array.c21
-rw-r--r--mysys/base64.c6
-rw-r--r--mysys/charset-def.c167
-rw-r--r--mysys/charset.c124
-rw-r--r--mysys/checksum.c10
-rw-r--r--mysys/default.c197
-rw-r--r--mysys/default_modify.c252
-rw-r--r--mysys/errors.c14
-rw-r--r--mysys/hash.c76
-rw-r--r--mysys/lf_alloc-pin.c69
-rw-r--r--mysys/lf_dynarray.c15
-rw-r--r--mysys/lf_hash.c37
-rw-r--r--mysys/list.c8
-rw-r--r--mysys/ma_dyncol.c8
-rwxr-xr-xmysys/make-ccc4
-rw-r--r--mysys/make-conf.c71
-rw-r--r--mysys/md5.c2
-rw-r--r--mysys/mf_brkhant.c72
-rw-r--r--mysys/mf_cache.c14
-rw-r--r--mysys/mf_dirname.c21
-rw-r--r--mysys/mf_fn_ext.c6
-rw-r--r--mysys/mf_format.c9
-rw-r--r--mysys/mf_getdate.c6
-rw-r--r--mysys/mf_iocache.c204
-rw-r--r--mysys/mf_iocache2.c80
-rw-r--r--mysys/mf_keycache.c259
-rw-r--r--mysys/mf_keycaches.c5
-rw-r--r--mysys/mf_loadpath.c3
-rw-r--r--mysys/mf_pack.c82
-rw-r--r--mysys/mf_path.c13
-rw-r--r--mysys/mf_sort.c6
-rw-r--r--mysys/mf_tempdir.c23
-rw-r--r--mysys/mf_tempfile.c24
-rw-r--r--mysys/mf_unixpath.c15
-rw-r--r--mysys/mf_util.c47
-rw-r--r--mysys/mf_wfile.c126
-rw-r--r--mysys/my_access.c20
-rw-r--r--mysys/my_addr_resolve.c198
-rw-r--r--mysys/my_alloc.c14
-rw-r--r--mysys/my_append.c64
-rw-r--r--mysys/my_atomic.c42
-rw-r--r--mysys/my_basename.c41
-rw-r--r--mysys/my_bit.c11
-rw-r--r--mysys/my_bitmap.c279
-rw-r--r--mysys/my_chsize.c12
-rw-r--r--mysys/my_clock.c32
-rw-r--r--mysys/my_compare.c49
-rw-r--r--mysys/my_compress.c18
-rw-r--r--mysys/my_context.c728
-rw-r--r--mysys/my_copy.c21
-rw-r--r--mysys/my_create.c14
-rw-r--r--mysys/my_delete.c51
-rw-r--r--mysys/my_dup.c41
-rw-r--r--mysys/my_error.c65
-rw-r--r--mysys/my_file.c5
-rw-r--r--mysys/my_fopen.c16
-rw-r--r--mysys/my_fstream.c14
-rw-r--r--mysys/my_gethwaddr.c10
-rw-r--r--mysys/my_getncpus.c11
-rw-r--r--mysys/my_getopt.c708
-rw-r--r--mysys/my_getsystime.c11
-rw-r--r--mysys/my_getwd.c30
-rw-r--r--mysys/my_handler_errors.h24
-rw-r--r--mysys/my_init.c405
-rw-r--r--mysys/my_largepage.c29
-rw-r--r--mysys/my_lib.c167
-rw-r--r--mysys/my_lock.c70
-rw-r--r--mysys/my_lockmem.c21
-rw-r--r--mysys/my_malloc.c110
-rw-r--r--mysys/my_mess.c (renamed from mysys/my_messnc.c)18
-rw-r--r--mysys/my_mmap.c22
-rw-r--r--mysys/my_net.c134
-rw-r--r--mysys/my_netware.c150
-rw-r--r--mysys/my_new.cc49
-rw-r--r--mysys/my_once.c16
-rw-r--r--mysys/my_open.c21
-rw-r--r--mysys/my_pread.c30
-rw-r--r--mysys/my_pthread.c177
-rw-r--r--mysys/my_quick.c5
-rw-r--r--mysys/my_rdtsc.c962
-rw-r--r--mysys/my_read.c13
-rw-r--r--mysys/my_realloc.c79
-rw-r--r--mysys/my_redel.c22
-rw-r--r--mysys/my_rename.c22
-rw-r--r--mysys/my_safehash.c36
-rw-r--r--mysys/my_safehash.h4
-rw-r--r--mysys/my_seek.c26
-rw-r--r--mysys/my_sleep.c8
-rw-r--r--mysys/my_static.c86
-rw-r--r--mysys/my_static.h40
-rw-r--r--mysys/my_symlink.c3
-rw-r--r--mysys/my_sync.c32
-rw-r--r--mysys/my_thr_init.c451
-rw-r--r--mysys/my_timer_cycles.il39
-rw-r--r--mysys/my_uuid.c12
-rw-r--r--mysys/my_vle.c109
-rw-r--r--mysys/my_wincond.c42
-rw-r--r--mysys/my_windac.c12
-rw-r--r--mysys/my_winerr.c5
-rw-r--r--mysys/my_winfile.c8
-rw-r--r--mysys/my_winthread.c172
-rw-r--r--mysys/my_write.c18
-rw-r--r--mysys/mysys_priv.h110
-rw-r--r--mysys/ptr_cmp.c41
-rw-r--r--mysys/queues.c7
-rw-r--r--mysys/rijndael.c20
-rw-r--r--mysys/safemalloc.c696
-rw-r--r--mysys/stacktrace.c228
-rw-r--r--mysys/string.c19
-rw-r--r--mysys/test_charset.c14
-rw-r--r--mysys/test_fn.c69
-rw-r--r--mysys/testhash.c6
-rw-r--r--mysys/thr_alarm.c227
-rw-r--r--mysys/thr_lock.c607
-rw-r--r--mysys/thr_mutex.c61
-rw-r--r--mysys/thr_rwlock.c167
-rw-r--r--mysys/tree.c8
-rw-r--r--mysys/trie.c236
-rw-r--r--mysys/typelib.c293
-rw-r--r--mysys/waiting_threads.c34
-rw-r--r--mysys/wqueue.c26
124 files changed, 5706 insertions, 5677 deletions
diff --git a/mysys/.cvsignore b/mysys/.cvsignore
deleted file mode 100644
index 056ecc2691c..00000000000
--- a/mysys/.cvsignore
+++ /dev/null
@@ -1,10 +0,0 @@
-.deps
-.libs
-Makefile
-Makefile.in
-st35l1t6
-test_charset
-test_thr_alarm
-test_thr_lock
-test_vsnprintf
-testhash
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index 9e35a98faac..832cd01e263 100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -11,42 +11,74 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/mysys)
-# Only the server link with this library, the client libraries and the client
-# executables all link with recompiles of source found in the "mysys" directory.
-# So we only need to create one version of this library, with the "static"
-# Thread Local Storage model.
-#
-# Exception is the embedded server that needs this library compiled with
-# dynamic TLS, i.e. define USE_TLS
-
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/zlib ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/mysys)
-
-SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_modify.c
- errors.c hash.c list.c md5.c mf_brkhant.c mf_cache.c mf_dirname.c mf_fn_ext.c
- mf_format.c mf_getdate.c mf_iocache.c mf_iocache2.c mf_keycache.c my_safehash.c
+SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c
+ errors.c hash.c list.c md5.c mf_cache.c mf_dirname.c mf_fn_ext.c
+ mf_format.c mf_getdate.c mf_iocache.c mf_iocache2.c mf_keycache.c
mf_keycaches.c mf_loadpath.c mf_pack.c mf_path.c mf_qsort.c mf_qsort2.c
mf_radix.c mf_same.c mf_sort.c mf_soundex.c mf_arr_appstr.c mf_tempdir.c
- mf_tempfile.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_access.c
- my_aes.c my_alarm.c my_alloc.c my_append.c my_bit.c my_bitmap.c my_chmod.c my_chsize.c
- my_clock.c my_compress.c my_conio.c my_copy.c my_crc32.c my_create.c my_delete.c
+ mf_tempfile.c mf_unixpath.c mf_wcomp.c mulalloc.c my_access.c
+ my_aes.c my_alloc.c my_bit.c my_bitmap.c my_chsize.c
+ my_compress.c my_copy.c my_create.c my_delete.c
my_div.c my_error.c my_file.c my_fopen.c my_fstream.c
my_gethwaddr.c my_getopt.c my_getsystime.c my_getwd.c my_compare.c my_init.c
- my_lib.c my_lock.c my_lockmem.c my_malloc.c my_messnc.c
- my_mkdir.c my_mmap.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c
- my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_sleep.c
- my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c
- my_winerr.c my_winfile.c my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c stacktrace.c
- rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
- thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c ma_dyncol.c
- lf_alloc-pin.c lf_dynarray.c lf_hash.c
- my_atomic.c my_getncpus.c my_rnd.c
- my_uuid.c wqueue.c waiting_threads.c
-)
-
-IF(NOT SOURCE_SUBLIBS)
- ADD_LIBRARY(mysys ${MYSYS_SOURCES})
- TARGET_LINK_LIBRARIES(mysys IPHLPAPI)
-ENDIF(NOT SOURCE_SUBLIBS)
+ my_lib.c my_lock.c my_malloc.c my_mess.c
+ my_mkdir.c my_mmap.c my_once.c my_open.c my_pread.c my_pthread.c
+ my_quick.c my_read.c my_redel.c my_rename.c my_seek.c my_sleep.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
+ rijndael.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
+ thr_rwlock.c tree.c typelib.c base64.c my_memmem.c my_getpagesize.c
+ lf_alloc-pin.c lf_dynarray.c lf_hash.c
+ safemalloc.c my_new.cc
+ my_atomic.c my_getncpus.c my_safehash.c my_chmod.c my_rnd.c
+ my_uuid.c wqueue.c waiting_threads.c ma_dyncol.c
+ my_rdtsc.c my_context.c)
+
+IF (WIN32)
+ SET (MYSYS_SOURCES ${MYSYS_SOURCES} my_winthread.c my_wincond.c my_winerr.c my_winfile.c my_windac.c my_conio.c)
+ENDIF()
+
+IF(UNIX)
+ SET (MYSYS_SOURCES ${MYSYS_SOURCES} my_addr_resolve.c)
+ENDIF()
+
+IF(HAVE_ALARM)
+ SET(MYSYS_SOURCES ${MYSYS_SOURCES} my_alarm.c)
+ENDIF()
+
+IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND CMAKE_C_COMPILER_ID MATCHES "SunPro")
+ # Inline assembly template for rdtsc
+ SET_SOURCE_FILES_PROPERTIES(my_rdtsc.c
+ PROPERTIES COMPILE_FLAGS "${CMAKE_CURRENT_SOURCE_DIR}/my_timer_cycles.il")
+ENDIF()
+
+IF(HAVE_LARGE_PAGES)
+ SET(MYSYS_SOURCES ${MYSYS_SOURCES} my_largepage.c)
+ENDIF()
+
+IF(HAVE_MLOCK)
+ SET(MYSYS_SOURCES ${MYSYS_SOURCES} my_lockmem.c)
+ENDIF()
+
+ADD_CONVENIENCE_LIBRARY(mysys ${MYSYS_SOURCES})
+TARGET_LINK_LIBRARIES(mysys dbug strings ${ZLIB_LIBRARY}
+ ${LIBNSL} ${LIBM} ${LIBRT} ${LIBSOCKET} ${LIBEXECINFO})
+DTRACE_INSTRUMENT(mysys)
+
+IF(HAVE_BFD_H)
+ TARGET_LINK_LIBRARIES(mysys bfd)
+ENDIF(HAVE_BFD_H)
+
+IF (WIN32)
+ TARGET_LINK_LIBRARIES(mysys IPHLPAPI)
+ENDIF(WIN32)
+
+ADD_EXECUTABLE(thr_lock thr_lock.c)
+TARGET_LINK_LIBRARIES(thr_lock mysys)
+SET_TARGET_PROPERTIES(thr_lock PROPERTIES COMPILE_FLAGS "-DMAIN")
+
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
deleted file mode 100644
index eb263ee34c6..00000000000
--- a/mysys/Makefile.am
+++ /dev/null
@@ -1,156 +0,0 @@
-# Copyright (c) 2000, 2011, Oracle and/or its affiliates
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-MYSQLDATAdir = $(localstatedir)
-MYSQLSHAREdir = $(pkgdatadir)
-MYSQLBASEdir= $(prefix)
-INCLUDES = @ZLIB_INCLUDES@ -I$(top_builddir)/include \
- -I$(top_srcdir)/include -I$(srcdir)
-pkglib_LIBRARIES = libmysys.a
-noinst_LTLIBRARIES = libmysys.la
-LDADD = libmysys.a $(top_builddir)/strings/libmystrings.a $(top_builddir)/dbug/libdbug.a
-noinst_HEADERS = mysys_priv.h my_static.h my_handler_errors.h \
- my_safehash.h
-libmysys_la_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
- mf_path.c mf_loadpath.c my_file.c \
- my_open.c my_create.c my_dup.c my_seek.c my_read.c \
- my_pread.c my_write.c my_getpagesize.c \
- my_crc32.c ma_dyncol.c \
- mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \
- mf_tempdir.c my_lock.c mf_brkhant.c my_alarm.c \
- my_malloc.c my_realloc.c my_once.c mulalloc.c \
- my_alloc.c safemalloc.c my_new.cc \
- my_vle.c my_atomic.c \
- my_safehash.c lf_hash.c lf_dynarray.c lf_alloc-pin.c \
- my_rnd.c my_uuid.c my_chmod.c \
- my_fopen.c my_fstream.c my_getsystime.c \
- my_error.c errors.c my_div.c my_messnc.c \
- mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
- my_symlink.c my_symlink2.c \
- mf_pack.c mf_unixpath.c mf_arr_appstr.c \
- mf_wcomp.c mf_wfile.c my_gethwaddr.c \
- mf_qsort.c mf_qsort2.c mf_sort.c \
- ptr_cmp.c mf_radix.c queues.c my_getncpus.c \
- tree.c trie.c list.c hash.c array.c string.c \
- typelib.c \
- my_copy.c my_append.c my_lib.c \
- my_delete.c my_rename.c my_redel.c \
- my_chsize.c my_clock.c \
- my_quick.c my_lockmem.c my_static.c \
- my_sync.c my_getopt.c my_mkdir.c \
- default_modify.c default.c \
- my_compress.c checksum.c \
- my_net.c my_port.c my_sleep.c \
- charset.c charset-def.c my_bitmap.c my_bit.c md5.c \
- rijndael.c my_aes.c sha1.c \
- my_compare.c my_netware.c my_largepage.c \
- my_memmem.c stacktrace.c \
- my_windac.c my_access.c base64.c my_libwrap.c \
- wqueue.c
-libmysys_la_LDFLAGS = $(AM_LDFLAGS) @WRAPLIBS@
-libmysys_la_LIBADD = $(ZLIB_LIBS)
-
-if NEED_THREAD
-# mf_keycache is used only in the server, so it is safe to leave the file
-# out of the non-threaded library.
-# In fact, it will currently not compile without thread support.
-libmysys_la_SOURCES += thr_alarm.c thr_lock.c thr_mutex.c thr_rwlock.c \
- my_pthread.c my_thr_init.c waiting_threads.c \
- mf_keycache.c mf_keycaches.c
-endif
-
-EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
- thr_mutex.c thr_rwlock.c waiting_threads.c \
- CMakeLists.txt mf_soundex.c \
- my_conio.c my_wincond.c my_winthread.c my_winfile.c my_winerr.c
-# test_dir_DEPENDENCIES= $(LIBRARIES)
-# testhash_DEPENDENCIES= $(LIBRARIES)
-# test_charset_DEPENDENCIES= $(LIBRARIES)
-# charset2html_DEPENDENCIES= $(LIBRARIES)
-DEFS = -DDEFAULT_BASEDIR='"$(prefix)"' \
- -DMYSQL_DATADIR='"$(MYSQLDATAdir)"' \
- -DDEFAULT_CHARSET_HOME='"$(MYSQLBASEdir)"' \
- -DSHAREDIR'="$(MYSQLSHAREdir)"' \
- -DDEFAULT_HOME_ENV=MYSQL_HOME \
- -DDEFAULT_GROUP_SUFFIX_ENV=MYSQL_GROUP_SUFFIX \
- -DDEFAULT_SYSCONFDIR='"$(sysconfdir)"' \
- @DEFS@
-
-# I hope this always does the right thing. Otherwise this is only test programs
-FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@
-
-CLEANFILES = test_bitmap$(EXEEXT) test_priority_queue$(EXEEXT) \
- test_thr_alarm$(EXEEXT) test_thr_lock$(EXEEXT) \
- test_vsnprintf$(EXEEXT) test_io_cache$(EXEEXT) \
- test_dir$(EXEEXT) test_charset$(EXEEXT) \
- testhash$(EXEEXT) test_gethwaddr$(EXEEXT) \
- test_base64$(EXEEXT) test_thr_mutex$(EXEEXT)
-
-libmysys_a_SOURCES=
-libmysys.a: libmysys.la
- $(CP) .libs/libmysys.a $@
-
-#
-# The CP .. RM stuff is to avoid problems with some compilers (like alpha ccc)
-# which automaticly removes the object files you use to compile a final program
-#
-
-test_bitmap$(EXEEXT): my_bitmap.c $(LIBRARIES)
- $(LINK) $(FLAGS) -DMAIN ./my_bitmap.c $(LDADD) $(LIBS)
-
-test_priority_queue$(EXEEXT): queues.c $(LIBRARIES)
- $(LINK) $(FLAGS) -DMAIN ./queues.c $(LDADD) $(LIBS)
-
-test_thr_alarm$(EXEEXT): thr_alarm.c $(LIBRARIES)
- $(CP) $(srcdir)/thr_alarm.c ./test_thr_alarm.c
- $(LINK) $(FLAGS) -DMAIN ./test_thr_alarm.c $(LDADD) $(LIBS)
- $(RM) -f ./test_thr_alarm.c
-
-test_thr_lock$(EXEEXT): thr_lock.c $(LIBRARIES)
- $(CP) $(srcdir)/thr_lock.c test_thr_lock.c
- $(LINK) $(FLAGS) -DMAIN ./test_thr_lock.c $(LDADD) $(LIBS)
- $(RM) -f ./test_thr_lock.c
-
-test_vsnprintf$(EXEEXT): my_vsnprintf.c $(LIBRARIES)
- $(CP) $(srcdir)/my_vsnprintf.c test_vsnprintf.c
- $(LINK) $(FLAGS) -DMAIN ./test_vsnprintf.c $(LDADD) $(LIBS)
- $(RM) -f test_vsnprintf.c
-
-test_io_cache$(EXEEXT): mf_iocache.c $(LIBRARIES)
- $(CP) $(srcdir)/mf_iocache.c test_io_cache.c
- $(LINK) $(FLAGS) -DMAIN ./test_io_cache.c $(LDADD) $(LIBS)
- $(RM) -f test_io_cache.c
-
-test_dir$(EXEEXT): test_dir.c $(LIBRARIES)
- $(LINK) $(FLAGS) -DMAIN $(srcdir)/test_dir.c $(LDADD) $(LIBS)
-
-test_charset$(EXEEXT): test_charset.c $(LIBRARIES)
- $(LINK) $(FLAGS) -DMAIN $(srcdir)/test_charset.c $(LDADD) $(LIBS)
-
-testhash$(EXEEXT): testhash.c $(LIBRARIES)
- $(LINK) $(FLAGS) -DMAIN $(srcdir)/testhash.c $(LDADD) $(LIBS)
-
-test_gethwaddr$(EXEEXT): my_gethwaddr.c $(LIBRARIES)
- $(CP) $(srcdir)/my_gethwaddr.c ./test_gethwaddr.c
- $(LINK) $(FLAGS) -DMAIN ./test_gethwaddr.c $(LDADD) $(LIBS)
- $(RM) -f ./test_gethwaddr.c
-
-test_base64$(EXEEXT): base64.c $(LIBRARIES)
- $(CP) $(srcdir)/base64.c ./test_base64.c
- $(LINK) $(FLAGS) -DMAIN ./test_base64.c $(LDADD) $(LIBS)
- $(RM) -f ./test_base64.c
-
-test_thr_mutex$(EXEEXT): test_thr_mutex.c $(LIBRARIES)
- $(LINK) $(FLAGS) $(srcdir)/test_thr_mutex.c $(LDADD) $(LIBS)
diff --git a/mysys/array.c b/mysys/array.c
index ba67e3a5d47..c969da83586 100644
--- a/mysys/array.c
+++ b/mysys/array.c
@@ -1,6 +1,4 @@
-/*
- Copyright (c) 2000, 2002, 2005-2007 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* Copyright (c) 2000, 2010, 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
@@ -13,8 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* Handling of arrays that can grow dynamicly. */
@@ -44,10 +41,10 @@
*/
my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size,
- void *init_buffer, uint init_alloc,
- uint alloc_increment CALLER_INFO_PROTO)
+ void *init_buffer, uint init_alloc,
+ uint alloc_increment)
{
- DBUG_ENTER("init_dynamic_array");
+ DBUG_ENTER("init_dynamic_array2");
if (!alloc_increment)
{
alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
@@ -64,14 +61,14 @@ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size,
Since the dynamic array is usable even if allocation fails here malloc
should not throw an error
*/
- if (!(array->buffer= (uchar*) my_malloc_ci(element_size*init_alloc, MYF(0))))
+ if (init_alloc &&
+ !(array->buffer= (uchar*) my_malloc(element_size*init_alloc, MYF(0))))
array->max_element=0;
DBUG_RETURN(FALSE);
}
my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
- uint init_alloc,
- uint alloc_increment CALLER_INFO_PROTO)
+ uint init_alloc, uint alloc_increment)
{
/* placeholder to preserve ABI */
return my_init_dynamic_array_ci(array, element_size, init_alloc,
@@ -303,7 +300,7 @@ void delete_dynamic(DYNAMIC_ARRAY *array)
else
if (array->buffer)
{
- my_free(array->buffer,MYF(MY_WME));
+ my_free(array->buffer);
array->buffer=0;
array->elements=array->max_element=0;
}
diff --git a/mysys/base64.c b/mysys/base64.c
index e9b6203dba3..b48bcb85e03 100644
--- a/mysys/base64.c
+++ b/mysys/base64.c
@@ -1,5 +1,4 @@
-/*
- Copyright (c) 2003-2008 MySQL AB, 2009 Sun Microsystems, Inc.
+/* Copyright (c) 2003-2008 MySQL AB, 2009 Sun Microsystems, Inc.
Use is subject to license terms.
This program is free software; you can redistribute it and/or modify
@@ -13,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <my_global.h>
#include <m_string.h> /* strchr() */
diff --git a/mysys/charset-def.c b/mysys/charset-def.c
index 8678852ba5f..e9f2ecdea49 100644
--- a/mysys/charset-def.c
+++ b/mysys/charset-def.c
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
@@ -42,9 +42,59 @@ extern struct charset_info_st my_charset_ucs2_roman_uca_ci;
extern struct charset_info_st my_charset_ucs2_persian_uca_ci;
extern struct charset_info_st my_charset_ucs2_esperanto_uca_ci;
extern struct charset_info_st my_charset_ucs2_hungarian_uca_ci;
+extern struct charset_info_st my_charset_ucs2_sinhala_uca_ci;
extern struct charset_info_st my_charset_ucs2_croatian_uca_ci;
#endif
+
+#ifdef HAVE_CHARSET_utf32
+extern struct charset_info_st my_charset_utf32_icelandic_uca_ci;
+extern struct charset_info_st my_charset_utf32_latvian_uca_ci;
+extern struct charset_info_st my_charset_utf32_romanian_uca_ci;
+extern struct charset_info_st my_charset_utf32_slovenian_uca_ci;
+extern struct charset_info_st my_charset_utf32_polish_uca_ci;
+extern struct charset_info_st my_charset_utf32_estonian_uca_ci;
+extern struct charset_info_st my_charset_utf32_spanish_uca_ci;
+extern struct charset_info_st my_charset_utf32_swedish_uca_ci;
+extern struct charset_info_st my_charset_utf32_turkish_uca_ci;
+extern struct charset_info_st my_charset_utf32_czech_uca_ci;
+extern struct charset_info_st my_charset_utf32_danish_uca_ci;
+extern struct charset_info_st my_charset_utf32_lithuanian_uca_ci;
+extern struct charset_info_st my_charset_utf32_slovak_uca_ci;
+extern struct charset_info_st my_charset_utf32_spanish2_uca_ci;
+extern struct charset_info_st my_charset_utf32_roman_uca_ci;
+extern struct charset_info_st my_charset_utf32_persian_uca_ci;
+extern struct charset_info_st my_charset_utf32_esperanto_uca_ci;
+extern struct charset_info_st my_charset_utf32_hungarian_uca_ci;
+extern struct charset_info_st my_charset_utf32_sinhala_uca_ci;
+extern struct charset_info_st my_charset_utf32_croatian_uca_ci;
+#endif /* HAVE_CHARSET_utf32 */
+
+
+#ifdef HAVE_CHARSET_utf16
+extern struct charset_info_st my_charset_utf16_icelandic_uca_ci;
+extern struct charset_info_st my_charset_utf16_latvian_uca_ci;
+extern struct charset_info_st my_charset_utf16_romanian_uca_ci;
+extern struct charset_info_st my_charset_utf16_slovenian_uca_ci;
+extern struct charset_info_st my_charset_utf16_polish_uca_ci;
+extern struct charset_info_st my_charset_utf16_estonian_uca_ci;
+extern struct charset_info_st my_charset_utf16_spanish_uca_ci;
+extern struct charset_info_st my_charset_utf16_swedish_uca_ci;
+extern struct charset_info_st my_charset_utf16_turkish_uca_ci;
+extern struct charset_info_st my_charset_utf16_czech_uca_ci;
+extern struct charset_info_st my_charset_utf16_danish_uca_ci;
+extern struct charset_info_st my_charset_utf16_lithuanian_uca_ci;
+extern struct charset_info_st my_charset_utf16_slovak_uca_ci;
+extern struct charset_info_st my_charset_utf16_spanish2_uca_ci;
+extern struct charset_info_st my_charset_utf16_roman_uca_ci;
+extern struct charset_info_st my_charset_utf16_persian_uca_ci;
+extern struct charset_info_st my_charset_utf16_esperanto_uca_ci;
+extern struct charset_info_st my_charset_utf16_hungarian_uca_ci;
+extern struct charset_info_st my_charset_utf16_sinhala_uca_ci;
+extern struct charset_info_st my_charset_utf16_croatian_uca_ci;
+#endif /* HAVE_CHARSET_utf16 */
+
+
#ifdef HAVE_CHARSET_utf8
extern struct charset_info_st my_charset_utf8_icelandic_uca_ci;
extern struct charset_info_st my_charset_utf8_latvian_uca_ci;
@@ -64,12 +114,36 @@ extern struct charset_info_st my_charset_utf8_roman_uca_ci;
extern struct charset_info_st my_charset_utf8_persian_uca_ci;
extern struct charset_info_st my_charset_utf8_esperanto_uca_ci;
extern struct charset_info_st my_charset_utf8_hungarian_uca_ci;
+extern struct charset_info_st my_charset_utf8_sinhala_uca_ci;
extern struct charset_info_st my_charset_utf8_croatian_uca_ci;
#ifdef HAVE_UTF8_GENERAL_CS
extern struct charset_info_st my_charset_utf8_general_cs;
#endif
#endif
+#ifdef HAVE_CHARSET_utf8mb4
+extern struct charset_info_st my_charset_utf8mb4_icelandic_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_latvian_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_romanian_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_slovenian_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_polish_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_estonian_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_spanish_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_swedish_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_turkish_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_czech_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_danish_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_lithuanian_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_slovak_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_spanish2_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_roman_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_persian_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_esperanto_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_hungarian_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_sinhala_uca_ci;
+extern struct charset_info_st my_charset_utf8mb4_croatian_uca_ci;
+#endif /* HAVE_CHARSET_utf8mb4 */
+
#endif /* HAVE_UCA_COLLATIONS */
my_bool init_compiled_charsets(myf flags __attribute__((unused)))
@@ -155,6 +229,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused)))
add_compiled_collation(&my_charset_ucs2_persian_uca_ci);
add_compiled_collation(&my_charset_ucs2_esperanto_uca_ci);
add_compiled_collation(&my_charset_ucs2_hungarian_uca_ci);
+ add_compiled_collation(&my_charset_ucs2_sinhala_uca_ci);
add_compiled_collation(&my_charset_ucs2_croatian_uca_ci);
#endif
#endif
@@ -191,9 +266,97 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused)))
add_compiled_collation(&my_charset_utf8_persian_uca_ci);
add_compiled_collation(&my_charset_utf8_esperanto_uca_ci);
add_compiled_collation(&my_charset_utf8_hungarian_uca_ci);
+ add_compiled_collation(&my_charset_utf8_sinhala_uca_ci);
add_compiled_collation(&my_charset_utf8_croatian_uca_ci);
#endif
-#endif
+#endif /* HAVE_CHARSET_utf8 */
+
+
+#ifdef HAVE_CHARSET_utf8mb4
+ add_compiled_collation(&my_charset_utf8mb4_general_ci);
+ add_compiled_collation(&my_charset_utf8mb4_bin);
+#ifdef HAVE_UCA_COLLATIONS
+ add_compiled_collation(&my_charset_utf8mb4_unicode_ci);
+ add_compiled_collation(&my_charset_utf8mb4_icelandic_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_latvian_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_romanian_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_slovenian_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_polish_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_estonian_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_spanish_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_swedish_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_turkish_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_czech_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_danish_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_lithuanian_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_slovak_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_spanish2_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_roman_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_persian_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_esperanto_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_hungarian_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_sinhala_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb4_croatian_uca_ci);
+#endif /* HAVE_UCA_COLLATIONS */
+#endif /* HAVE_CHARSET_utf8mb4 */
+
+
+#ifdef HAVE_CHARSET_utf16
+ add_compiled_collation(&my_charset_utf16_general_ci);
+ add_compiled_collation(&my_charset_utf16_bin);
+#ifdef HAVE_UCA_COLLATIONS
+ add_compiled_collation(&my_charset_utf16_unicode_ci);
+ add_compiled_collation(&my_charset_utf16_icelandic_uca_ci);
+ add_compiled_collation(&my_charset_utf16_latvian_uca_ci);
+ add_compiled_collation(&my_charset_utf16_romanian_uca_ci);
+ add_compiled_collation(&my_charset_utf16_slovenian_uca_ci);
+ add_compiled_collation(&my_charset_utf16_polish_uca_ci);
+ add_compiled_collation(&my_charset_utf16_estonian_uca_ci);
+ add_compiled_collation(&my_charset_utf16_spanish_uca_ci);
+ add_compiled_collation(&my_charset_utf16_swedish_uca_ci);
+ add_compiled_collation(&my_charset_utf16_turkish_uca_ci);
+ add_compiled_collation(&my_charset_utf16_czech_uca_ci);
+ add_compiled_collation(&my_charset_utf16_danish_uca_ci);
+ add_compiled_collation(&my_charset_utf16_lithuanian_uca_ci);
+ add_compiled_collation(&my_charset_utf16_slovak_uca_ci);
+ add_compiled_collation(&my_charset_utf16_spanish2_uca_ci);
+ add_compiled_collation(&my_charset_utf16_roman_uca_ci);
+ add_compiled_collation(&my_charset_utf16_persian_uca_ci);
+ add_compiled_collation(&my_charset_utf16_esperanto_uca_ci);
+ add_compiled_collation(&my_charset_utf16_hungarian_uca_ci);
+ add_compiled_collation(&my_charset_utf16_sinhala_uca_ci);
+ add_compiled_collation(&my_charset_utf16_croatian_uca_ci);
+#endif /* HAVE_UCA_COLLATIONS */
+#endif /* HAVE_CHARSET_utf16 */
+
+
+#ifdef HAVE_CHARSET_utf32
+ add_compiled_collation(&my_charset_utf32_general_ci);
+ add_compiled_collation(&my_charset_utf32_bin);
+#ifdef HAVE_UCA_COLLATIONS
+ add_compiled_collation(&my_charset_utf32_unicode_ci);
+ add_compiled_collation(&my_charset_utf32_icelandic_uca_ci);
+ add_compiled_collation(&my_charset_utf32_latvian_uca_ci);
+ add_compiled_collation(&my_charset_utf32_romanian_uca_ci);
+ add_compiled_collation(&my_charset_utf32_slovenian_uca_ci);
+ add_compiled_collation(&my_charset_utf32_polish_uca_ci);
+ add_compiled_collation(&my_charset_utf32_estonian_uca_ci);
+ add_compiled_collation(&my_charset_utf32_spanish_uca_ci);
+ add_compiled_collation(&my_charset_utf32_swedish_uca_ci);
+ add_compiled_collation(&my_charset_utf32_turkish_uca_ci);
+ add_compiled_collation(&my_charset_utf32_czech_uca_ci);
+ add_compiled_collation(&my_charset_utf32_danish_uca_ci);
+ add_compiled_collation(&my_charset_utf32_lithuanian_uca_ci);
+ add_compiled_collation(&my_charset_utf32_slovak_uca_ci);
+ add_compiled_collation(&my_charset_utf32_spanish2_uca_ci);
+ add_compiled_collation(&my_charset_utf32_roman_uca_ci);
+ add_compiled_collation(&my_charset_utf32_persian_uca_ci);
+ add_compiled_collation(&my_charset_utf32_esperanto_uca_ci);
+ add_compiled_collation(&my_charset_utf32_hungarian_uca_ci);
+ add_compiled_collation(&my_charset_utf32_sinhala_uca_ci);
+ add_compiled_collation(&my_charset_utf32_croatian_uca_ci);
+#endif /* HAVE_UCA_COLLATIONS */
+#endif /* HAVE_CHARSET_utf32 */
/* Copy compiled charsets */
for (cs=compiled_charsets; cs->name; cs++)
diff --git a/mysys/charset.c b/mysys/charset.c
index fe8eff5af2b..cc1d0a0111e 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
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
@@ -12,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -44,7 +43,7 @@ get_collation_number_internal(const char *name)
{
CHARSET_INFO **cs;
for (cs= all_charsets;
- cs < all_charsets+array_elements(all_charsets)-1 ;
+ cs < all_charsets + array_elements(all_charsets);
cs++)
{
if ( cs[0] && cs[0]->name &&
@@ -255,13 +254,38 @@ static int add_collation(struct charset_info_st *cs)
{
#if defined(HAVE_CHARSET_ucs2) && defined(HAVE_UCA_COLLATIONS)
copy_uca_collation(newcs, &my_charset_ucs2_unicode_ci);
- newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
+ newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
#endif
}
- else if (!strcmp(cs->csname, "utf8"))
+ else if (!strcmp(cs->csname, "utf8") || !strcmp(cs->csname, "utf8mb3"))
{
#if defined (HAVE_CHARSET_utf8) && defined(HAVE_UCA_COLLATIONS)
copy_uca_collation(newcs, &my_charset_utf8_unicode_ci);
+ newcs->ctype= my_charset_utf8_unicode_ci.ctype;
+ if (init_state_maps(newcs))
+ return MY_XML_ERROR;
+#endif
+ }
+ else if (!strcmp(cs->csname, "utf8mb4"))
+ {
+#if defined (HAVE_CHARSET_utf8mb4) && defined(HAVE_UCA_COLLATIONS)
+ copy_uca_collation(newcs, &my_charset_utf8mb4_unicode_ci);
+ newcs->ctype= my_charset_utf8mb4_unicode_ci.ctype;
+ newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED;
+#endif
+ }
+ else if (!strcmp(cs->csname, "utf16"))
+ {
+#if defined (HAVE_CHARSET_utf16) && defined(HAVE_UCA_COLLATIONS)
+ copy_uca_collation(newcs, &my_charset_utf16_unicode_ci);
+ newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
+#endif
+ }
+ else if (!strcmp(cs->csname, "utf32"))
+ {
+#if defined (HAVE_CHARSET_utf32) && defined(HAVE_UCA_COLLATIONS)
+ copy_uca_collation(newcs, &my_charset_utf32_unicode_ci);
+ newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
#endif
}
else
@@ -344,10 +368,10 @@ static my_bool my_read_charset_file(const char *filename, myf myflags)
!(buf= (uchar*) my_malloc(len,myflags)))
return TRUE;
- if ((fd=my_open(filename,O_RDONLY,myflags)) < 0)
+ if ((fd= mysql_file_open(key_file_charset, filename, O_RDONLY, myflags)) < 0)
goto error;
- tmp_len=my_read(fd, buf, len, myflags);
- my_close(fd,myflags);
+ tmp_len= mysql_file_read(fd, buf, len, myflags);
+ mysql_file_close(fd, myflags);
if (tmp_len != len)
goto error;
@@ -361,11 +385,11 @@ static my_bool my_read_charset_file(const char *filename, myf myflags)
#endif
}
- my_free(buf, myflags);
+ my_free(buf);
return FALSE;
error:
- my_free(buf, myflags);
+ my_free(buf);
return TRUE;
}
@@ -392,11 +416,12 @@ char *get_charsets_dir(char *buf)
DBUG_RETURN(res);
}
-CHARSET_INFO *all_charsets[256]={NULL};
+CHARSET_INFO *all_charsets[MY_ALL_CHARSETS_SIZE]={NULL};
CHARSET_INFO *default_charset_info = &my_charset_latin1;
void add_compiled_collation(struct charset_info_st *cs)
{
+ DBUG_ASSERT(cs->number < array_elements(all_charsets));
all_charsets[cs->number]= cs;
cs->state|= MY_CS_AVAILABLE;
}
@@ -417,7 +442,7 @@ static void init_available_charsets(void)
bzero((char*) &all_charsets,sizeof(all_charsets));
init_compiled_charsets(MYF(0));
-
+
/* Copy compiled charsets */
for (cs= (struct charset_info_st**) all_charsets;
cs < (struct charset_info_st**) all_charsets +
@@ -431,7 +456,7 @@ static void init_available_charsets(void)
*cs= NULL;
}
}
-
+
strmov(get_charsets_dir(fname), MY_CHARSET_INDEX);
my_read_charset_file(fname, MYF(0));
}
@@ -442,20 +467,39 @@ void free_charsets(void)
charsets_initialized= charsets_template;
}
+
+static const char*
+get_collation_name_alias(const char *name, char *buf, size_t bufsize)
+{
+ if (!strncasecmp(name, "utf8mb3_", 8))
+ {
+ my_snprintf(buf, bufsize, "utf8_%s", name + 8);
+ return buf;
+ }
+ return NULL;
+}
+
+
uint get_collation_number(const char *name)
{
+ uint id;
+ char alias[64];
my_pthread_once(&charsets_initialized, init_available_charsets);
- return get_collation_number_internal(name);
+ if ((id= get_collation_number_internal(name)))
+ return id;
+ if ((name= get_collation_name_alias(name, alias, sizeof(alias))))
+ return get_collation_number_internal(name);
+ return 0;
}
-uint get_charset_number(const char *charset_name, uint cs_flags)
+static uint
+get_charset_number_internal(const char *charset_name, uint cs_flags)
{
CHARSET_INFO **cs;
- my_pthread_once(&charsets_initialized, init_available_charsets);
for (cs= all_charsets;
- cs < all_charsets+array_elements(all_charsets)-1 ;
+ cs < all_charsets + array_elements(all_charsets);
cs++)
{
if ( cs[0] && cs[0]->csname && (cs[0]->state & cs_flags) &&
@@ -466,16 +510,40 @@ uint get_charset_number(const char *charset_name, uint cs_flags)
}
+static const char*
+get_charset_name_alias(const char *name)
+{
+ if (!my_strcasecmp(&my_charset_latin1, name, "utf8mb3"))
+ return "utf8";
+ return NULL;
+}
+
+
+uint get_charset_number(const char *charset_name, uint cs_flags)
+{
+ uint id;
+ my_pthread_once(&charsets_initialized, init_available_charsets);
+ if ((id= get_charset_number_internal(charset_name, cs_flags)))
+ return id;
+ if ((charset_name= get_charset_name_alias(charset_name)))
+ return get_charset_number_internal(charset_name, cs_flags);
+ return 0;
+}
+
+
const char *get_charset_name(uint charset_number)
{
- CHARSET_INFO *cs;
my_pthread_once(&charsets_initialized, init_available_charsets);
- cs=all_charsets[charset_number];
- if (cs && (cs->number == charset_number) && cs->name )
- return (char*) cs->name;
+ if (charset_number < array_elements(all_charsets))
+ {
+ CHARSET_INFO *cs= all_charsets[charset_number];
+
+ if (cs && (cs->number == charset_number) && cs->name)
+ return (char*) cs->name;
+ }
- return (char*) "?"; /* this mimics find_type() */
+ return "?"; /* this mimics find_type() */
}
@@ -484,6 +552,8 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
char buf[FN_REFLEN];
struct charset_info_st *cs;
+ DBUG_ASSERT(cs_number < array_elements(all_charsets));
+
if ((cs= (struct charset_info_st*) all_charsets[cs_number]))
{
if (cs->state & MY_CS_READY) /* if CS is already initialized */
@@ -493,7 +563,7 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
To make things thread safe we are not allowing other threads to interfere
while we may changing the cs_info_table
*/
- pthread_mutex_lock(&THR_LOCK_charset);
+ mysql_mutex_lock(&THR_LOCK_charset);
if (!(cs->state & (MY_CS_COMPILED|MY_CS_LOADED))) /* if CS is not in memory */
{
@@ -515,7 +585,7 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
else
cs= NULL;
- pthread_mutex_unlock(&THR_LOCK_charset);
+ mysql_mutex_unlock(&THR_LOCK_charset);
}
return cs;
}
@@ -528,8 +598,8 @@ CHARSET_INFO *get_charset(uint cs_number, myf flags)
return default_charset_info;
my_pthread_once(&charsets_initialized, init_available_charsets);
-
- if (!cs_number || cs_number >= array_elements(all_charsets)-1)
+
+ if (cs_number >= array_elements(all_charsets))
return NULL;
cs=get_internal_charset(cs_number, flags);
diff --git a/mysys/checksum.c b/mysys/checksum.c
index 1d264b54321..7bc52c6a178 100644
--- a/mysys/checksum.c
+++ b/mysys/checksum.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,14 +11,14 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <my_global.h>
#include <my_sys.h>
#include <zlib.h>
-ha_checksum my_crc_dbug_check= 1; /* Unlikely number */
+ulong my_crc_dbug_check= ~0; /* Cannot happen */
/*
Calculate a long checksum for a memoryblock.
@@ -32,9 +32,9 @@ ha_checksum my_crc_dbug_check= 1; /* Unlikely number */
ha_checksum my_checksum(ha_checksum crc, const uchar *pos, size_t length)
{
- crc= (ha_checksum) crc32((uint)crc, pos, length);
+ crc= (ha_checksum) crc32((uint)crc, pos, (uint) length);
DBUG_PRINT("info", ("crc: %lu", (ulong) crc));
- if (crc == my_crc_dbug_check)
+ if ((ulong)crc == my_crc_dbug_check)
my_debug_put_break_here();
return crc;
}
diff --git a/mysys/default.c b/mysys/default.c
index 1c0f997520a..c7ac0d89462 100644
--- a/mysys/default.c
+++ b/mysys/default.c
@@ -1,6 +1,4 @@
-/*
- Copyright (c) 2000-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* 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
@@ -13,8 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/****************************************************************************
Add all options from files named "group".cnf from the default_directories
@@ -44,9 +41,51 @@
#include <winbase.h>
#endif
+/**
+ arguments separator
+
+ load_defaults() loads arguments from config file and put them
+ before the arguments from command line, this separator is used to
+ separate the arguments loaded from config file and arguments user
+ provided on command line.
+
+ Options with value loaded from config file are always in the form
+ '--option=value', while for command line options, the value can be
+ given as the next argument. Thus we used a separator so that
+ handle_options() can distinguish them.
+
+ Note: any other places that does not need to distinguish them
+ should skip the separator.
+
+ The content of arguments separator does not matter, one should only
+ check the pointer, use "----args-separator----" here to ease debug
+ if someone misused it.
+
+ The args seprator will only be added when
+ my_getopt_use_args_seprator is set to TRUE before calling
+ load_defaults();
+
+ See BUG#25192
+*/
+static const char *args_separator= "----args-separator----";
+inline static void set_args_separator(char** arg)
+{
+ DBUG_ASSERT(my_getopt_use_args_separator);
+ *arg= (char*)args_separator;
+}
+my_bool my_getopt_use_args_separator= FALSE;
+my_bool my_getopt_is_args_separator(const char* arg)
+{
+ return (arg == args_separator);
+}
const char *my_defaults_file=0;
const char *my_defaults_group_suffix=0;
-char *my_defaults_extra_file=0;
+const char *my_defaults_extra_file=0;
+
+static char my_defaults_file_buffer[FN_REFLEN];
+static char my_defaults_extra_file_buffer[FN_REFLEN];
+
+static my_bool defaults_already_read= FALSE;
/* Which directories are searched for options (and in which order) */
@@ -98,11 +137,10 @@ static int search_default_file_with_ext(Process_option_func func,
- Windows: GetWindowsDirectory()
- Windows: C:/
- Windows: Directory above where the executable is located
- - Netware: sys:/etc/
- Unix: /etc/
- Unix: /etc/mysql/
- Unix: --sysconfdir=<path> (compile-time option)
- - ALL: getenv(DEFAULT_HOME_ENV)
+ - ALL: getenv("MYSQL_HOME")
- ALL: --defaults-extra-file=<path> (run-time option)
- Unix: ~/
@@ -121,6 +159,33 @@ static char *remove_end_comment(char *ptr);
/*
+ Expand a file name so that the current working directory is added if
+ the name is relative.
+
+ RETURNS
+ 0 All OK
+ 2 Out of memory or path to long
+ 3 Not able to get working directory
+ */
+
+static int
+fn_expand(const char *filename, char *result_buf)
+{
+ char dir[FN_REFLEN];
+ const int flags= MY_UNPACK_FILENAME | MY_SAFE_PATH | MY_RELATIVE_PATH;
+ DBUG_ENTER("fn_expand");
+ DBUG_PRINT("enter", ("filename: %s, result_buf: 0x%lx",
+ filename, (unsigned long) result_buf));
+ if (my_getwd(dir, sizeof(dir), MYF(0)))
+ DBUG_RETURN(3);
+ DBUG_PRINT("debug", ("dir: %s", dir));
+ if (fn_format(result_buf, filename, dir, "", flags) == NULL)
+ DBUG_RETURN(2);
+ DBUG_PRINT("return", ("result: %s", result_buf));
+ DBUG_RETURN(0);
+}
+
+/*
Process config files in default directories.
SYNOPSIS
@@ -148,6 +213,7 @@ static char *remove_end_comment(char *ptr);
0 ok
1 given cinf_file doesn't exist
2 out of memory
+ 3 Can't get current working directory
The global variable 'my_defaults_group_suffix' is updated with value for
--defaults_group_suffix
@@ -170,11 +236,23 @@ int my_search_option_files(const char *conf_file, int *argc, char ***argv,
if (! my_defaults_group_suffix)
my_defaults_group_suffix= getenv(STRINGIFY_ARG(DEFAULT_GROUP_SUFFIX_ENV));
- if (forced_extra_defaults)
- my_defaults_extra_file= (char *) forced_extra_defaults;
-
- if (forced_default_file)
- my_defaults_file= forced_default_file;
+ if (forced_extra_defaults && !defaults_already_read)
+ {
+ int error= fn_expand(forced_extra_defaults, my_defaults_extra_file_buffer);
+ if (error)
+ DBUG_RETURN(error);
+ my_defaults_extra_file= my_defaults_extra_file_buffer;
+ }
+
+ if (forced_default_file && !defaults_already_read)
+ {
+ int error= fn_expand(forced_default_file, my_defaults_file_buffer);
+ if (error)
+ DBUG_RETURN(error);
+ my_defaults_file= my_defaults_file_buffer;
+ }
+
+ defaults_already_read= TRUE;
/*
We can only handle 'defaults-group-suffix' if we are called from
@@ -217,15 +295,15 @@ int my_search_option_files(const char *conf_file, int *argc, char ***argv,
group->type_names[group->count]= 0;
}
- if (forced_default_file)
+ if (my_defaults_file)
{
if ((error= search_default_file_with_ext(func, func_ctx, "", "",
- forced_default_file, 0)) < 0)
+ my_defaults_file, 0)) < 0)
goto err;
if (error > 0)
{
fprintf(stderr, "Could not open required defaults file: %s\n",
- forced_default_file);
+ my_defaults_file);
goto err;
}
}
@@ -298,7 +376,7 @@ static int handle_default_option(void *in_ctx, const char *group_name,
if (!option)
return 0;
- if (find_type((char *)group_name, ctx->group, 3))
+ if (find_type((char *)group_name, ctx->group, FIND_TYPE_NO_PREFIX))
{
if (!(tmp= alloc_root(ctx->alloc, strlen(option) + 1)))
return 1;
@@ -439,6 +517,7 @@ int my_load_defaults(const char *conf_file, const char **groups,
char *ptr,**res;
struct handle_option_ctx ctx;
const char **dirs;
+ uint args_sep= my_getopt_use_args_separator ? 1 : 0;
DBUG_ENTER("load_defaults");
init_alloc_root(&alloc,512,0);
@@ -451,16 +530,28 @@ int my_load_defaults(const char *conf_file, const char **groups,
if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults"))
{
/* remove the --no-defaults argument and return only the other arguments */
- uint i;
+ uint i, j;
if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
(*argc + 1)*sizeof(char*))))
goto err;
res= (char**) (ptr+sizeof(alloc));
res[0]= **argv; /* Copy program name */
- for (i=2 ; i < (uint) *argc ; i++)
- res[i-1]=argv[0][i];
- res[i-1]=0; /* End pointer */
- (*argc)--;
+ j= 1; /* Start from 1 for the reset result args */
+ if (my_getopt_use_args_separator)
+ {
+ /* set arguments separator */
+ set_args_separator(&res[1]);
+ j++;
+ }
+ for (i=2 ; i < (uint) *argc ; i++, j++)
+ res[j]=argv[0][i];
+ res[j]=0; /* End pointer */
+ /*
+ Update the argc, if have not added args separator, then we have
+ to decrease argc because we have removed the "--no-defaults".
+ */
+ if (!my_getopt_use_args_separator)
+ (*argc)--;
*argv=res;
*(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
if (default_directories)
@@ -482,15 +573,19 @@ int my_load_defaults(const char *conf_file, const char **groups,
ctx.args= &args;
ctx.group= &group;
- error= my_search_option_files(conf_file, argc, argv, &args_used,
- handle_default_option, (void *) &ctx,
- dirs);
+ if ((error= my_search_option_files(conf_file, argc, argv, &args_used,
+ handle_default_option, (void *) &ctx,
+ dirs)))
+ {
+ free_root(&alloc,MYF(0));
+ DBUG_RETURN(error);
+ }
/*
Here error contains <> 0 only if we have a fully specified conf_file
or a forced default file
*/
if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
- (args.elements + *argc +1) *sizeof(char*))))
+ (args.elements + *argc + 1 + args_sep) *sizeof(char*))))
goto err;
res= (char**) (ptr+sizeof(alloc));
@@ -511,12 +606,19 @@ int my_load_defaults(const char *conf_file, const char **groups,
--*argc; ++*argv; /* skip argument */
}
+ if (my_getopt_use_args_separator)
+ {
+ /* set arguments separator for arguments from config file and
+ command line */
+ set_args_separator(&res[args.elements+1]);
+ }
+
if (*argc)
- memcpy((uchar*) (res+1+args.elements), (char*) ((*argv)+1),
+ memcpy((uchar*) (res+1+args.elements+args_sep), (char*) ((*argv)+1),
(*argc-1)*sizeof(char*));
- res[args.elements+ *argc]=0; /* last null */
+ res[args.elements+ *argc+args_sep]=0; /* last null */
- (*argc)+=args.elements;
+ (*argc)+=args.elements+args_sep;
*argv= (char**) res;
*(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
delete_dynamic(&args);
@@ -526,15 +628,16 @@ int my_load_defaults(const char *conf_file, const char **groups,
printf("%s would have been started with the following arguments:\n",
**argv);
for (i=1 ; i < *argc ; i++)
- printf("%s ", (*argv)[i]);
+ if (!my_getopt_is_args_separator((*argv)[i])) /* skip arguments separator */
+ printf("%s ", (*argv)[i]);
puts("");
exit(0);
}
- if (error == 0 && default_directories)
+ if (default_directories)
*default_directories= dirs;
- DBUG_RETURN(error);
+ DBUG_RETURN(0);
err:
fprintf(stderr,"Fatal error in defaults handling. Program aborted\n");
@@ -546,7 +649,7 @@ int my_load_defaults(const char *conf_file, const char **groups,
void free_defaults(char **argv)
{
MEM_ROOT ptr;
- memcpy_fixed((char*) &ptr,(char *) argv - sizeof(ptr), sizeof(ptr));
+ memcpy(&ptr, ((char *) argv) - sizeof(ptr), sizeof(ptr));
free_root(&ptr,MYF(0));
}
@@ -657,7 +760,7 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
static const char includedir_keyword[]= "includedir";
static const char include_keyword[]= "include";
const int max_recursion_level= 10;
- FILE *fp;
+ MYSQL_FILE *fp;
uint line=0;
my_bool found_group=0;
uint i;
@@ -678,7 +781,7 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
strmov(name,config_file);
}
fn_format(name,name,"","",4);
-#if !defined(__WIN__) && !defined(__NETWARE__)
+#if !defined(__WIN__)
{
MY_STAT stat_info;
if (!my_stat(name,&stat_info,MYF(0)))
@@ -697,10 +800,10 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
}
}
#endif
- if (!(fp= my_fopen(name, O_RDONLY, MYF(0))))
+ if (!(fp= mysql_file_fopen(key_file_cnf, name, O_RDONLY, MYF(0))))
return 1; /* Ignore wrong files */
- while (fgets(buff, sizeof(buff) - 1, fp))
+ while (mysql_file_fgets(buff, sizeof(buff) - 1, fp))
{
line++;
/* Ignore comment and empty lines */
@@ -890,11 +993,11 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
goto err;
}
}
- my_fclose(fp,MYF(0));
+ mysql_file_fclose(fp, MYF(0));
return(0);
err:
- my_fclose(fp,MYF(0));
+ mysql_file_fclose(fp, MYF(0));
return -1; /* Fatal error */
}
@@ -924,7 +1027,6 @@ static char *remove_end_comment(char *ptr)
return ptr;
}
-#include <help_start.h>
void my_print_default_files(const char *conf_file)
{
@@ -1004,8 +1106,6 @@ void print_defaults(const char *conf_file, const char **groups)
--defaults-extra-file=# Read this file after the global files are read.");
}
-#include <help_end.h>
-
static int add_directory(MEM_ROOT *alloc, const char *dir, const char **dirs)
{
@@ -1098,10 +1198,11 @@ static const char **init_default_directories(MEM_ROOT *alloc)
const char **dirs;
char *env;
int errors= 0;
+ DBUG_ENTER("init_default_directories");
dirs= (const char **)alloc_root(alloc, DEFAULT_DIRS_SIZE * sizeof(char *));
if (dirs == NULL)
- return NULL;
+ DBUG_RETURN(NULL);
bzero((char *) dirs, DEFAULT_DIRS_SIZE * sizeof(char *));
#ifdef __WIN__
@@ -1120,10 +1221,6 @@ static const char **init_default_directories(MEM_ROOT *alloc)
errors += add_directory(alloc, fname_buffer, dirs);
}
-#elif defined(__NETWARE__)
-
- errors += add_directory(alloc, "sys:/etc/", dirs);
-
#else
errors += add_directory(alloc, "/etc/", dirs);
@@ -1136,15 +1233,15 @@ static const char **init_default_directories(MEM_ROOT *alloc)
#endif
- if ((env= getenv(STRINGIFY_ARG(DEFAULT_HOME_ENV))))
+ if ((env= getenv("MYSQL_HOME")))
errors += add_directory(alloc, env, dirs);
/* Placeholder for --defaults-extra-file=<path> */
errors += add_directory(alloc, "", dirs);
-#if !defined(__WIN__) && !defined(__NETWARE__)
+#if !defined(__WIN__)
errors += add_directory(alloc, "~/", dirs);
#endif
- return (errors > 0 ? NULL : dirs);
+ DBUG_RETURN(errors > 0 ? NULL : dirs);
}
diff --git a/mysys/default_modify.c b/mysys/default_modify.c
deleted file mode 100644
index ccbf47176a6..00000000000
--- a/mysys/default_modify.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/* Copyright (C) 2005 MySQL 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "my_global.h"
-#include "mysys_priv.h"
-#include "m_string.h"
-#include <my_dir.h>
-
-#define BUFF_SIZE 1024
-#define RESERVE 1024 /* Extend buffer with this extent */
-
-#ifdef _WIN32
-#define NEWLINE "\r\n"
-#define NEWLINE_LEN 2
-#else
-#define NEWLINE "\n"
-#define NEWLINE_LEN 1
-#endif
-
-static char *add_option(char *dst, const char *option_value,
- const char *option, int remove_option);
-
-
-/*
- Add/remove option to the option file section.
-
- SYNOPSYS
- modify_defaults_file()
- file_location The location of configuration file to edit
- option The name of the option to look for (can be NULL)
- option value The value of the option we would like to set (can be NULL)
- section_name The name of the section (must be NOT NULL)
- remove_option This defines what we want to remove:
- - MY_REMOVE_NONE -- nothing to remove;
- - MY_REMOVE_OPTION -- remove the specified option;
- - MY_REMOVE_SECTION -- remove the specified section;
- IMPLEMENTATION
- We open the option file first, then read the file line-by-line,
- looking for the section we need. At the same time we put these lines
- into a buffer. Then we look for the option within this section and
- change/remove it. In the end we get a buffer with modified version of the
- file. Then we write it to the file, truncate it if needed and close it.
- Note that there is a small time gap, when the file is incomplete,
- and this theoretically might introduce a problem.
-
- RETURN
- 0 - ok
- 1 - some error has occured. Probably due to the lack of resourses
- 2 - cannot open the file
-*/
-
-int modify_defaults_file(const char *file_location, const char *option,
- const char *option_value,
- const char *section_name, int remove_option)
-{
- FILE *cnf_file;
- MY_STAT file_stat;
- char linebuff[BUFF_SIZE], *src_ptr, *dst_ptr, *file_buffer;
- size_t opt_len= 0, optval_len= 0, sect_len, new_opt_len, reserve_extended;
- uint nr_newlines= 0, buffer_size;
- my_bool in_section= FALSE, opt_applied= 0;
- int reserve_occupied= 0;
- DBUG_ENTER("modify_defaults_file");
-
- if (!(cnf_file= my_fopen(file_location, O_RDWR | O_BINARY, MYF(0))))
- DBUG_RETURN(2);
-
- /* my_fstat doesn't use the flag parameter */
- if (my_fstat(my_fileno(cnf_file), &file_stat, MYF(0)))
- goto malloc_err;
-
- if (option && option_value)
- {
- opt_len= strlen(option);
- optval_len= strlen(option_value);
- }
-
- new_opt_len= opt_len + 1 + optval_len + NEWLINE_LEN;
-
- /* calculate the size of the buffer we need */
- reserve_extended= (opt_len +
- 1 + /* For '=' char */
- optval_len + /* Option value len */
- NEWLINE_LEN + /* Space for newline */
- RESERVE); /* Some additional space */
-
- buffer_size= (uint)(file_stat.st_size +
- 1); /* The ending zero */
-
- /*
- Reserve space to read the contents of the file and some more
- for the option we want to add.
- */
- if (!(file_buffer= (char*) my_malloc(buffer_size + reserve_extended,
- MYF(MY_WME))))
- goto malloc_err;
-
- sect_len= strlen(section_name);
-
- for (dst_ptr= file_buffer; fgets(linebuff, BUFF_SIZE, cnf_file); )
- {
- /* Skip over whitespaces */
- for (src_ptr= linebuff; my_isspace(&my_charset_latin1, *src_ptr);
- src_ptr++)
- {}
-
- if (!*src_ptr) /* Empty line */
- {
- nr_newlines++;
- continue;
- }
-
- /* correct the option (if requested) */
- if (option && in_section && !strncmp(src_ptr, option, opt_len) &&
- (*(src_ptr + opt_len) == '=' ||
- my_isspace(&my_charset_latin1, *(src_ptr + opt_len)) ||
- *(src_ptr + opt_len) == '\0'))
- {
- char *old_src_ptr= src_ptr;
- src_ptr= strend(src_ptr+ opt_len); /* Find the end of the line */
-
- /* could be negative */
- reserve_occupied+= (int) new_opt_len - (int) (src_ptr - old_src_ptr);
- if (reserve_occupied >= (int) reserve_extended)
- {
- reserve_extended= (uint) reserve_occupied + RESERVE;
- if (!(file_buffer= (char*) my_realloc(file_buffer, buffer_size +
- reserve_extended,
- MYF(MY_WME|MY_FREE_ON_ERROR))))
- goto malloc_err;
- }
- opt_applied= 1;
- dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
- }
- else
- {
- /*
- If we are going to the new group and have an option to apply, do
- it now. If we are removing a single option or the whole section
- this will only trigger opt_applied flag.
- */
-
- if (in_section && !opt_applied && *src_ptr == '[')
- {
- dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
- opt_applied= 1; /* set the flag to do write() later */
- reserve_occupied= new_opt_len+ opt_len + 1 + NEWLINE_LEN;
- }
-
- for (; nr_newlines; nr_newlines--)
- dst_ptr= strmov(dst_ptr, NEWLINE);
-
- /* Skip the section if MY_REMOVE_SECTION was given */
- if (!in_section || remove_option != MY_REMOVE_SECTION)
- dst_ptr= strmov(dst_ptr, linebuff);
- }
- /* Look for a section */
- if (*src_ptr == '[')
- {
- /* Copy the line to the buffer */
- if (!strncmp(++src_ptr, section_name, sect_len))
- {
- src_ptr+= sect_len;
- /* Skip over whitespaces. They are allowed after section name */
- for (; my_isspace(&my_charset_latin1, *src_ptr); src_ptr++)
- {}
-
- if (*src_ptr != ']')
- {
- in_section= FALSE;
- continue; /* Missing closing parenthesis. Assume this was no group */
- }
-
- if (remove_option == MY_REMOVE_SECTION)
- dst_ptr= dst_ptr - strlen(linebuff);
-
- in_section= TRUE;
- }
- else
- in_section= FALSE; /* mark that this section is of no interest to us */
- }
- }
-
- /*
- File ended. Apply an option or set opt_applied flag (in case of
- MY_REMOVE_SECTION) so that the changes are saved. Do not do anything
- if we are removing non-existent option.
- */
-
- if (!opt_applied && in_section && (remove_option != MY_REMOVE_OPTION))
- {
- /* New option still remains to apply at the end */
- if (!remove_option && *(dst_ptr - 1) != '\n')
- dst_ptr= strmov(dst_ptr, NEWLINE);
- dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
- opt_applied= 1;
- }
- for (; nr_newlines; nr_newlines--)
- dst_ptr= strmov(dst_ptr, NEWLINE);
-
- if (opt_applied)
- {
- /* Don't write the file if there are no changes to be made */
- if (my_chsize(my_fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0,
- MYF(MY_WME)) ||
- my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) ||
- my_fwrite(cnf_file, (uchar*) file_buffer, (size_t) (dst_ptr - file_buffer),
- MYF(MY_NABP)))
- goto err;
- }
- if (my_fclose(cnf_file, MYF(MY_WME)))
- DBUG_RETURN(1);
-
- my_free(file_buffer, MYF(0));
- DBUG_RETURN(0);
-
-err:
- my_free(file_buffer, MYF(0));
-malloc_err:
- my_fclose(cnf_file, MYF(0));
- DBUG_RETURN(1); /* out of resources */
-}
-
-
-static char *add_option(char *dst, const char *option_value,
- const char *option, int remove_option)
-{
- if (!remove_option)
- {
- dst= strmov(dst, option);
- if (*option_value)
- {
- *dst++= '=';
- dst= strmov(dst, option_value);
- }
- /* add a newline */
- dst= strmov(dst, NEWLINE);
- }
- return dst;
-}
diff --git a/mysys/errors.c b/mysys/errors.c
index a2f4ce298f1..1063cae8856 100644
--- a/mysys/errors.c
+++ b/mysys/errors.c
@@ -12,15 +12,14 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
#ifndef SHARED_LIBRARY
-const char * NEAR globerrs[GLOBERRS]=
+const char *globerrs[GLOBERRS]=
{
"Can't create/write to file '%s' (Errcode: %d)",
"Error reading file '%s' (Errcode: %d)",
@@ -99,9 +98,9 @@ void init_glob_errs()
EE(EE_FILE_NOT_CLOSED) = "File '%s' (fileno: %d) was not closed";
EE(EE_CHANGE_OWNERSHIP) = "Can't change ownership of the file '%s' (Errcode: %d)";
EE(EE_CHANGE_PERMISSIONS) = "Can't change permissions of the file '%s' (Errcode: %d)";
+ EE(EE_CANT_SEEK) = "Can't seek in file '%s' (Errcode: %d)";
EE(EE_CANT_CHMOD) = "Can't change mode for file '%s' to 0x%lx (Error: %d)";
EE(EE_CANT_COPY_OWNERSHIP)= "Warning: Can't copy ownership for file '%s' (Error: %d)";
- EE(EE_CANT_SEEK) = "Can't seek in file '%s' (Errcode: %d)";
}
#endif
@@ -116,5 +115,10 @@ void wait_for_free_space(const char *filename, int errors)
MYF(ME_BELL | ME_NOREFRESH | ME_JUST_WARNING),
MY_WAIT_FOR_USER_TO_FIX_PANIC,
MY_WAIT_GIVE_USER_A_MESSAGE * MY_WAIT_FOR_USER_TO_FIX_PANIC );
- VOID(sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC));
+ (void) sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC);
+}
+
+const char **get_global_errmsgs()
+{
+ return globerrs;
}
diff --git a/mysys/hash.c b/mysys/hash.c
index f60092391fa..b93f6b666d6 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -1,6 +1,4 @@
-/*
- Copyright (c) 2000-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* Copyright (c) 2000, 2010, 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
@@ -13,8 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* The hash functions used for saveing keys */
/* One of key_length or key_length_offset must be given */
@@ -36,16 +33,18 @@ typedef struct st_hash_info {
uchar *data; /* data for current entry */
} HASH_LINK;
-static uint my_hash_mask(size_t hashnr, size_t buffmax, size_t maxlength);
+static uint my_hash_mask(my_hash_value_type hashnr,
+ size_t buffmax, size_t maxlength);
static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink);
static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
size_t length);
-static uint calc_hash(const HASH *hash, const uchar *key, size_t length)
+static my_hash_value_type calc_hash(const HASH *hash,
+ const uchar *key, size_t length)
{
ulong nr1=1, nr2=4;
hash->charset->coll->hash_sort(hash->charset,(uchar*) key,length,&nr1,&nr2);
- return nr1;
+ return (my_hash_value_type)nr1;
}
/**
@@ -68,8 +67,6 @@ static uint calc_hash(const HASH *hash, const uchar *key, size_t length)
@param[in] get_key get the key for the hash
@param[in] free_element pointer to the function that
does cleanup
- @param[in] CALLER_INFO_PROTO flag that define the behaviour
- of the hash
@return inidicates success or failure of initialization
@retval 0 success
@retval 1 failure
@@ -78,8 +75,9 @@ my_bool
_my_hash_init(HASH *hash, uint growth_size, CHARSET_INFO *charset,
ulong size, size_t key_offset, size_t key_length,
my_hash_get_key get_key,
- void (*free_element)(void*), uint flags CALLER_INFO_PROTO)
+ void (*free_element)(void*), uint flags)
{
+ my_bool res;
DBUG_ENTER("my_hash_init");
DBUG_PRINT("enter",("hash: 0x%lx size: %u", (long) hash, (uint) size));
@@ -91,8 +89,9 @@ _my_hash_init(HASH *hash, uint growth_size, CHARSET_INFO *charset,
hash->free=free_element;
hash->flags=flags;
hash->charset=charset;
- DBUG_RETURN(my_init_dynamic_array_ci(&hash->array,
- sizeof(HASH_LINK), size, growth_size));
+ res= my_init_dynamic_array_ci(&hash->array,
+ sizeof(HASH_LINK), size, growth_size);
+ DBUG_RETURN(res);
}
@@ -183,7 +182,8 @@ my_hash_key(const HASH *hash, const uchar *record, size_t *length,
/* Calculate pos according to keys */
-static uint my_hash_mask(size_t hashnr, size_t buffmax, size_t maxlength)
+static uint my_hash_mask(my_hash_value_type hashnr, size_t buffmax,
+ size_t maxlength)
{
if ((hashnr & (buffmax-1)) < maxlength)
return (uint) (hashnr & (buffmax-1));
@@ -205,7 +205,7 @@ static
#if !defined(__USLC__) && !defined(__sgi)
inline
#endif
-unsigned int rec_hashnr(HASH *hash,const uchar *record)
+my_hash_value_type rec_hashnr(HASH *hash,const uchar *record)
{
size_t length;
uchar *key= (uchar*) my_hash_key(hash, record, &length, 0);
@@ -219,6 +219,23 @@ uchar* my_hash_search(const HASH *hash, const uchar *key, size_t length)
return my_hash_first(hash, key, length, &state);
}
+uchar* my_hash_search_using_hash_value(const HASH *hash,
+ my_hash_value_type hash_value,
+ const uchar *key,
+ size_t length)
+{
+ HASH_SEARCH_STATE state;
+ return my_hash_first_from_hash_value(hash, hash_value,
+ key, length, &state);
+}
+
+my_hash_value_type my_calc_hash(const HASH *hash,
+ const uchar *key, size_t length)
+{
+ return calc_hash(hash, key, length ? length : hash->key_length);
+}
+
+
/*
Search after a record based on a key
@@ -229,14 +246,31 @@ uchar* my_hash_search(const HASH *hash, const uchar *key, size_t length)
uchar* my_hash_first(const HASH *hash, const uchar *key, size_t length,
HASH_SEARCH_STATE *current_record)
{
+ uchar *res;
+ if (my_hash_inited(hash))
+ res= my_hash_first_from_hash_value(hash,
+ calc_hash(hash, key, length ? length : hash->key_length),
+ key, length, current_record);
+ else
+ res= 0;
+ return res;
+}
+
+
+uchar* my_hash_first_from_hash_value(const HASH *hash,
+ my_hash_value_type hash_value,
+ const uchar *key,
+ size_t length,
+ HASH_SEARCH_STATE *current_record)
+{
HASH_LINK *pos;
uint flag,idx;
- DBUG_ENTER("my_hash_first");
+ DBUG_ENTER("my_hash_first_from_hash_value");
flag=1;
if (hash->records)
{
- idx= my_hash_mask(calc_hash(hash, key, length ? length : hash->key_length),
+ idx= my_hash_mask(hash_value,
hash->blength, hash->records);
do
{
@@ -342,7 +376,8 @@ static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
my_bool my_hash_insert(HASH *info, const uchar *record)
{
int flag;
- size_t idx,halfbuff,hash_nr,first_index;
+ size_t idx,halfbuff,first_index;
+ my_hash_value_type hash_nr;
uchar *UNINIT_VAR(ptr_to_rec),*UNINIT_VAR(ptr_to_rec2);
HASH_LINK *data,*empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos;
@@ -488,7 +523,8 @@ my_bool my_hash_insert(HASH *info, const uchar *record)
my_bool my_hash_delete(HASH *hash, uchar *record)
{
- uint pos2,pos_hashnr,lastpos_hashnr,idx,empty_index;
+ uint pos2,idx,empty_index;
+ my_hash_value_type pos_hashnr, lastpos_hashnr;
size_t blength;
HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
DBUG_ENTER("my_hash_delete");
@@ -563,7 +599,7 @@ my_bool my_hash_delete(HASH *hash, uchar *record)
pos->next=empty_index;
exit:
- VOID(pop_dynamic(&hash->array));
+ (void) pop_dynamic(&hash->array);
if (hash->free)
(*hash->free)((uchar*) record);
DBUG_RETURN(0);
diff --git a/mysys/lf_alloc-pin.c b/mysys/lf_alloc-pin.c
index 0293bfc6faf..6ab6ba3aae0 100644
--- a/mysys/lf_alloc-pin.c
+++ b/mysys/lf_alloc-pin.c
@@ -1,10 +1,9 @@
/* QQ: TODO multi-pinbox */
-/* Copyright (C) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2006, 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; either version 2 of the License, or
- (at your option) any later version.
+ 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
@@ -13,7 +12,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
wait-free concurrent allocator based on pinning addresses
@@ -147,6 +146,7 @@ void lf_pinbox_destroy(LF_PINBOX *pinbox)
*/
LF_PINS *_lf_pinbox_get_pins(LF_PINBOX *pinbox)
{
+ struct st_my_thread_var *var;
uint32 pins, next, top_ver;
LF_PINS *el;
/*
@@ -189,7 +189,12 @@ LF_PINS *_lf_pinbox_get_pins(LF_PINBOX *pinbox)
el->link= pins;
el->purgatory_count= 0;
el->pinbox= pinbox;
- el->stack_ends_here= & my_thread_var->stack_ends_here;
+ var= my_thread_var;
+ /*
+ Threads that do not call my_thread_init() should still be
+ able to use the LF_HASH.
+ */
+ el->stack_ends_here= (var ? & var->stack_ends_here : NULL);
return el;
}
@@ -206,13 +211,16 @@ void _lf_pinbox_put_pins(LF_PINS *pins)
LF_PINBOX *pinbox= pins->pinbox;
uint32 top_ver, nr;
nr= pins->link;
-#ifdef MY_LF_EXTRA_DEBUG
+
+#ifndef DBUG_OFF
{
+ /* This thread should not hold any pin. */
int i;
for (i= 0; i < LF_PINBOX_PINS; i++)
DBUG_ASSERT(pins->pin[i] == 0);
}
-#endif
+#endif /* DBUG_OFF */
+
/*
XXX this will deadlock if other threads will wait for
the caller to do something after _lf_pinbox_put_pins(),
@@ -263,7 +271,7 @@ static int ptr_cmp(void **a, void **b)
void _lf_pinbox_free(LF_PINS *pins, void *addr)
{
add_to_purgatory(pins, addr);
- if (pins->purgatory_count % LF_PURGATORY_SIZE)
+ if (pins->purgatory_count % LF_PURGATORY_SIZE == 0)
_lf_pinbox_real_free(pins);
}
@@ -328,35 +336,36 @@ static int match_pins(LF_PINS *el, void *addr)
*/
static void _lf_pinbox_real_free(LF_PINS *pins)
{
- int npins, alloca_size;
- void *list, **addr;
- void *first, *last= NULL;
+ int npins;
+ void *list;
+ void **addr= NULL;
+ void *first= NULL, *last= NULL;
LF_PINBOX *pinbox= pins->pinbox;
- LINT_INIT(first);
npins= pinbox->pins_in_array+1;
#ifdef HAVE_ALLOCA
- alloca_size= sizeof(void *)*LF_PINBOX_PINS*npins;
- /* create a sorted list of pinned addresses, to speed up searches */
- if (available_stack_size(&pinbox, *pins->stack_ends_here) > alloca_size)
+ if (pins->stack_ends_here != NULL)
{
- struct st_harvester hv;
- addr= (void **) alloca(alloca_size);
- hv.granary= addr;
- hv.npins= npins;
- /* scan the dynarray and accumulate all pinned addresses */
- _lf_dynarray_iterate(&pinbox->pinarray,
- (lf_dynarray_func)harvest_pins, &hv);
-
- npins= hv.granary-addr;
- /* and sort them */
- if (npins)
- qsort(addr, npins, sizeof(void *), (qsort_cmp)ptr_cmp);
+ int alloca_size= sizeof(void *)*LF_PINBOX_PINS*npins;
+ /* create a sorted list of pinned addresses, to speed up searches */
+ if (available_stack_size(&pinbox, *pins->stack_ends_here) > alloca_size)
+ {
+ struct st_harvester hv;
+ addr= (void **) alloca(alloca_size);
+ hv.granary= addr;
+ hv.npins= npins;
+ /* scan the dynarray and accumulate all pinned addresses */
+ _lf_dynarray_iterate(&pinbox->pinarray,
+ (lf_dynarray_func)harvest_pins, &hv);
+
+ npins= hv.granary-addr;
+ /* and sort them */
+ if (npins)
+ qsort(addr, npins, sizeof(void *), (qsort_cmp)ptr_cmp);
+ }
}
- else
#endif
- addr= 0;
list= pins->purgatory;
pins->purgatory= 0;
@@ -474,7 +483,7 @@ void lf_alloc_destroy(LF_ALLOCATOR *allocator)
uchar *tmp= anext_node(node);
if (allocator->destructor)
allocator->destructor(node);
- my_free((void *)node, MYF(0));
+ my_free(node);
node= tmp;
}
lf_pinbox_destroy(&allocator->pinbox);
diff --git a/mysys/lf_dynarray.c b/mysys/lf_dynarray.c
index 7c8f54f07cf..3d072fd063e 100644
--- a/mysys/lf_dynarray.c
+++ b/mysys/lf_dynarray.c
@@ -1,9 +1,8 @@
-/* Copyright (C) 2006 MySQL AB
+/* Copyright (c) 2006, 2010, 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; either version 2 of the License, or
- (at your option) any later version.
+ 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
@@ -12,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
Analog of DYNAMIC_ARRAY that never reallocs
@@ -58,10 +57,10 @@ static void recursive_free(void **alloc, int level)
int i;
for (i= 0; i < LF_DYNARRAY_LEVEL_LENGTH; i++)
recursive_free(alloc[i], level-1);
- my_free((void *)alloc, MYF(0));
+ my_free(alloc);
}
else
- my_free(alloc[-1], MYF(0));
+ my_free(alloc[-1]);
}
void lf_dynarray_destroy(LF_DYNARRAY *array)
@@ -116,7 +115,7 @@ void *_lf_dynarray_lvalue(LF_DYNARRAY *array, uint idx)
if (my_atomic_casptr(ptr_ptr, &ptr, alloc))
ptr= alloc;
else
- my_free(alloc, MYF(0));
+ my_free(alloc);
}
ptr_ptr= ((void **)ptr) + idx / dynarray_idxes_in_prev_level[i];
idx%= dynarray_idxes_in_prev_level[i];
@@ -140,7 +139,7 @@ void *_lf_dynarray_lvalue(LF_DYNARRAY *array, uint idx)
if (my_atomic_casptr(ptr_ptr, &ptr, data))
ptr= data;
else
- my_free(alloc, MYF(0));
+ my_free(alloc);
}
return ((uchar*)ptr) + array->size_of_element * idx;
}
diff --git a/mysys/lf_hash.c b/mysys/lf_hash.c
index 6569bafc00d..38b212c65f0 100644
--- a/mysys/lf_hash.c
+++ b/mysys/lf_hash.c
@@ -1,9 +1,8 @@
-/* Copyright (C) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2006, 2010, 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; either version 2 of the License, or
- (at your option) any later version.
+ 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
@@ -12,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
extensible hash
@@ -269,8 +268,10 @@ static LF_SLIST *lsearch(LF_SLIST * volatile *head, CHARSET_INFO *cs,
int res= lfind(head, cs, hashnr, key, keylen, &cursor, pins);
if (res)
_lf_pin(pins, 2, cursor.curr);
- _lf_unpin(pins, 0);
+ else
+ _lf_unpin(pins, 2);
_lf_unpin(pins, 1);
+ _lf_unpin(pins, 0);
return res ? cursor.curr : 0;
}
@@ -315,7 +316,7 @@ static int initialize_bucket(LF_HASH *, LF_SLIST * volatile*, uint, LF_PINS *);
See wt_init() for example.
*/
void lf_hash_init(LF_HASH *hash, uint element_size, uint flags,
- uint key_offset, uint key_length, hash_get_key get_key,
+ uint key_offset, uint key_length, my_hash_get_key get_key,
CHARSET_INFO *charset)
{
lf_alloc_init(&hash->alloc, sizeof(LF_SLIST)+element_size,
@@ -336,18 +337,18 @@ void lf_hash_destroy(LF_HASH *hash)
{
LF_SLIST *el, **head= (LF_SLIST **)_lf_dynarray_value(&hash->array, 0);
- if (unlikely(!head))
- return;
- el= *head;
-
- while (el)
+ if (head)
{
- intptr next= el->link;
- if (el->hashnr & 1)
- lf_alloc_direct_free(&hash->alloc, el); /* normal node */
- else
- my_free((void *)el, MYF(0)); /* dummy node */
- el= (LF_SLIST *)next;
+ el= *head;
+ while (el)
+ {
+ intptr next= el->link;
+ if (el->hashnr & 1)
+ lf_alloc_direct_free(&hash->alloc, el); /* normal node */
+ else
+ my_free(el); /* dummy node */
+ el= (LF_SLIST *)next;
+ }
}
lf_alloc_destroy(&hash->alloc);
lf_dynarray_destroy(&hash->array);
@@ -491,7 +492,7 @@ static int initialize_bucket(LF_HASH *hash, LF_SLIST * volatile *node,
dummy->keylen= 0;
if ((cur= linsert(el, hash->charset, dummy, pins, LF_HASH_UNIQUE)))
{
- my_free((void *)dummy, MYF(0));
+ my_free(dummy);
dummy= cur;
}
my_atomic_casptr((void **)node, (void **)(char*) &tmp, dummy);
diff --git a/mysys/list.c b/mysys/list.c
index aaadd686365..fb46120db04 100644
--- a/mysys/list.c
+++ b/mysys/list.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
Code for handling dubble-linked lists in C
@@ -61,8 +61,8 @@ void list_free(LIST *root, uint free_data)
{
next=root->next;
if (free_data)
- my_free((uchar*) root->data,MYF(0));
- my_free((uchar*) root,MYF(0));
+ my_free(root->data);
+ my_free(root);
root=next;
}
}
diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c
index 03d9007c7cb..c717f69c3e5 100644
--- a/mysys/ma_dyncol.c
+++ b/mysys/ma_dyncol.c
@@ -949,8 +949,7 @@ static void type_and_offset_read(DYNAMIC_COLUMN_TYPE *type,
size_t *offset,
uchar *place, size_t offset_size)
{
- ulong val;
- LINT_INIT(val);
+ ulong UNINIT_VAR(val);
place+= COLUMN_NUMBER_SIZE; /* skip column number */
switch (offset_size) {
@@ -1625,8 +1624,7 @@ dynamic_column_list(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_uint)
if (entry_size * column_count + FIXED_HEADER_SIZE > str->length)
return ER_DYNCOL_FORMAT;
- if (init_dynamic_array(array_of_uint, sizeof(uint),
- column_count, 0 CALLER_INFO))
+ if (init_dynamic_array(array_of_uint, sizeof(uint), column_count, 0))
return ER_DYNCOL_RESOURCE;
for (i= 0, read= (uchar *)str->str + FIXED_HEADER_SIZE;
@@ -2079,7 +2077,7 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str,
rc= ER_DYNCOL_OK;
end:
- my_free(plan, MYF(0));
+ my_free(plan);
return rc;
create_new_string:
diff --git a/mysys/make-ccc b/mysys/make-ccc
deleted file mode 100755
index b34bd80e1d1..00000000000
--- a/mysys/make-ccc
+++ /dev/null
@@ -1,4 +0,0 @@
-rm -f .deps/* raid.o mf_iocache.o libmysys.a
-ccc -DDEFAULT_BASEDIR="\"/usr/local/mysql\"" -DDATADIR="\"/usr/local/mysql/var\"" -DHAVE_CONFIG_H -I./../include -I../include -I.. -DDBUG_OFF -fast -O3 -fomit-frame-pointer -c array.c checksum.c default.c errors.c getopt.c getopt1.c getvar.c hash.c list.c mf_brkhant.c mf_cache.c mf_casecnv.c mf_dirname.c mf_fn_ext.c mf_format.c mf_getdate.c mf_keycache.c mf_loadpath.c mf_pack.c mf_pack2.c mf_path.c mf_qsort.c mf_qsort2.c mf_radix.c mf_reccache.c mf_same.c mf_sort.c mf_soundex.c mf_stripp.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_alarm.c my_alloc.c my_append.c my_chsize.c my_clock.c my_compress.c my_copy.c my_create.c my_delete.c my_div.c my_error.c my_fopen.c my_fstream.c my_getwd.c my_init.c my_lib.c my_lockmem.c my_malloc.c my_messnc.c my_mkdir.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_static.c my_tempnam.c my_thr_init.c my_write.c ptr_cmp.c queues.c safemalloc.c string.c thr_alarm.c thr_lock.c thr_mutex.c thr_rwlock.c tree.c typelib.c
-make raid.o mf_iocache.o my_lock.o
-ar -cr libmysys.a array.o raid.o mf_iocache.o my_lock.o
diff --git a/mysys/make-conf.c b/mysys/make-conf.c
deleted file mode 100644
index 0dacde4dee0..00000000000
--- a/mysys/make-conf.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Copyright (C) 2000 MySQL 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* make-conf.c
- * make a charset .conf file out of a ctype-charset.c file.
- */
-
-#ifndef CHARSET
-#error You must define the charset, e.g.: -DCHARSET=latin1
-#endif
-
-/* some pre-processor tricks to get us going */
-#define _STRINGIZE_HELPER(x) #x
-#define STRINGIZE(x) _STRINGIZE_HELPER(x)
-
-#define _JOIN_WORDS_HELPER(a, b) a ## b
-#define JOIN_WORDS(a, b) _JOIN_WORDS_HELPER(a, b)
-
-#define CH_SRC ctype- ## CHARSET ## .c
-#define CH_INCLUDE STRINGIZE(CH_SRC)
-
-/* aaaah, that's better */
-#include <my_my_global.h>
-#include CH_INCLUDE
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#define ROW_LEN 16
-
-void print_array(const char *name, const uchar *array, uint size);
-
-int main(void)
-{
- printf("# Configuration file for the "
- STRINGIZE(CHARSET)
- " character set.\n");
-
- print_array("ctype", JOIN_WORDS(ctype_, CHARSET), 257);
- print_array("to_lower", JOIN_WORDS(to_lower_, CHARSET), 256);
- print_array("to_upper", JOIN_WORDS(to_upper_, CHARSET), 256);
- print_array("sort_order", JOIN_WORDS(sort_order_, CHARSET), 256);
-
- exit(EXIT_SUCCESS);
-}
-
-void print_array(const char *name, const uchar *array, uint size)
-{
- uint i;
-
- printf("\n# The %s array must have %d elements.\n", name, size);
-
- for (i = 0; i < size; ++i) {
- printf(" %02X", array[i]);
-
- if ((i+1) % ROW_LEN == size % ROW_LEN)
- printf("\n");
- }
-}
diff --git a/mysys/md5.c b/mysys/md5.c
index 2388cebedc4..22a5e409a09 100644
--- a/mysys/md5.c
+++ b/mysys/md5.c
@@ -176,7 +176,7 @@ my_MD5Final (unsigned char digest[16], my_MD5Context *ctx)
putu32(ctx->buf[1], digest + 4);
putu32(ctx->buf[2], digest + 8);
putu32(ctx->buf[3], digest + 12);
- memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
+ memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
}
#ifndef ASM_MD5
diff --git a/mysys/mf_brkhant.c b/mysys/mf_brkhant.c
deleted file mode 100644
index 3573b9973b2..00000000000
--- a/mysys/mf_brkhant.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Copyright (C) 2000 MySQL 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Dont let the user break when you are doing something important */
-/* Remembers if it got 'SIGINT' and executes it on allow_break */
-/* A static buffer is used; don't call dont_break() twice in a row */
-
-#include "mysys_priv.h"
-#include "my_static.h"
-
- /* Set variable that we can't break */
-
-#if !defined(THREAD)
-void dont_break(void)
-{
- my_dont_interrupt=1;
- return;
-} /* dont_break */
-
-void allow_break(void)
-{
- {
- reg1 int index;
-
- my_dont_interrupt=0;
- if (_my_signals)
- {
- if (_my_signals > MAX_SIGNALS)
- _my_signals=MAX_SIGNALS;
- for (index=0 ; index < _my_signals ; index++)
- {
- if (_my_sig_remember[index].func) /* Safequard */
- {
- (*_my_sig_remember[index].func)(_my_sig_remember[index].number);
- _my_sig_remember[index].func=0;
- }
- }
- _my_signals=0;
- }
- }
-} /* dont_break */
-#endif
-
- /* Set old status */
-
-#if !defined(THREAD)
-void my_remember_signal(int signal_number, sig_handler (*func) (int))
-{
-#ifndef __WIN__
- reg1 int index;
-
- index=_my_signals++; /* Nobody can break a ++ ? */
- if (index < MAX_SIGNALS)
- {
- _my_sig_remember[index].number=signal_number;
- _my_sig_remember[index].func=func;
- }
-#endif /* __WIN__ */
-} /* my_remember_signal */
-#endif /* THREAD */
diff --git a/mysys/mf_cache.c b/mysys/mf_cache.c
index f0df0f3fa77..545084ea97f 100644
--- a/mysys/mf_cache.c
+++ b/mysys/mf_cache.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* Open a temporary file and cache it with io_cache. Delete it on close */
@@ -71,8 +71,8 @@ my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix,
{
DBUG_RETURN(0);
}
- my_free(cache->dir, MYF(MY_ALLOW_ZERO_PTR));
- my_free(cache->prefix,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(cache->dir);
+ my_free(cache->prefix);
DBUG_RETURN(1);
}
@@ -110,12 +110,12 @@ void close_cached_file(IO_CACHE *cache)
if (cache->file_name)
{
(void) my_delete(cache->file_name,MYF(MY_WME | ME_NOINPUT));
- my_free(cache->file_name,MYF(0));
+ my_free(cache->file_name);
}
#endif
}
- my_free(cache->dir,MYF(MY_ALLOW_ZERO_PTR));
- my_free(cache->prefix,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(cache->dir);
+ my_free(cache->prefix);
}
DBUG_VOID_RETURN;
}
diff --git a/mysys/mf_dirname.c b/mysys/mf_dirname.c
index 1b428ded751..569293f5401 100644
--- a/mysys/mf_dirname.c
+++ b/mysys/mf_dirname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include <m_string.h>
@@ -40,11 +40,7 @@ size_t dirname_length(const char *name)
continue;
}
#endif
- if (*pos == FN_LIBCHAR || *pos == '/'
-#ifdef FN_C_AFTER_DIR
- || *pos == FN_C_AFTER_DIR || *pos == FN_C_AFTER_DIR_2
-#endif
- )
+ if (*pos == FN_LIBCHAR || *pos == '/')
gpos=pos;
}
return (size_t) (gpos+1-(char*) name);
@@ -88,8 +84,7 @@ size_t dirname_part(char *to, const char *name, size_t *to_res_length)
from_end Pointer at end of filename (normally end \0)
IMPLEMENTATION
- If MSDOS converts '/' to '\'
- If VMS converts '<' to '[' and '>' to ']'
+ If Windows converts '/' to '\'
Adds a FN_LIBCHAR to end if the result string if there isn't one
and the last isn't dev_char.
Copies data from 'from' until ASCII(0) for until from == from_end
@@ -118,18 +113,12 @@ char *convert_dirname(char *to, const char *from, const char *from_end)
if (!from_end || (from_end - from) > FN_REFLEN-2)
from_end=from+FN_REFLEN -2;
-#if FN_LIBCHAR != '/' || defined(FN_C_BEFORE_DIR_2)
+#if FN_LIBCHAR != '/'
{
for (; from != from_end && *from ; from++)
{
if (*from == '/')
*to++= FN_LIBCHAR;
-#ifdef FN_C_BEFORE_DIR_2
- else if (*from == FN_C_BEFORE_DIR_2)
- *to++= FN_C_BEFORE_DIR;
- else if (*from == FN_C_AFTER_DIR_2)
- *to++= FN_C_AFTER_DIR;
-#endif
else
{
#ifdef BACKSLASH_MBTAIL
diff --git a/mysys/mf_fn_ext.c b/mysys/mf_fn_ext.c
index da7fac3de73..47fc67cabbd 100644
--- a/mysys/mf_fn_ext.c
+++ b/mysys/mf_fn_ext.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
@@ -39,7 +39,7 @@ char *fn_ext(const char *name)
DBUG_ENTER("fn_ext");
DBUG_PRINT("mfunkt",("name: '%s'",name));
-#if defined(FN_DEVCHAR) || defined(FN_C_AFTER_DIR) || defined(BASKSLASH_MBTAIL)
+#if defined(FN_DEVCHAR) || defined(BASKSLASH_MBTAIL)
{
char buff[FN_REFLEN];
size_t res_length;
diff --git a/mysys/mf_format.c b/mysys/mf_format.c
index b0c7075aa9a..2b2356c08df 100644
--- a/mysys/mf_format.c
+++ b/mysys/mf_format.c
@@ -1,6 +1,4 @@
-/*
- Copyright (c) 2000-2007 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* 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
@@ -13,8 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include <m_string.h>
@@ -34,6 +31,8 @@ char * fn_format(char * to, const char *name, const char *dir,
reg1 size_t length;
size_t dev_length;
DBUG_ENTER("fn_format");
+ DBUG_ASSERT(name != NULL);
+ DBUG_ASSERT(extension != NULL);
DBUG_PRINT("enter",("name: %s dir: %s extension: %s flag: %d",
name,dir,extension,flag));
diff --git a/mysys/mf_getdate.c b/mysys/mf_getdate.c
index e09dd0603dc..ed8544a23fe 100644
--- a/mysys/mf_getdate.c
+++ b/mysys/mf_getdate.c
@@ -1,5 +1,4 @@
-/*
- Copyright (c) 2000, 2004-2007 MySQL AB, 2009 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2004-2007 MySQL AB, 2009 Sun Microsystems, Inc.
Use is subject to license terms.
This program is free software; you can redistribute it and/or modify
@@ -13,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* Get date in a printable form: yyyy-mm-dd hh:mm:ss */
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 8caca5d438b..02e5c5373ae 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
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
@@ -12,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
Cashing of files with only does (sequential) read or writes of fixed-
@@ -49,7 +48,6 @@ TODO:
write buffer to the read buffer before we start to reuse it.
*/
-#define MAP_TO_USE_RAID
#include "mysys_priv.h"
#include <m_string.h>
#ifdef HAVE_AIOWAIT
@@ -58,15 +56,10 @@ static void my_aiowait(my_aio_result *result);
#endif
#include <errno.h>
-#ifdef THREAD
#define lock_append_buffer(info) \
- pthread_mutex_lock(&(info)->append_buffer_lock)
+ mysql_mutex_lock(&(info)->append_buffer_lock)
#define unlock_append_buffer(info) \
- pthread_mutex_unlock(&(info)->append_buffer_lock)
-#else
-#define lock_append_buffer(info)
-#define unlock_append_buffer(info)
-#endif
+ mysql_mutex_unlock(&(info)->append_buffer_lock)
#define IO_ROUND_UP(X) (((X)+IO_SIZE-1) & ~(IO_SIZE-1))
#define IO_ROUND_DN(X) ( (X) & ~(IO_SIZE-1))
@@ -119,11 +112,7 @@ init_functions(IO_CACHE* info)
info->write_function = 0; /* Force a core if used */
break;
default:
- info->read_function =
-#ifdef THREAD
- info->share ? _my_b_read_r :
-#endif
- _my_b_read;
+ info->read_function = info->share ? _my_b_read_r : _my_b_read;
info->write_function = _my_b_write;
}
@@ -176,7 +165,7 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize,
if (file >= 0)
{
- pos= my_tell(file, MYF(0));
+ pos= mysql_file_tell(file, MYF(0));
if ((pos == (my_off_t) -1) && (my_errno == ESPIPE))
{
/*
@@ -194,9 +183,7 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize,
}
info->disk_writes= 0;
-#ifdef THREAD
info->share=0;
-#endif
if (!cachesize && !(cachesize= my_default_record_cache_size))
DBUG_RETURN(1); /* No cache requested */
@@ -206,7 +193,7 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize,
if (!(cache_myflags & MY_DONT_CHECK_FILESIZE))
{
/* Calculate end of file to avoid allocating oversized buffers */
- end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
+ end_of_file= mysql_file_seek(file, 0L, MY_SEEK_END, MYF(0));
/* Need to reset seek_not_done now that we just did a seek. */
info->seek_not_done= end_of_file == seek_offset ? 0 : 1;
if (end_of_file < seek_offset)
@@ -264,11 +251,10 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize,
{
info->append_read_pos = info->write_pos = info->write_buffer;
info->write_end = info->write_buffer + info->buffer_length;
-#ifdef THREAD
- pthread_mutex_init(&info->append_buffer_lock,MY_MUTEX_INIT_FAST);
-#endif
+ mysql_mutex_init(key_IO_CACHE_append_buffer_lock,
+ &info->append_buffer_lock, MY_MUTEX_INIT_FAST);
}
-#if defined(SAFE_MUTEX) && defined(THREAD)
+#if defined(SAFE_MUTEX)
else
{
/* Clear mutex so that safe_mutex will notice that it's not initialized */
@@ -454,7 +440,9 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
RETURN
0 we succeeded in reading all data
- 1 Error: can't read requested characters
+ 1 Error: couldn't read requested characters. In this case:
+ If info->error == -1, we got a read error.
+ Otherwise info->error contains the number of bytes in Buffer.
*/
int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
@@ -463,6 +451,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
my_off_t pos_in_file;
DBUG_ENTER("_my_b_read");
+ /* If the buffer is not empty yet, copy what is available. */
if ((left_length= (size_t) (info->read_end-info->read_pos)))
{
DBUG_ASSERT(Count >= left_length); /* User is not using my_b_read() */
@@ -474,7 +463,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
/* pos_in_file always point on where info->buffer was read */
pos_in_file=info->pos_in_file+ (size_t) (info->read_end - info->buffer);
- /*
+ /*
Whenever a function which operates on IO_CACHE flushes/writes
some part of the IO_CACHE to disk it will set the property
"seek_not_done" to indicate this to other functions operating
@@ -482,7 +471,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
*/
if (info->seek_not_done)
{
- if ((my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0))
+ if ((mysql_file_seek(info->file, pos_in_file, MY_SEEK_SET, MYF(0))
!= MY_FILEPOS_ERROR))
{
/* No error, reset seek_not_done flag. */
@@ -501,19 +490,38 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
}
}
+ /*
+ Calculate, how much we are within a IO_SIZE block. Ideally this
+ should be zero.
+ */
diff_length= (size_t) (pos_in_file & (IO_SIZE-1));
+
+ /*
+ If more than a block plus the rest of the current block is wanted,
+ we do read directly, without filling the buffer.
+ */
if (Count >= (size_t) (IO_SIZE+(IO_SIZE-diff_length)))
{ /* Fill first intern buffer */
size_t read_length;
if (info->end_of_file <= pos_in_file)
- { /* End of file */
+ {
+ /* End of file. Return, what we did copy from the buffer. */
info->error= (int) left_length;
DBUG_RETURN(1);
}
+ /*
+ Crop the wanted count to a multiple of IO_SIZE and subtract,
+ what we did already read from a block. That way, the read will
+ end aligned with a block.
+ */
length=(Count & (size_t) ~(IO_SIZE-1))-diff_length;
- if ((read_length= my_read(info->file,Buffer, length, info->myflags))
+ if ((read_length= mysql_file_read(info->file,Buffer, length, info->myflags))
!= length)
{
+ /*
+ If we didn't get, what we wanted, we either return -1 for a read
+ error, or (it's end of file), how much we got in total.
+ */
info->error= (read_length == (size_t) -1 ? -1 :
(int) (read_length+left_length));
DBUG_RETURN(1);
@@ -525,30 +533,52 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
diff_length=0;
}
+ /*
+ At this point, we want less than one and a partial block.
+ We will read a full cache, minus the number of bytes, we are
+ within a block already. So we will reach new alignment.
+ */
max_length= info->read_length-diff_length;
+ /* We will not read past end of file. */
if (info->type != READ_FIFO &&
max_length > (info->end_of_file - pos_in_file))
max_length= (size_t) (info->end_of_file - pos_in_file);
+ /*
+ If there is nothing left to read,
+ we either are done, or we failed to fulfill the request.
+ Otherwise, we read max_length into the cache.
+ */
if (!max_length)
{
if (Count)
{
- info->error= (int) left_length; /* We only got this many char */
+ /* We couldn't fulfil the request. Return, how much we got. */
+ info->error= (int) left_length;
DBUG_RETURN(1);
}
length=0; /* Didn't read any chars */
}
- else if ((length= my_read(info->file,info->buffer, max_length,
+ else if ((length= mysql_file_read(info->file,info->buffer, max_length,
info->myflags)) < Count ||
length == (size_t) -1)
{
+ /*
+ We got an read error, or less than requested (end of file).
+ If not a read error, copy, what we got.
+ */
if (length != (size_t) -1)
memcpy(Buffer, info->buffer, length);
info->pos_in_file= pos_in_file;
+ /* For a read error, return -1, otherwise, what we got in total. */
info->error= length == (size_t) -1 ? -1 : (int) (length+left_length);
info->read_pos=info->read_end=info->buffer;
DBUG_RETURN(1);
}
+ /*
+ Count is the remaining number of bytes requested.
+ length is the amount of data in the cache.
+ Read Count bytes from the cache.
+ */
info->read_pos=info->buffer+Count;
info->read_end=info->buffer+length;
info->pos_in_file=pos_in_file;
@@ -557,7 +587,6 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
}
-#ifdef THREAD
/*
Prepare IO_CACHE for shared use.
@@ -639,9 +668,10 @@ void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare,
DBUG_ASSERT(read_cache->type == READ_CACHE);
DBUG_ASSERT(!write_cache || (write_cache->type == WRITE_CACHE));
- pthread_mutex_init(&cshare->mutex, MY_MUTEX_INIT_FAST);
- pthread_cond_init(&cshare->cond, 0);
- pthread_cond_init(&cshare->cond_writer, 0);
+ mysql_mutex_init(key_IO_CACHE_SHARE_mutex,
+ &cshare->mutex, MY_MUTEX_INIT_FAST);
+ mysql_cond_init(key_IO_CACHE_SHARE_cond, &cshare->cond, 0);
+ mysql_cond_init(key_IO_CACHE_SHARE_cond_writer, &cshare->cond_writer, 0);
cshare->running_threads= num_threads;
cshare->total_threads= num_threads;
@@ -692,7 +722,7 @@ void remove_io_thread(IO_CACHE *cache)
if (cache == cshare->source_cache)
flush_io_cache(cache);
- pthread_mutex_lock(&cshare->mutex);
+ mysql_mutex_lock(&cshare->mutex);
DBUG_PRINT("io_cache_share", ("%s: 0x%lx",
(cache == cshare->source_cache) ?
"writer" : "reader", (long) cache));
@@ -715,18 +745,18 @@ void remove_io_thread(IO_CACHE *cache)
if (!--cshare->running_threads)
{
DBUG_PRINT("io_cache_share", ("the last running thread leaves, wake all"));
- pthread_cond_signal(&cshare->cond_writer);
- pthread_cond_broadcast(&cshare->cond);
+ mysql_cond_signal(&cshare->cond_writer);
+ mysql_cond_broadcast(&cshare->cond);
}
- pthread_mutex_unlock(&cshare->mutex);
+ mysql_mutex_unlock(&cshare->mutex);
if (!total)
{
DBUG_PRINT("io_cache_share", ("last thread removed, destroy share"));
- pthread_cond_destroy (&cshare->cond_writer);
- pthread_cond_destroy (&cshare->cond);
- pthread_mutex_destroy(&cshare->mutex);
+ mysql_cond_destroy (&cshare->cond_writer);
+ mysql_cond_destroy (&cshare->cond);
+ mysql_mutex_destroy(&cshare->mutex);
}
DBUG_VOID_RETURN;
@@ -767,7 +797,7 @@ static int lock_io_cache(IO_CACHE *cache, my_off_t pos)
DBUG_ENTER("lock_io_cache");
/* Enter the lock. */
- pthread_mutex_lock(&cshare->mutex);
+ mysql_mutex_lock(&cshare->mutex);
cshare->running_threads--;
DBUG_PRINT("io_cache_share", ("%s: 0x%lx pos: %lu running: %u",
(cache == cshare->source_cache) ?
@@ -784,7 +814,7 @@ static int lock_io_cache(IO_CACHE *cache, my_off_t pos)
while (cshare->running_threads)
{
DBUG_PRINT("io_cache_share", ("writer waits in lock"));
- pthread_cond_wait(&cshare->cond_writer, &cshare->mutex);
+ mysql_cond_wait(&cshare->cond_writer, &cshare->mutex);
}
DBUG_PRINT("io_cache_share", ("writer awoke, going to copy"));
@@ -796,7 +826,7 @@ static int lock_io_cache(IO_CACHE *cache, my_off_t pos)
if (!cshare->running_threads)
{
DBUG_PRINT("io_cache_share", ("waking writer"));
- pthread_cond_signal(&cshare->cond_writer);
+ mysql_cond_signal(&cshare->cond_writer);
}
/*
@@ -808,7 +838,7 @@ static int lock_io_cache(IO_CACHE *cache, my_off_t pos)
cshare->source_cache)
{
DBUG_PRINT("io_cache_share", ("reader waits in lock"));
- pthread_cond_wait(&cshare->cond, &cshare->mutex);
+ mysql_cond_wait(&cshare->cond, &cshare->mutex);
}
/*
@@ -850,7 +880,7 @@ static int lock_io_cache(IO_CACHE *cache, my_off_t pos)
cshare->running_threads)
{
DBUG_PRINT("io_cache_share", ("reader waits in lock"));
- pthread_cond_wait(&cshare->cond, &cshare->mutex);
+ mysql_cond_wait(&cshare->cond, &cshare->mutex);
}
/* If the block is not yet read, continue with a locked cache and read. */
@@ -872,7 +902,7 @@ static int lock_io_cache(IO_CACHE *cache, my_off_t pos)
Leave the lock. Do not call unlock_io_cache() later. The thread that
filled the buffer did this and marked all threads as running.
*/
- pthread_mutex_unlock(&cshare->mutex);
+ mysql_mutex_unlock(&cshare->mutex);
DBUG_RETURN(0);
}
@@ -915,8 +945,8 @@ static void unlock_io_cache(IO_CACHE *cache)
cshare->total_threads));
cshare->running_threads= cshare->total_threads;
- pthread_cond_broadcast(&cshare->cond);
- pthread_mutex_unlock(&cshare->mutex);
+ mysql_cond_broadcast(&cshare->cond);
+ mysql_mutex_unlock(&cshare->mutex);
DBUG_VOID_RETURN;
}
@@ -1011,7 +1041,7 @@ int _my_b_read_r(register IO_CACHE *cache, uchar *Buffer, size_t Count)
*/
if (cache->seek_not_done)
{
- if (my_seek(cache->file, pos_in_file, MY_SEEK_SET, MYF(0))
+ if (mysql_file_seek(cache->file, pos_in_file, MY_SEEK_SET, MYF(0))
== MY_FILEPOS_ERROR)
{
cache->error= -1;
@@ -1019,7 +1049,7 @@ int _my_b_read_r(register IO_CACHE *cache, uchar *Buffer, size_t Count)
DBUG_RETURN(1);
}
}
- len= my_read(cache->file, cache->buffer, length, cache->myflags);
+ len= mysql_file_read(cache->file, cache->buffer, length, cache->myflags);
}
DBUG_PRINT("io_cache_share", ("read %lu bytes", (ulong) len));
@@ -1117,7 +1147,6 @@ static void copy_to_read_buffer(IO_CACHE *write_cache,
write_length-= copy_length;
}
}
-#endif /*THREAD*/
/*
@@ -1158,7 +1187,7 @@ int _my_b_seq_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
With read-append cache we must always do a seek before we read,
because the write could have moved the file pointer astray
*/
- if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) == MY_FILEPOS_ERROR)
+ if (mysql_file_seek(info->file, pos_in_file, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR)
{
info->error= -1;
unlock_append_buffer(info);
@@ -1175,8 +1204,8 @@ int _my_b_seq_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
size_t read_length;
length=(Count & (size_t) ~(IO_SIZE-1))-diff_length;
- if ((read_length= my_read(info->file,Buffer, length,
- info->myflags)) == (size_t) -1)
+ if ((read_length= mysql_file_read(info->file,Buffer, length,
+ info->myflags)) == (size_t) -1)
{
info->error= -1;
unlock_append_buffer(info);
@@ -1209,7 +1238,7 @@ int _my_b_seq_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
}
else
{
- length= my_read(info->file,info->buffer, max_length, info->myflags);
+ length= mysql_file_read(info->file,info->buffer, max_length, info->myflags);
if (length == (size_t) -1)
{
info->error= -1;
@@ -1386,7 +1415,7 @@ int _my_b_async_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
return 1;
}
- if (my_seek(info->file,next_pos_in_file,MY_SEEK_SET,MYF(0))
+ if (mysql_file_seek(info->file, next_pos_in_file, MY_SEEK_SET, MYF(0))
== MY_FILEPOS_ERROR)
{
info->error= -1;
@@ -1396,8 +1425,8 @@ int _my_b_async_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
read_length=IO_SIZE*2- (size_t) (next_pos_in_file & (IO_SIZE-1));
if (Count < read_length)
{ /* Small block, read to cache */
- if ((read_length=my_read(info->file,info->request_pos,
- read_length, info->myflags)) == (size_t) -1)
+ if ((read_length=mysql_file_read(info->file,info->request_pos,
+ read_length, info->myflags)) == (size_t) -1)
return info->error= -1;
use_length=min(Count,read_length);
memcpy(Buffer,info->request_pos,(size_t) use_length);
@@ -1417,7 +1446,7 @@ int _my_b_async_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
}
else
{ /* Big block, don't cache it */
- if ((read_length= my_read(info->file,Buffer, Count,info->myflags))
+ if ((read_length= mysql_file_read(info->file, Buffer, Count,info->myflags))
!= Count)
{
info->error= read_length == (size_t) -1 ? -1 : read_length+left_length;
@@ -1498,8 +1527,13 @@ int _my_b_get(IO_CACHE *info)
int _my_b_write(register IO_CACHE *info, const uchar *Buffer, size_t Count)
{
size_t rest_length,length;
+ my_off_t pos_in_file= info->pos_in_file;
- if (info->pos_in_file+info->buffer_length > info->end_of_file)
+ DBUG_EXECUTE_IF("simulate_huge_load_data_file",
+ {
+ pos_in_file=(my_off_t)(5000000000ULL);
+ });
+ if (pos_in_file+info->buffer_length > info->end_of_file)
{
my_errno=errno=EFBIG;
return info->error = -1;
@@ -1524,17 +1558,16 @@ int _my_b_write(register IO_CACHE *info, const uchar *Buffer, size_t Count)
"seek_not_done" to indicate this to other functions operating
on the IO_CACHE.
*/
- if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)))
+ if (mysql_file_seek(info->file, info->pos_in_file, MY_SEEK_SET, MYF(0)))
{
info->error= -1;
return (1);
}
info->seek_not_done=0;
}
- if (my_write(info->file, Buffer, length, info->myflags | MY_NABP))
+ if (mysql_file_write(info->file, Buffer, length, info->myflags | MY_NABP))
return info->error= -1;
-#ifdef THREAD
/*
In case of a shared I/O cache with a writer we normally do direct
write cache to read cache copy. Simulate this here by direct
@@ -1548,7 +1581,6 @@ int _my_b_write(register IO_CACHE *info, const uchar *Buffer, size_t Count)
*/
if (info->share)
copy_to_read_buffer(info, Buffer, length);
-#endif
Count-=length;
Buffer+=length;
@@ -1570,13 +1602,11 @@ int my_b_append(register IO_CACHE *info, const uchar *Buffer, size_t Count)
{
size_t rest_length,length;
-#ifdef THREAD
/*
Assert that we cannot come here with a shared cache. If we do one
day, we might need to add a call to copy_to_read_buffer().
*/
DBUG_ASSERT(!info->share);
-#endif
lock_append_buffer(info);
rest_length= (size_t) (info->write_end - info->write_pos);
@@ -1594,7 +1624,7 @@ int my_b_append(register IO_CACHE *info, const uchar *Buffer, size_t Count)
if (Count >= IO_SIZE)
{ /* Fill first intern buffer */
length=Count & (size_t) ~(IO_SIZE-1);
- if (my_write(info->file,Buffer, length, info->myflags | MY_NABP))
+ if (mysql_file_write(info->file,Buffer, length, info->myflags | MY_NABP))
{
unlock_append_buffer(info);
return info->error= -1;
@@ -1638,23 +1668,21 @@ int my_block_write(register IO_CACHE *info, const uchar *Buffer, size_t Count,
size_t length;
int error=0;
-#ifdef THREAD
/*
Assert that we cannot come here with a shared cache. If we do one
day, we might need to add a call to copy_to_read_buffer().
*/
DBUG_ASSERT(!info->share);
-#endif
if (pos < info->pos_in_file)
{
/* Of no overlap, write everything without buffering */
if (pos + Count <= info->pos_in_file)
- return (int) my_pwrite(info->file, Buffer, Count, pos,
- info->myflags | MY_NABP);
+ return (int)mysql_file_pwrite(info->file, Buffer, Count, pos,
+ info->myflags | MY_NABP);
/* Write the part of the block that is before buffer */
length= (uint) (info->pos_in_file - pos);
- if (my_pwrite(info->file, Buffer, length, pos, info->myflags | MY_NABP))
+ if (mysql_file_pwrite(info->file, Buffer, length, pos, info->myflags | MY_NABP))
info->error= error= -1;
Buffer+=length;
pos+= length;
@@ -1687,16 +1715,10 @@ int my_block_write(register IO_CACHE *info, const uchar *Buffer, size_t Count,
/* Flush write cache */
-#ifdef THREAD
#define LOCK_APPEND_BUFFER if (need_append_buffer_lock) \
lock_append_buffer(info);
#define UNLOCK_APPEND_BUFFER if (need_append_buffer_lock) \
unlock_append_buffer(info);
-#else
-#define LOCK_APPEND_BUFFER
-#define UNLOCK_APPEND_BUFFER
-#endif
-
int my_b_flush_io_cache(IO_CACHE *info,
int need_append_buffer_lock __attribute__((unused)))
@@ -1707,10 +1729,8 @@ int my_b_flush_io_cache(IO_CACHE *info,
DBUG_ENTER("my_b_flush_io_cache");
DBUG_PRINT("enter", ("cache: 0x%lx", (long) info));
-#ifdef THREAD
if (!append_cache)
need_append_buffer_lock= 0;
-#endif
if (info->type == WRITE_CACHE || append_cache)
{
@@ -1723,7 +1743,6 @@ int my_b_flush_io_cache(IO_CACHE *info,
if ((length=(size_t) (info->write_pos - info->write_buffer)))
{
-#ifdef THREAD
/*
In case of a shared I/O cache with a writer we do direct write
cache to read cache copy. Do it before the write here so that
@@ -1732,7 +1751,6 @@ int my_b_flush_io_cache(IO_CACHE *info,
*/
if (info->share)
copy_to_read_buffer(info, info->write_buffer, length);
-#endif
pos_in_file=info->pos_in_file;
/*
@@ -1741,7 +1759,7 @@ int my_b_flush_io_cache(IO_CACHE *info,
*/
if (!append_cache && info->seek_not_done)
{ /* File touched, do seek */
- if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(info->myflags & MY_WME)) ==
+ if (mysql_file_seek(info->file, pos_in_file, MY_SEEK_SET, MYF(info->myflags & MY_WME)) ==
MY_FILEPOS_ERROR)
{
UNLOCK_APPEND_BUFFER;
@@ -1755,7 +1773,7 @@ int my_b_flush_io_cache(IO_CACHE *info,
info->write_end= (info->write_buffer+info->buffer_length-
((pos_in_file+length) & (IO_SIZE-1)));
- if (my_write(info->file,info->write_buffer,length,
+ if (mysql_file_write(info->file,info->write_buffer,length,
info->myflags | MY_NABP))
info->error= -1;
else
@@ -1767,7 +1785,7 @@ int my_b_flush_io_cache(IO_CACHE *info,
else
{
info->end_of_file+=(info->write_pos-info->append_read_pos);
- DBUG_ASSERT(info->end_of_file == my_tell(info->file,MYF(0)));
+ DBUG_ASSERT(info->end_of_file == mysql_file_tell(info->file, MYF(0)));
}
info->append_read_pos=info->write_pos=info->write_buffer;
@@ -1811,13 +1829,11 @@ int end_io_cache(IO_CACHE *info)
DBUG_ENTER("end_io_cache");
DBUG_PRINT("enter",("cache: 0x%lx", (ulong) info));
-#ifdef THREAD
/*
Every thread must call remove_io_thread(). The last one destroys
the share elements.
*/
DBUG_ASSERT(!info->share || !info->share->total_threads);
-#endif
if ((pre_close=info->pre_close))
{
@@ -1829,20 +1845,16 @@ int end_io_cache(IO_CACHE *info)
info->alloced_buffer=0;
if (info->file != -1) /* File doesn't exist */
error= my_b_flush_io_cache(info,1);
- my_free((uchar*) info->buffer,MYF(MY_WME));
+ my_free(info->buffer);
info->buffer=info->read_pos=(uchar*) 0;
}
if (info->type == SEQ_READ_APPEND)
{
/* Destroy allocated mutex */
info->type= TYPE_NOT_SET;
-#ifdef THREAD
- pthread_mutex_destroy(&info->append_buffer_lock);
-#endif
+ mysql_mutex_destroy(&info->append_buffer_lock);
}
-#ifdef THREAD
info->share= 0;
-#endif
DBUG_RETURN(error);
} /* end_io_cache */
@@ -1918,7 +1930,7 @@ int main(int argc, char** argv)
total_bytes += 4+block_size;
}
close_file(&sra_cache);
- my_free(block,MYF(MY_WME));
+ my_free(block);
if (!my_stat(fname,&status,MYF(MY_WME)))
die("%s failed to stat, but I had just closed it,\
wonder how that happened");
diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c
index 5836314b742..ff05b7fa485 100644
--- a/mysys/mf_iocache2.c
+++ b/mysys/mf_iocache2.c
@@ -1,6 +1,4 @@
-/*
- Copyright (c) 2000-2004, 2006, 2007 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* 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
@@ -13,14 +11,12 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
More functions to be used with IO_CACHE files
*/
-#define MAP_TO_USE_RAID
#include "mysys_priv.h"
#include <m_string.h>
#include <stdarg.h>
@@ -74,6 +70,16 @@ my_b_copy_to_file(IO_CACHE *cache, FILE *file)
my_off_t my_b_append_tell(IO_CACHE* info)
{
/*
+ Sometimes we want to make sure that the variable is not put into
+ a register in debugging mode so we can see its value in the core
+ */
+#ifndef DBUG_OFF
+# define dbug_volatile volatile
+#else
+# define dbug_volatile
+#endif
+
+ /*
Prevent optimizer from putting res in a register when debugging
we need this to be able to see the value of res when the assert fails
*/
@@ -84,9 +90,8 @@ my_off_t my_b_append_tell(IO_CACHE* info)
from messing with the variables that we need in order to provide the
answer to the question.
*/
-#ifdef THREAD
- pthread_mutex_lock(&info->append_buffer_lock);
-#endif
+ mysql_mutex_lock(&info->append_buffer_lock);
+
#ifndef DBUG_OFF
/*
Make sure EOF is where we think it is. Note that we cannot just use
@@ -106,9 +111,7 @@ my_off_t my_b_append_tell(IO_CACHE* info)
}
#endif
res = info->end_of_file + (info->write_pos-info->append_read_pos);
-#ifdef THREAD
- pthread_mutex_unlock(&info->append_buffer_lock);
-#endif
+ mysql_mutex_unlock(&info->append_buffer_lock);
return res;
}
@@ -138,7 +141,7 @@ void my_b_seek(IO_CACHE *info,my_off_t pos)
b) see if there is a better way to make it work
*/
if (info->type == SEQ_READ_APPEND)
- VOID(flush_io_cache(info));
+ (void) flush_io_cache(info);
offset=(pos - info->pos_in_file);
@@ -166,7 +169,7 @@ void my_b_seek(IO_CACHE *info,my_off_t pos)
info->write_pos = info->write_buffer + offset;
DBUG_VOID_RETURN;
}
- VOID(flush_io_cache(info));
+ (void) flush_io_cache(info);
/* Correct buffer end so that we write in increments of IO_SIZE */
info->write_end=(info->write_buffer+info->buffer_length-
(pos & (IO_SIZE-1)));
@@ -520,52 +523,3 @@ err:
return (size_t) -1;
}
-
-int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
- const char *default_val)
-{
- uint length;
- DBUG_ENTER("init_strvar_from_file");
-
- if ((length=my_b_gets(f,var, max_size)))
- {
- char* last_p = var + length -1;
- if (*last_p == '\n')
- *last_p = 0; /* if we stopped on newline, kill it */
- else
- {
- /*
- If we truncated a line or stopped on last char, remove all chars
- up to and including newline.
- */
- int c;
- while (((c=my_b_get(f)) != '\n' && c != my_b_EOF))
- ;
- }
- DBUG_RETURN(0);
- }
- else if (default_val)
- {
- strmake(var, default_val, max_size-1);
- DBUG_RETURN(0);
- }
- DBUG_RETURN(1);
-}
-
-int init_intvar_from_file(int* var, IO_CACHE* f, int default_val)
-{
- char buf[32];
- DBUG_ENTER("init_intvar_from_file");
-
- if (my_b_gets(f, buf, sizeof(buf)))
- {
- *var = atoi(buf);
- DBUG_RETURN(0);
- }
- else if (default_val)
- {
- *var = default_val;
- DBUG_RETURN(0);
- }
- DBUG_RETURN(1);
-}
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index dc2d7fdd127..30f269454c2 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
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
@@ -12,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
@@ -37,6 +36,7 @@
#include <my_bit.h>
#include <errno.h>
#include <stdarg.h>
+#include "probes_mysql.h"
/******************************************************************************
Simple Key Cache Module
@@ -90,13 +90,13 @@
time only.
Before starting to wait on its condition variable with
- pthread_cond_wait(), the thread enters itself to a specific wait queue
+ mysql_cond_wait(), the thread enters itself to a specific wait queue
with link_into_queue() (double linked with '*next' + '**prev') or
wait_on_queue() (single linked with '*next').
Another thread, when releasing a resource, looks up the waiting thread
in the related wait queue. It sends a signal with
- pthread_cond_signal() to the waiting thread.
+ mysql_cond_signal() to the waiting thread.
NOTE: Depending on the particular wait situation, either the sending
thread removes the waiting thread from the wait queue with
@@ -156,11 +156,11 @@ typedef struct st_keycache_wqueue
typedef struct st_simple_key_cache_cb
{
- my_bool key_cache_inited; /* <=> control block is allocated */
+ my_bool key_cache_inited; /* <=> control block is allocated */
my_bool in_resize; /* true during resize operation */
my_bool resize_in_flush; /* true during flush of resize operation */
my_bool can_be_used; /* usage of cache for read/write is allowed */
- size_t key_cache_mem_size; /* specified size of the cache memory */
+ size_t key_cache_mem_size; /* specified size of the cache memory */
uint key_cache_block_size; /* size of the page buffer of a cache block */
ulong min_warm_blocks; /* min number of warm blocks; */
ulong age_threshold; /* age threshold for hot blocks */
@@ -178,12 +178,12 @@ typedef struct st_simple_key_cache_cb
HASH_LINK **hash_root; /* arr. of entries into hash table buckets */
HASH_LINK *hash_link_root; /* memory for hash table links */
HASH_LINK *free_hash_list; /* list of free hash links */
- BLOCK_LINK *free_block_list; /* list of free blocks */
+ BLOCK_LINK *free_block_list; /* list of free blocks */
BLOCK_LINK *block_root; /* memory for block links */
- uchar HUGE_PTR *block_mem; /* memory for block buffers */
+ uchar *block_mem; /* memory for block buffers */
BLOCK_LINK *used_last; /* ptr to the last block of the LRU chain */
BLOCK_LINK *used_ins; /* ptr to the insertion block in LRU chain */
- pthread_mutex_t cache_lock; /* to lock access to the cache structure */
+ mysql_mutex_t cache_lock; /* to lock access to the cache structure */
KEYCACHE_WQUEUE resize_queue; /* threads waiting during resize operation */
/*
Waiting for a zero resize count. Using a queue for symmetry though
@@ -196,7 +196,7 @@ typedef struct st_simple_key_cache_cb
BLOCK_LINK *file_blocks[CHANGED_BLOCKS_HASH]; /* hash for other file bl.*/
/* Statistics variables. These are reset in reset_key_cache_counters(). */
- ulong global_blocks_changed; /* number of currently dirty blocks */
+ ulong global_blocks_changed; /* number of currently dirty blocks */
ulonglong global_cache_w_requests;/* number of write requests (write hits) */
ulonglong global_cache_write; /* number of writes from cache to files */
ulonglong global_cache_r_requests;/* number of read requests (read hits) */
@@ -221,8 +221,8 @@ typedef struct st_simple_key_cache_cb
accessing it;
to set this number equal to <N> add
#define MAX_THREADS <N>
- - to substitute calls of pthread_cond_wait for calls of
- pthread_cond_timedwait (wait with timeout set up);
+ - to substitute calls of mysql_cond_wait for calls of
+ mysql_cond_timedwait (wait with timeout set up);
this setting should be used only when you want to trap a deadlock
situation, which theoretically should not happen;
to set timeout equal to <T> seconds add
@@ -253,7 +253,7 @@ typedef struct st_simple_key_cache_cb
#define COND_FOR_SAVED 1
#define COND_FOR_READERS 2
-typedef pthread_cond_t KEYCACHE_CONDVAR;
+typedef mysql_cond_t KEYCACHE_CONDVAR;
/* descriptor of the page in the key cache block buffer */
struct st_keycache_page
@@ -319,16 +319,11 @@ KEY_CACHE *dflt_key_cache= &dflt_key_cache_var;
static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache);
static void end_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, my_bool cleanup);
-#ifdef THREAD
static void wait_on_queue(KEYCACHE_WQUEUE *wqueue,
- pthread_mutex_t *mutex);
+ mysql_mutex_t *mutex);
static void release_whole_queue(KEYCACHE_WQUEUE *wqueue);
-#else
-#define wait_on_queue(wqueue, mutex) do {} while (0)
-#define release_whole_queue(wqueue) do {} while (0)
-#endif
static void free_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block);
-#if !defined(DBUG_OFF)
+#ifndef DBUG_OFF
static void test_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
const char *where, my_bool lock);
#endif
@@ -347,7 +342,7 @@ static void test_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
#if defined(KEYCACHE_DEBUG_LOG)
static FILE *keycache_debug_log=NULL;
-static void keycache_debug_print _VARARGS((const char *fmt,...));
+static void keycache_debug_print(const char *fmt,...);
#define KEYCACHE_DEBUG_OPEN \
if (!keycache_debug_log) \
{ \
@@ -380,7 +375,6 @@ static void keycache_debug_print _VARARGS((const char *fmt,...));
#endif /* defined(KEYCACHE_DEBUG_LOG) && defined(KEYCACHE_DEBUG) */
#if defined(KEYCACHE_DEBUG) || !defined(DBUG_OFF)
-#ifdef THREAD
static long keycache_thread_id;
#define KEYCACHE_THREAD_TRACE(l) \
KEYCACHE_DBUG_PRINT(l,("|thread %ld",keycache_thread_id))
@@ -392,11 +386,6 @@ static long keycache_thread_id;
#define KEYCACHE_THREAD_TRACE_END(l) \
KEYCACHE_DBUG_PRINT(l,("]thread %ld",keycache_thread_id))
-#else /* THREAD */
-#define KEYCACHE_THREAD_TRACE(l) KEYCACHE_DBUG_PRINT(l,(""))
-#define KEYCACHE_THREAD_TRACE_BEGIN(l) KEYCACHE_DBUG_PRINT(l,(""))
-#define KEYCACHE_THREAD_TRACE_END(l) KEYCACHE_DBUG_PRINT(l,(""))
-#endif /* THREAD */
#else
#define KEYCACHE_THREAD_TRACE_BEGIN(l)
#define KEYCACHE_THREAD_TRACE_END(l)
@@ -409,20 +398,20 @@ static long keycache_thread_id;
((uint) (((char*)(h)-(char *) keycache->hash_link_root)/sizeof(HASH_LINK)))
#if (defined(KEYCACHE_TIMEOUT) && !defined(__WIN__)) || defined(KEYCACHE_DEBUG)
-static int keycache_pthread_cond_wait(pthread_cond_t *cond,
- pthread_mutex_t *mutex);
+static int keycache_pthread_cond_wait(mysql_cond_t *cond,
+ mysql_mutex_t *mutex);
#else
-#define keycache_pthread_cond_wait pthread_cond_wait
+#define keycache_pthread_cond_wait(C, M) mysql_cond_wait(C, M)
#endif
#if defined(KEYCACHE_DEBUG)
-static int keycache_pthread_mutex_lock(pthread_mutex_t *mutex);
-static void keycache_pthread_mutex_unlock(pthread_mutex_t *mutex);
-static int keycache_pthread_cond_signal(pthread_cond_t *cond);
+static int keycache_pthread_mutex_lock(mysql_mutex_t *mutex);
+static void keycache_pthread_mutex_unlock(mysql_mutex_t *mutex);
+static int keycache_pthread_cond_signal(mysql_cond_t *cond);
#else
-#define keycache_pthread_mutex_lock pthread_mutex_lock
-#define keycache_pthread_mutex_unlock pthread_mutex_unlock
-#define keycache_pthread_cond_signal pthread_cond_signal
+#define keycache_pthread_mutex_lock(M) mysql_mutex_lock(M)
+#define keycache_pthread_mutex_unlock(M) mysql_mutex_unlock(M)
+#define keycache_pthread_cond_signal(C) mysql_cond_signal(C)
#endif /* defined(KEYCACHE_DEBUG) */
#if !defined(DBUG_OFF)
@@ -515,7 +504,8 @@ int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_si
keycache->cnt_for_resize_op= 0;
keycache->waiting_for_resize_cnt.last_thread= NULL;
keycache->in_init= 0;
- pthread_mutex_init(&keycache->cache_lock, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_KEY_CACHE_cache_lock,
+ &keycache->cache_lock, MY_MUTEX_INIT_FAST);
keycache->resize_queue.last_thread= NULL;
}
@@ -557,7 +547,7 @@ int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_si
if ((keycache->block_root= (BLOCK_LINK*) my_malloc(length,
MYF(0))))
break;
- my_large_free(keycache->block_mem, MYF(0));
+ my_large_free(keycache->block_mem);
keycache->block_mem= 0;
}
if (blocks < 8)
@@ -632,12 +622,12 @@ err:
keycache->blocks= 0;
if (keycache->block_mem)
{
- my_large_free((uchar*) keycache->block_mem, MYF(0));
+ my_large_free((uchar*) keycache->block_mem);
keycache->block_mem= NULL;
}
if (keycache->block_root)
{
- my_free((uchar*) keycache->block_root, MYF(0));
+ my_free(keycache->block_root);
keycache->block_root= NULL;
}
my_errno= error;
@@ -685,7 +675,6 @@ int prepare_resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
keycache_pthread_mutex_lock(&keycache->cache_lock);
-#ifdef THREAD
/*
We may need to wait for another thread which is doing a resize
already. This cannot happen in the MySQL server though. It allows
@@ -698,7 +687,6 @@ int prepare_resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
wait_on_queue(&keycache->resize_queue, &keycache->cache_lock);
/* purecov: end */
}
-#endif
/*
Mark the operation in progress. This blocks other threads from doing
@@ -727,7 +715,6 @@ int prepare_resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
keycache->resize_in_flush= 0;
}
-#ifdef THREAD
/*
Some direct read/write operations (bypassing the cache) may still be
unfinished. Wait until they are done. If the key cache can be used,
@@ -741,9 +728,6 @@ int prepare_resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
*/
while (keycache->cnt_for_resize_op)
wait_on_queue(&keycache->waiting_for_resize_cnt, &keycache->cache_lock);
-#else
- KEYCACHE_DBUG_ASSERT(keycache->cnt_for_resize_op == 0);
-#endif
end_simple_key_cache(keycache, 0);
@@ -793,7 +777,7 @@ void finish_resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
if (acquire_lock)
keycache_pthread_mutex_lock(&keycache->cache_lock);
- safe_mutex_assert_owner(&keycache->cache_lock);
+ mysql_mutex_assert_owner(&keycache->cache_lock);
/*
Mark the resize finished. This allows other threads to start a
@@ -987,9 +971,9 @@ void end_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, my_bool cleanup)
{
if (keycache->block_mem)
{
- my_large_free((uchar*) keycache->block_mem, MYF(0));
+ my_large_free((uchar*) keycache->block_mem);
keycache->block_mem= NULL;
- my_free((uchar*) keycache->block_root, MYF(0));
+ my_free(keycache->block_root);
keycache->block_root= NULL;
}
keycache->disk_blocks= -1;
@@ -1014,7 +998,7 @@ void end_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, my_bool cleanup)
if (cleanup)
{
- pthread_mutex_destroy(&keycache->cache_lock);
+ mysql_mutex_destroy(&keycache->cache_lock);
keycache->key_cache_inited= keycache->can_be_used= 0;
KEYCACHE_DEBUG_CLOSE;
}
@@ -1022,8 +1006,6 @@ void end_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, my_bool cleanup)
} /* end_key_cache */
-#ifdef THREAD
-
/*
Link a thread into double-linked queue of waiting threads.
@@ -1129,7 +1111,7 @@ static void unlink_from_queue(KEYCACHE_WQUEUE *wqueue,
*/
static void wait_on_queue(KEYCACHE_WQUEUE *wqueue,
- pthread_mutex_t *mutex)
+ mysql_mutex_t *mutex)
{
struct st_my_thread_var *last;
struct st_my_thread_var *thread= my_thread_var;
@@ -1203,8 +1185,6 @@ static void release_whole_queue(KEYCACHE_WQUEUE *wqueue)
wqueue->last_thread= NULL;
}
-#endif /* THREAD */
-
/*
Unlink a block from the chain of dirty/clean blocks
@@ -1376,7 +1356,6 @@ static void link_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block,
DBUG_ASSERT(block->prev_changed && *block->prev_changed == block);
DBUG_ASSERT(!block->next_used);
DBUG_ASSERT(!block->prev_used);
-#ifdef THREAD
if (!hot && keycache->waiting_for_block.last_thread)
{
/* Signal that in the LRU warm sub-chain an available block has appeared */
@@ -1436,10 +1415,6 @@ static void link_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block,
#endif
return;
}
-#else /* THREAD */
- KEYCACHE_DBUG_ASSERT(! (!hot && keycache->waiting_for_block.last_thread));
- /* Condition not transformed using DeMorgan, to keep the text identical */
-#endif /* THREAD */
pins= hot ? &keycache->used_ins : &keycache->used_last;
ins= *pins;
if (ins)
@@ -1662,12 +1637,8 @@ static void remove_reader(BLOCK_LINK *block)
DBUG_ASSERT(!block->next_used);
DBUG_ASSERT(!block->prev_used);
DBUG_ASSERT(block->hash_link->requests);
-#ifdef THREAD
if (! --block->hash_link->requests && block->condvar)
keycache_pthread_cond_signal(block->condvar);
-#else
- --block->hash_link->requests;
-#endif
}
@@ -1679,7 +1650,6 @@ static void remove_reader(BLOCK_LINK *block)
static void wait_for_readers(SIMPLE_KEY_CACHE_CB *keycache,
BLOCK_LINK *block)
{
-#ifdef THREAD
struct st_my_thread_var *thread= my_thread_var;
DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
DBUG_ASSERT(!(block->status & (BLOCK_IN_FLUSH | BLOCK_CHANGED)));
@@ -1701,9 +1671,6 @@ static void wait_for_readers(SIMPLE_KEY_CACHE_CB *keycache,
keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock);
block->condvar= NULL;
}
-#else
- KEYCACHE_DBUG_ASSERT(block->hash_link->requests == 0);
-#endif
}
@@ -1733,7 +1700,6 @@ static void unlink_hash(SIMPLE_KEY_CACHE_CB *keycache, HASH_LINK *hash_link)
if ((*hash_link->prev= hash_link->next))
hash_link->next->prev= hash_link->prev;
hash_link->block= NULL;
-#ifdef THREAD
if (keycache->waiting_for_hash_link.last_thread)
{
/* Signal that a free hash link has appeared */
@@ -1769,9 +1735,6 @@ static void unlink_hash(SIMPLE_KEY_CACHE_CB *keycache, HASH_LINK *hash_link)
hash_link);
return;
}
-#else /* THREAD */
- KEYCACHE_DBUG_ASSERT(! (keycache->waiting_for_hash_link.last_thread));
-#endif /* THREAD */
hash_link->next= keycache->free_hash_list;
keycache->free_hash_list= hash_link;
}
@@ -1836,7 +1799,6 @@ restart:
}
else
{
-#ifdef THREAD
/* Wait for a free hash link */
struct st_my_thread_var *thread= my_thread_var;
KEYCACHE_PAGE page;
@@ -1850,9 +1812,6 @@ restart:
keycache_pthread_cond_wait(&thread->suspend,
&keycache->cache_lock);
thread->opt_info= NULL;
-#else
- KEYCACHE_DBUG_ASSERT(0);
-#endif
goto restart;
}
hash_link->file= file;
@@ -1972,7 +1931,6 @@ restart:
- block assigned but not yet read from file (invalid data).
*/
-#ifdef THREAD
if (keycache->in_resize)
{
/* This is a request during a resize operation */
@@ -2214,9 +2172,6 @@ restart:
}
DBUG_RETURN(0);
}
-#else /* THREAD */
- DBUG_ASSERT(!keycache->in_resize);
-#endif
if (page_status == PAGE_READ &&
(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH |
@@ -2346,7 +2301,6 @@ restart:
from the LRU ring.
*/
-#ifdef THREAD
if (! keycache->used_last)
{
/*
@@ -2379,9 +2333,6 @@ restart:
DBUG_ASSERT(!hash_link->block->next_used);
DBUG_ASSERT(!hash_link->block->prev_used);
}
-#else
- KEYCACHE_DBUG_ASSERT(keycache->used_last);
-#endif
/*
If we waited above, hash_link->block has been assigned by
link_block(). Otherwise it is still NULL. In the latter case
@@ -2815,6 +2766,15 @@ uchar *simple_key_cache_read(SIMPLE_KEY_CACHE_CB *keycache,
uint offset;
int page_st;
+ if (MYSQL_KEYCACHE_READ_START_ENABLED())
+ {
+ MYSQL_KEYCACHE_READ_START(my_filename(file), length,
+ (ulong) (keycache->blocks_used *
+ keycache->key_cache_block_size),
+ (ulong) (keycache->blocks_unused *
+ keycache->key_cache_block_size));
+ }
+
/*
When the key cache is once initialized, we use the cache_lock to
reliably distinguish the cases of normal operation, resizing, and
@@ -2859,13 +2819,11 @@ uchar *simple_key_cache_read(SIMPLE_KEY_CACHE_CB *keycache,
set_if_smaller(read_length, keycache->key_cache_block_size-offset);
KEYCACHE_DBUG_ASSERT(read_length > 0);
-#ifndef THREAD
- if (block_length > keycache->key_cache_block_size || offset)
- return_buffer=0;
-#endif
-
/* Request the cache block that matches file/pos. */
keycache->global_cache_r_requests++;
+
+ MYSQL_KEYCACHE_READ_BLOCK(keycache->key_cache_block_size);
+
block=find_key_block(keycache, file, filepos, level, 0, &page_st);
if (!block)
{
@@ -2885,6 +2843,7 @@ uchar *simple_key_cache_read(SIMPLE_KEY_CACHE_CB *keycache,
{
if (page_st != PAGE_READ)
{
+ MYSQL_KEYCACHE_READ_MISS();
/* The requested page is to be read into the block buffer */
read_block(keycache, block,
keycache->key_cache_block_size, read_length+offset,
@@ -2909,14 +2868,15 @@ uchar *simple_key_cache_read(SIMPLE_KEY_CACHE_CB *keycache,
my_errno= -1;
block->status|= BLOCK_ERROR;
}
+ else
+ {
+ MYSQL_KEYCACHE_READ_HIT();
+ }
}
/* block status may have added BLOCK_ERROR in the above 'if'. */
if (!(block->status & BLOCK_ERROR))
{
-#ifndef THREAD
- if (! return_buffer)
-#endif
{
DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
#if !defined(SERIALIZED_READ_FROM_CACHE)
@@ -2924,10 +2884,7 @@ uchar *simple_key_cache_read(SIMPLE_KEY_CACHE_CB *keycache,
#endif
/* Copy data from the cache buffer */
- if (!(read_length & 511))
- bmove512(buff, block->buffer+offset, read_length);
- else
- memcpy(buff, block->buffer+offset, (size_t) read_length);
+ memcpy(buff, block->buffer+offset, (size_t) read_length);
#if !defined(SERIALIZED_READ_FROM_CACHE)
keycache_pthread_mutex_lock(&keycache->cache_lock);
@@ -2958,17 +2915,19 @@ uchar *simple_key_cache_read(SIMPLE_KEY_CACHE_CB *keycache,
break;
}
-#ifndef THREAD
- /* This is only true if we where able to read everything in one block */
- if (return_buffer)
- DBUG_RETURN(block->buffer);
-#endif
next_block:
buff+= read_length;
filepos+= read_length+offset;
offset= 0;
} while ((length-= read_length));
+ if (MYSQL_KEYCACHE_READ_DONE_ENABLED())
+ {
+ MYSQL_KEYCACHE_READ_DONE((ulong) (keycache->blocks_used *
+ keycache->key_cache_block_size),
+ (ulong) (keycache->blocks_unused *
+ keycache->key_cache_block_size));
+ }
goto end;
}
KEYCACHE_DBUG_PRINT("key_cache_read", ("keycache not initialized"));
@@ -3164,10 +3123,7 @@ int simple_key_cache_insert(SIMPLE_KEY_CACHE_CB *keycache,
#endif
/* Copy data from buff */
- if (!(read_length & 511))
- bmove512(block->buffer+offset, buff, read_length);
- else
- memcpy(block->buffer+offset, buff, (size_t) read_length);
+ memcpy(block->buffer+offset, buff, (size_t) read_length);
#if !defined(SERIALIZED_READ_FROM_CACHE)
keycache_pthread_mutex_lock(&keycache->cache_lock);
@@ -3347,6 +3303,15 @@ int simple_key_cache_write(SIMPLE_KEY_CACHE_CB *keycache,
uint offset;
int page_st;
+ if (MYSQL_KEYCACHE_WRITE_START_ENABLED())
+ {
+ MYSQL_KEYCACHE_WRITE_START(my_filename(file), length,
+ (ulong) (keycache->blocks_used *
+ keycache->key_cache_block_size),
+ (ulong) (keycache->blocks_unused *
+ keycache->key_cache_block_size));
+ }
+
/*
When the key cache is once initialized, we use the cache_lock to
reliably distinguish the cases of normal operation, resizing, and
@@ -3382,6 +3347,8 @@ int simple_key_cache_write(SIMPLE_KEY_CACHE_CB *keycache,
/* Cache could be disabled in a later iteration. */
if (!keycache->can_be_used)
goto no_key_cache;
+
+ MYSQL_KEYCACHE_WRITE_BLOCK(keycache->key_cache_block_size);
/* Start writing at the beginning of the cache block. */
filepos-= offset;
/* Do not write beyond the end of the cache block. */
@@ -3500,10 +3467,7 @@ int simple_key_cache_write(SIMPLE_KEY_CACHE_CB *keycache,
#if !defined(SERIALIZED_READ_FROM_CACHE)
keycache_pthread_mutex_unlock(&keycache->cache_lock);
#endif
- if (!(read_length & 511))
- bmove512(block->buffer+offset, buff, read_length);
- else
- memcpy(block->buffer+offset, buff, (size_t) read_length);
+ memcpy(block->buffer+offset, buff, (size_t) read_length);
#if !defined(SERIALIZED_READ_FROM_CACHE)
keycache_pthread_mutex_lock(&keycache->cache_lock);
@@ -3595,6 +3559,15 @@ end:
dec_counter_for_resize_op(keycache);
keycache_pthread_mutex_unlock(&keycache->cache_lock);
}
+
+ if (MYSQL_KEYCACHE_WRITE_DONE_ENABLED())
+ {
+ MYSQL_KEYCACHE_WRITE_DONE((ulong) (keycache->blocks_used *
+ keycache->key_cache_block_size),
+ (ulong) (keycache->blocks_unused *
+ keycache->key_cache_block_size));
+ }
+
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE("exec",
test_key_cache(keycache, "end of key_cache_write", 1););
@@ -4218,17 +4191,11 @@ restart:
if (!(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH |
BLOCK_REASSIGNED)))
{
- struct st_hash_link *next_hash_link;
- my_off_t next_diskpos;
- File next_file;
- uint next_status;
- uint hash_requests;
-
- LINT_INIT(next_hash_link);
- LINT_INIT(next_diskpos);
- LINT_INIT(next_file);
- LINT_INIT(next_status);
- LINT_INIT(hash_requests);
+ struct st_hash_link *UNINIT_VAR(next_hash_link);
+ my_off_t UNINIT_VAR(next_diskpos);
+ File UNINIT_VAR(next_file);
+ uint UNINIT_VAR(next_status);
+ uint UNINIT_VAR(hash_requests);
total_found++;
found++;
@@ -4332,7 +4299,7 @@ restart:
#endif
err:
if (cache != cache_buff)
- my_free((uchar*) cache, MYF(0));
+ my_free(cache);
if (last_errno)
errno=last_errno; /* Return first error */
DBUG_RETURN(last_errno != 0);
@@ -4443,7 +4410,7 @@ static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache)
do
{
- safe_mutex_assert_owner(&keycache->cache_lock);
+ mysql_mutex_assert_owner(&keycache->cache_lock);
total_found= 0;
/*
@@ -4691,8 +4658,8 @@ static void keycache_dump(SIMPLE_KEY_CACHE_CB *keycache)
#if defined(KEYCACHE_TIMEOUT) && !defined(__WIN__)
-static int keycache_pthread_cond_wait(pthread_cond_t *cond,
- pthread_mutex_t *mutex)
+static int keycache_pthread_cond_wait(mysql_cond_t *cond,
+ mysql_mutex_t *mutex)
{
int rc;
struct timeval now; /* time when we started waiting */
@@ -4719,7 +4686,7 @@ static int keycache_pthread_cond_wait(pthread_cond_t *cond,
fprintf(keycache_debug_log, "waiting...\n");
fflush(keycache_debug_log);
#endif
- rc= pthread_cond_timedwait(cond, mutex, &timeout);
+ rc= mysql_cond_timedwait(cond, mutex, &timeout);
KEYCACHE_THREAD_TRACE_BEGIN("finished waiting");
if (rc == ETIMEDOUT || rc == ETIME)
{
@@ -4740,12 +4707,12 @@ static int keycache_pthread_cond_wait(pthread_cond_t *cond,
}
#else
#if defined(KEYCACHE_DEBUG)
-static int keycache_pthread_cond_wait(pthread_cond_t *cond,
- pthread_mutex_t *mutex)
+static int keycache_pthread_cond_wait(mysql_cond_t *cond,
+ mysql_mutex_t *mutex)
{
int rc;
KEYCACHE_THREAD_TRACE_END("started waiting");
- rc= pthread_cond_wait(cond, mutex);
+ rc= mysql_cond_wait(cond, mutex);
KEYCACHE_THREAD_TRACE_BEGIN("finished waiting");
return rc;
}
@@ -4755,27 +4722,27 @@ static int keycache_pthread_cond_wait(pthread_cond_t *cond,
#if defined(KEYCACHE_DEBUG)
-static int keycache_pthread_mutex_lock(pthread_mutex_t *mutex)
+static int keycache_pthread_mutex_lock(mysql_mutex_t *mutex)
{
int rc;
- rc= pthread_mutex_lock(mutex);
+ rc= mysql_mutex_lock(mutex);
KEYCACHE_THREAD_TRACE_BEGIN("");
return rc;
}
-static void keycache_pthread_mutex_unlock(pthread_mutex_t *mutex)
+static void keycache_pthread_mutex_unlock(mysql_mutex_t *mutex)
{
KEYCACHE_THREAD_TRACE_END("");
- pthread_mutex_unlock(mutex);
+ mysql_mutex_unlock(mutex);
}
-static int keycache_pthread_cond_signal(pthread_cond_t *cond)
+static int keycache_pthread_cond_signal(mysql_cond_t *cond)
{
int rc;
KEYCACHE_THREAD_TRACE("signal");
- rc= pthread_cond_signal(cond);
+ rc= mysql_cond_signal(cond);
return rc;
}
@@ -5151,7 +5118,7 @@ int init_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
end_simple_key_cache(partition, 1);
if (!key_cache_inited)
{
- my_free(partition, MYF(0));
+ my_free(partition);
partition= 0;
}
if ((i == 0 && cnt < 0) || i > 0)
@@ -5170,7 +5137,7 @@ int init_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
*/
if (key_cache_inited)
{
- my_free(partition, MYF(0));
+ my_free(partition);
partition= 0;
if(key_cache_inited)
memmove(partition_ptr, partition_ptr+1,
@@ -5379,8 +5346,8 @@ void end_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
if (cleanup)
{
for (i= 0; i < partitions; i++)
- my_free((uchar*) keycache->partition_array[i], MYF(0));
- my_free((uchar*) keycache->partition_array, MYF(0));
+ my_free(keycache->partition_array[i]);
+ my_free(keycache->partition_array);
keycache->key_cache_inited= 0;
}
DBUG_VOID_RETURN;
@@ -5444,10 +5411,6 @@ uchar *partitioned_key_cache_read(PARTITIONED_KEY_CACHE_CB *keycache,
DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
(uint) file, (ulong) filepos, length));
-#ifndef THREAD
- if (block_length > keycache->key_cache_block_size || offset)
- return_buffer=0;
-#endif
/* Read data in key_cache_block_size increments */
do
@@ -5463,11 +5426,6 @@ uchar *partitioned_key_cache_read(PARTITIONED_KEY_CACHE_CB *keycache,
block_length, return_buffer);
if (ret_buff == 0)
DBUG_RETURN(0);
-#ifndef THREAD
- /* This is only true if we were able to read everything in one block */
- if (return_buffer)
- DBUG_RETURN(ret_buff);
-#endif
filepos+= r_length;
buff+= r_length;
offset= 0;
@@ -6152,7 +6110,7 @@ void end_key_cache_internal(KEY_CACHE *keycache, my_bool cleanup,
{
if (keycache->keycache_cb)
{
- my_free((uchar *) keycache->keycache_cb, MYF(0));
+ my_free(keycache->keycache_cb);
keycache->keycache_cb= 0;
}
/*
@@ -6426,7 +6384,8 @@ int flush_key_blocks(KEY_CACHE *keycache,
*/
int reset_key_cache_counters(const char *name __attribute__((unused)),
- KEY_CACHE *keycache)
+ KEY_CACHE *keycache,
+ void *unused __attribute__((unused)))
{
int rc= 0;
if (keycache->key_cache_inited)
diff --git a/mysys/mf_keycaches.c b/mysys/mf_keycaches.c
index 9ea5678da9a..7dbfc26a365 100644
--- a/mysys/mf_keycaches.c
+++ b/mysys/mf_keycaches.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2003-2007 MySQL AB
+/* Copyright (c) 2003, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2011, Monty Program 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
@@ -11,7 +12,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
Handling of multiple key caches
diff --git a/mysys/mf_loadpath.c b/mysys/mf_loadpath.c
index 9c67ed8ed06..7bad535585a 100644
--- a/mysys/mf_loadpath.c
+++ b/mysys/mf_loadpath.c
@@ -12,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include <m_string.h>
diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c
index 4521216cdc7..d684be238e6 100644
--- a/mysys/mf_pack.c
+++ b/mysys/mf_pack.c
@@ -20,13 +20,8 @@
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
-#ifdef VMS
-#include <rms.h>
-#include <iodef.h>
-#include <descrip.h>
-#endif /* VMS */
-static char * NEAR_F expand_tilde(char * *path);
+static char * expand_tilde(char **path);
/* Pack a dirname ; Changes HOME to ~/ and current dev to ./ */
/* from is a dirname (from dirname() ?) ending with FN_LIBCHAR */
@@ -199,7 +194,8 @@ size_t cleanup_dirname(register char *to, const char *from)
end_parentdir=pos;
while (pos >= start && *pos != FN_LIBCHAR) /* remove prev dir */
pos--;
- if (pos[1] == FN_HOMELIB || memcmp(pos,parent,length) == 0)
+ if (pos[1] == FN_HOMELIB ||
+ (pos >= start && memcmp(pos, parent, length) == 0))
{ /* Don't remove ~user/ */
pos=strmov(end_parentdir+1,parent);
*pos=FN_LIBCHAR;
@@ -302,8 +298,7 @@ size_t normalize_dirname(char *to, const char *from)
/*
Despite the name, this actually converts the name to the system's
- format (TODO: rip out the non-working VMS stuff and name this
- properly).
+ format (TODO: name this properly).
*/
(void) intern_filename(buff, from);
length= strlen(buff); /* Fix that '/' is last */
@@ -379,7 +374,7 @@ size_t unpack_dirname(char * to, const char *from)
/* Expand tilde to home or user-directory */
/* Path is reset to point at FN_LIBCHAR after ~xxx */
-static char * NEAR_F expand_tilde(char * *path)
+static char * expand_tilde(char **path)
{
if (path[0][0] == FN_LIBCHAR)
return home_dir; /* ~/ expanded to home */
@@ -445,73 +440,10 @@ size_t unpack_filename(char * to, const char *from)
/* Used before system command's like open(), create() .. */
/* Returns used length of to; total length should be FN_REFLEN */
-size_t system_filename(char * to, const char *from)
+size_t system_filename(char *to, const char *from)
{
-#ifndef FN_C_BEFORE_DIR
return (size_t) (strmake(to,from,FN_REFLEN-1)-to);
-#else /* VMS */
-
- /* change 'dev:lib/xxx' to 'dev:[lib]xxx' */
- /* change 'dev:xxx' to 'dev:xxx' */
- /* change './xxx' to 'xxx' */
- /* change './lib/' or lib/ to '[.lib]' */
- /* change '/x/y/z to '[x.y]x' */
- /* change 'dev:/x' to 'dev:[000000]x' */
-
- int libchar_found;
- size_t length;
- char * to_pos,from_pos,pos;
- char buff[FN_REFLEN + 1];
- DBUG_ENTER("system_filename");
-
- libchar_found=0;
- (void) strmov(buff,from); /* If to == from */
- from_pos= buff;
- if ((pos=strrchr(from_pos,FN_DEVCHAR))) /* Skip device part */
- {
- pos++;
- to_pos=strnmov(to,from_pos,(size_t) (pos-from_pos));
- from_pos=pos;
- }
- else
- to_pos=to;
-
- if (from_pos[0] == FN_CURLIB && from_pos[1] == FN_LIBCHAR)
- from_pos+=2; /* Skip './' */
- if (strchr(from_pos,FN_LIBCHAR))
- {
- *(to_pos++) = FN_C_BEFORE_DIR;
- if (strinstr(from_pos,FN_ROOTDIR) == 1)
- {
- from_pos+=strlen(FN_ROOTDIR); /* Actually +1 but... */
- if (! strchr(from_pos,FN_LIBCHAR))
- { /* No dir, use [000000] */
- to_pos=strmov(to_pos,FN_C_ROOT_DIR);
- libchar_found++;
- }
- }
- else
- *(to_pos++)=FN_C_DIR_SEP; /* '.' gives current dir */
-
- while ((pos=strchr(from_pos,FN_LIBCHAR)))
- {
- if (libchar_found++)
- *(to_pos++)=FN_C_DIR_SEP; /* Add '.' between dirs */
- if (strinstr(from_pos,FN_PARENTDIR) == 1 &&
- from_pos+strlen(FN_PARENTDIR) == pos)
- to_pos=strmov(to_pos,FN_C_PARENT_DIR); /* Found '../' */
- else
- to_pos=strnmov(to_pos,from_pos,(size_t) (pos-from_pos));
- from_pos=pos+1;
- }
- *(to_pos++)=FN_C_AFTER_DIR;
- }
- length= (size_t) (strmov(to_pos,from_pos)-to);
- DBUG_PRINT("exit",("name: '%s'",to));
- DBUG_RETURN(length);
-#endif
-} /* system_filename */
-
+}
/* Fix a filename to intern (UNIX format) */
diff --git a/mysys/mf_path.c b/mysys/mf_path.c
index 73e73cb7f76..725cf278f6f 100644
--- a/mysys/mf_path.c
+++ b/mysys/mf_path.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include <m_string.h>
@@ -42,7 +42,7 @@ char * my_path(char * to, const char *progname,
((prog=getenv("_")) != 0 &&
dirname_part(to, prog, &to_length))))
{
- VOID(intern_filename(to,to));
+ (void) intern_filename(to,to);
if (!test_if_hard_path(to))
{
if (!my_getwd(curr_dir,FN_REFLEN,MYF(0)))
@@ -60,11 +60,11 @@ char * my_path(char * to, const char *progname,
end= (char*) "/my/";
#endif
}
- VOID(intern_filename(to,end));
+ (void) intern_filename(to,end);
to=strend(to);
if (to != start && to[-1] != FN_LIBCHAR)
*to++ = FN_LIBCHAR;
- VOID(strmov(to,own_pathname_part));
+ (void) strmov(to,own_pathname_part);
}
DBUG_PRINT("exit",("to: '%s'",start));
DBUG_RETURN(start);
@@ -78,9 +78,6 @@ char * my_path(char * to, const char *progname,
#define F_OK 0
#define PATH_SEP ';'
#define PROGRAM_EXTENSION ".exe"
-#elif defined(__NETWARE__)
-#define PATH_SEP ';'
-#define PROGRAM_EXTENSION ".nlm"
#else
#define PATH_SEP ':'
#endif
diff --git a/mysys/mf_sort.c b/mysys/mf_sort.c
index 686ebbc1d14..9ef02787716 100644
--- a/mysys/mf_sort.c
+++ b/mysys/mf_sort.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* Sort of string pointers in string-order with radix or qsort */
@@ -27,7 +27,7 @@ void my_string_ptr_sort(uchar *base, uint items, size_t size)
(ptr= (uchar**) my_malloc(items*sizeof(char*),MYF(0))))
{
radixsort_for_str_ptr((uchar**) base,items,size,ptr);
- my_free((uchar*) ptr,MYF(0));
+ my_free(ptr);
}
else
#endif
diff --git a/mysys/mf_tempdir.c b/mysys/mf_tempdir.c
index 87282e350aa..eceb90bb619 100644
--- a/mysys/mf_tempdir.c
+++ b/mysys/mf_tempdir.c
@@ -1,6 +1,4 @@
-/*
- Copyright (c) 2000, 2002, 2004-2007 MySQL AB, 2008 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* Copyright (c) 2000, 2010, 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
@@ -13,13 +11,12 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include <m_string.h>
-#if defined( __WIN__) || defined(__NETWARE__)
+#if defined(__WIN__)
#define DELIM ';'
#else
#define DELIM ':'
@@ -32,14 +29,14 @@ my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist)
DBUG_ENTER("init_tmpdir");
DBUG_PRINT("enter", ("pathlist: %s", pathlist ? pathlist : "NULL"));
- pthread_mutex_init(&tmpdir->mutex, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_TMPDIR_mutex, &tmpdir->mutex, MY_MUTEX_INIT_FAST);
if (my_init_dynamic_array(&tmpdir->full_list, sizeof(char*), 1, 5))
goto err;
if (!pathlist || !pathlist[0])
{
/* Get default temporary directory */
pathlist=getenv("TMPDIR"); /* Use this if possible */
-#if defined( __WIN__) || defined(__NETWARE__)
+#if defined(__WIN__)
if (!pathlist)
pathlist=getenv("TEMP");
if (!pathlist)
@@ -68,7 +65,7 @@ my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist)
err:
delete_dynamic(&tmpdir->full_list); /* Safe to free */
- pthread_mutex_destroy(&tmpdir->mutex);
+ mysql_mutex_destroy(&tmpdir->mutex);
DBUG_RETURN(TRUE);
}
@@ -78,10 +75,10 @@ char *my_tmpdir(MY_TMPDIR *tmpdir)
char *dir;
if (!tmpdir->max)
return tmpdir->list[0];
- pthread_mutex_lock(&tmpdir->mutex);
+ mysql_mutex_lock(&tmpdir->mutex);
dir=tmpdir->list[tmpdir->cur];
tmpdir->cur= (tmpdir->cur == tmpdir->max) ? 0 : tmpdir->cur+1;
- pthread_mutex_unlock(&tmpdir->mutex);
+ mysql_mutex_unlock(&tmpdir->mutex);
return dir;
}
@@ -91,8 +88,8 @@ void free_tmpdir(MY_TMPDIR *tmpdir)
if (!tmpdir->full_list.elements)
return;
for (i=0; i<=tmpdir->max; i++)
- my_free(tmpdir->list[i], MYF(0));
+ my_free(tmpdir->list[i]);
delete_dynamic(&tmpdir->full_list);
- pthread_mutex_destroy(&tmpdir->mutex);
+ mysql_mutex_destroy(&tmpdir->mutex);
}
diff --git a/mysys/mf_tempfile.c b/mysys/mf_tempfile.c
index 40016210de4..15482075c39 100644
--- a/mysys/mf_tempfile.c
+++ b/mysys/mf_tempfile.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include <m_string.h>
@@ -100,16 +100,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
my_errno= tmp;
}
-#elif defined(_ZTC__)
- if (!dir)
- dir=getenv("TMPDIR");
- if ((res=tempnam((char*) dir,(char *) prefix)))
- {
- strmake(to,res,FN_REFLEN-1);
- (*free)(res);
- file=my_create(to, 0, mode | O_EXCL | O_NOFOLLOW, MyFlags);
- }
-#elif defined(HAVE_MKSTEMP) && !defined(__NETWARE__)
+#elif defined(HAVE_MKSTEMP)
{
char prefix_buff[30];
uint pfx_len;
@@ -143,9 +134,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
}
#elif defined(HAVE_TEMPNAM)
{
-#if !defined(__NETWARE__)
extern char **environ;
-#endif
char *res,**old_env,*temp_env[1];
if (dir && !dir[0])
@@ -154,14 +143,14 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
to[1]= 0;
dir=to;
}
-#if !defined(__NETWARE__)
+
old_env= (char**) environ;
if (dir)
{ /* Don't use TMPDIR if dir is given */
environ=(const char**) temp_env;
temp_env[0]=0;
}
-#endif
+
if ((res=tempnam((char*) dir, (char*) prefix)))
{
strmake(to,res,FN_REFLEN-1);
@@ -176,9 +165,8 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
{
DBUG_PRINT("error",("Got error: %d from tempnam",errno));
}
-#if !defined(__NETWARE__)
+
environ=(const char**) old_env;
-#endif
}
#else
#error No implementation found for create_temp_file
diff --git a/mysys/mf_unixpath.c b/mysys/mf_unixpath.c
index 75f8de14879..6777c27bc96 100644
--- a/mysys/mf_unixpath.c
+++ b/mysys/mf_unixpath.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,15 +11,20 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include <m_string.h>
- /* convert filename to unix style filename */
- /* If MSDOS converts '\' to '/' */
+/**
+ Convert filename to unix style filename.
-void to_unix_path(char * to __attribute__((unused)))
+ @remark On Windows, converts '\' to '/'.
+
+ @param to A pathname.
+*/
+
+void to_unix_path(char *to __attribute__((unused)))
{
#if FN_LIBCHAR != '/'
{
diff --git a/mysys/mf_util.c b/mysys/mf_util.c
deleted file mode 100644
index 248b72b8748..00000000000
--- a/mysys/mf_util.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright (C) 2000 MySQL 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Utilities with are missing on some systems */
-
-#include "mysys_priv.h"
-#ifdef __ZTC__
-#include <dos.h>
-#endif
-
-#ifdef __ZTC__
-
- /* On ZORTECH C we don't have a getpid() call */
-
-int getpid(void)
-{
- return (int) _psp;
-}
-
-#ifndef M_IC80386
-
- /* Define halloc and hfree in as in MSC */
-
-void * __CDECL halloc(long count,size_t length)
-{
- return (void*) MK_FP(dos_alloc((uint) ((count*length+15) >> 4)),0);
-}
-
-void __CDECL hfree(void *ptr)
-{
- dos_free(FP_SEG(ptr));
-}
-
-#endif /* M_IC80386 */
-#endif /* __ZTC__ */
diff --git a/mysys/mf_wfile.c b/mysys/mf_wfile.c
deleted file mode 100644
index 3de4e03cb84..00000000000
--- a/mysys/mf_wfile.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-/* Functions for finding files with wildcards */
-
-/*
- The following file-name-test is supported:
- - "name [[,] name...] ; Matches any of used filenames.
- Each name can have "*" and/or "?"
- wild-cards.
- - [wildspec [,]] !wildspec2 ; File that matches wildspec and not
- wildspec2.
-*/
-
-#include "mysys_priv.h"
-#include <m_string.h>
-
- /* Store wildcard-string in a easyer format */
-
-WF_PACK *wf_comp(char * str)
-{
- uint ant;
- int not_pos;
- register char * pos;
- char * buffer;
- WF_PACK *ret;
- DBUG_ENTER("wf_comp");
-
- not_pos= -1; /* Skip space and '!' in front */
- while (*str == ' ')
- str++;
- if (*str == '!')
- {
- not_pos=0;
- while (*++str == ' ') {};
- }
- if (*str == 0) /* Empty == everything */
- DBUG_RETURN((WF_PACK *) NULL);
-
- ant=1; /* Count filespecs */
- for (pos=str ; *pos ; pos++)
- ant+= test(*pos == ' ' || *pos == ',');
-
- if ((ret= (WF_PACK*) my_malloc((uint) ant*(sizeof(char **)+2)+
- sizeof(WF_PACK)+ (uint) strlen(str)+1,
- MYF(MY_WME)))
- == 0)
- DBUG_RETURN((WF_PACK *) NULL);
- ret->wild= (char **) (ret+1);
- buffer= (char *) (ret->wild+ant);
-
- ant=0;
- for (pos=str ; *pos ; str= pos)
- {
- ret->wild[ant++]=buffer;
- while (*pos != ' ' && *pos != ',' && *pos != '!' && *pos)
- *buffer++ = *pos++;
-
- *buffer++ = '\0';
- while (*pos == ' ' || *pos == ',' || *pos == '!' )
- if (*pos++ == '!' && not_pos <0)
- not_pos=(int) ant;
- }
-
- ret->wilds=ant;
- if (not_pos <0)
- ret->not_pos=ant;
- else
- ret->not_pos=(uint) not_pos;
-
- DBUG_PRINT("exit",("antal: %d not_pos: %d",ret->wilds,ret->not_pos));
- DBUG_RETURN(ret);
-} /* wf_comp */
-
-
- /* Test if a given filename is matched */
-
-int wf_test(register WF_PACK *wf_pack, register const char *name)
-{
- reg2 uint i;
- reg3 uint not_pos;
- DBUG_ENTER("wf_test");
-
- if (! wf_pack || wf_pack->wilds == 0)
- DBUG_RETURN(0); /* Everything goes */
-
- not_pos=wf_pack->not_pos;
- for (i=0 ; i < not_pos; i++)
- if (wild_compare(name,wf_pack->wild[i],0) == 0)
- goto found;
- if (i)
- DBUG_RETURN(1); /* No-match */
-
-found:
-/* Test that it isn't in not-list */
-
- for (i=not_pos ; i < wf_pack->wilds; i++)
- if (wild_compare(name,wf_pack->wild[i],0) == 0)
- DBUG_RETURN(1);
- DBUG_RETURN(0);
-} /* wf_test */
-
-
- /* We need this because program don't know with malloc we used */
-
-void wf_end(WF_PACK *buffer)
-{
- DBUG_ENTER("wf_end");
- if (buffer)
- my_free(buffer, MYF(0));
- DBUG_VOID_RETURN;
-} /* wf_end */
diff --git a/mysys/my_access.c b/mysys/my_access.c
index 43917da7f98..453d3e29cdf 100644
--- a/mysys/my_access.c
+++ b/mysys/my_access.c
@@ -1,4 +1,5 @@
/* Copyright (C) 2000 MySQL AB
+ Copyright (c) 2012, Monty Program 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
@@ -26,11 +27,6 @@
path Path to file
amode Access method
- DESCRIPTION
- This function wraps the normal access method because the access
- available in MSVCRT> +reports that filenames such as LPT1 and
- COM1 are valid (they are but should not be so for us).
-
RETURN VALUES
0 ok
-1 error (We use -1 as my_access is mapped to access on other platforms)
@@ -38,12 +34,11 @@
int my_access(const char *path, int amode)
{
- WIN32_FILE_ATTRIBUTE_DATA fileinfo;
- BOOL result;
-
- result= GetFileAttributesEx(path, GetFileExInfoStandard, &fileinfo);
- if (! result ||
- (fileinfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) && (amode & W_OK))
+ DWORD attributes;
+
+ attributes = GetFileAttributes(path);
+ if (attributes == INVALID_FILE_ATTRIBUTES ||
+ (attributes & FILE_ATTRIBUTE_READONLY) && (amode & W_OK))
{
my_errno= errno= EACCES;
return -1;
@@ -148,8 +143,7 @@ static char reserved_map[256]=
int check_if_legal_tablename(const char *name)
{
DBUG_ENTER("check_if_legal_tablename");
- DBUG_RETURN(name[0] != 0 && name[1] != 0 &&
- (reserved_map[(uchar) name[0]] & 1) &&
+ DBUG_RETURN((reserved_map[(uchar) name[0]] & 1) &&
(reserved_map[(uchar) name[1]] & 2) &&
(reserved_map[(uchar) name[2]] & 4) &&
str_list_find(&reserved_names[1], name));
diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c
new file mode 100644
index 00000000000..e5a3a5fe13b
--- /dev/null
+++ b/mysys/my_addr_resolve.c
@@ -0,0 +1,198 @@
+/* Copyright (C) 2011 Monty Program 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-1301 USA */
+
+#include "mysys_priv.h"
+#include <m_string.h>
+#include <my_sys.h>
+#include <my_stacktrace.h>
+
+/**
+ strip the path, leave the file name and the last dirname
+*/
+static const char *strip_path(const char *s) __attribute__((unused));
+static const char *strip_path(const char *s)
+{
+ const char *prev, *last;
+ for(prev= last= s; *s; s++)
+ if (*s == '/' || *s == '\\')
+ {
+ prev= last;
+ last= s + 1;
+ }
+ return prev;
+}
+
+/*
+ The following is very much single-threaded code and it's only supposed
+ to be used on shutdown or for a crash report
+ Or the caller should take care and use mutexes.
+
+ Also it does not free any its memory. For the same reason -
+ it's only used for crash reports or on shutdown when we already
+ have a memory leak.
+*/
+
+#ifdef HAVE_BFD_H
+#include <bfd.h>
+static bfd *bfdh= 0;
+static asymbol **symtable= 0;
+
+/**
+ finds a file name, a line number, and a function name corresponding to addr.
+
+ the function name is demangled.
+ the file name is stripped of its path, only the two last components are kept
+ the resolving logic is mostly based on addr2line of binutils-2.17
+
+ @return 0 on success, 1 on failure
+*/
+int my_addr_resolve(void *ptr, my_addr_loc *loc)
+{
+ bfd_vma addr= (intptr)ptr;
+ asection *sec;
+
+ for (sec= bfdh->sections; sec; sec= sec->next)
+ {
+ bfd_vma start;
+
+ if ((bfd_get_section_flags(bfdh, sec) & SEC_ALLOC) == 0)
+ continue;
+
+ start = bfd_get_section_vma(bfdh, sec);
+ if (addr < start || addr >= start + bfd_get_section_size(sec))
+ continue;
+
+ if (bfd_find_nearest_line(bfdh, sec, symtable, addr - start,
+ &loc->file, &loc->func, &loc->line))
+ {
+ if (loc->file)
+ loc->file= strip_path(loc->file);
+ else
+ loc->file= "";
+
+ if (loc->func)
+ {
+ const char *str= bfd_demangle(bfdh, loc->func, 3);
+ if (str)
+ loc->func= str;
+ }
+
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+const char *my_addr_resolve_init()
+{
+ if (!bfdh)
+ {
+ uint unused;
+ char **matching;
+
+ bfdh= bfd_openr(my_progname, NULL);
+ if (!bfdh)
+ goto err;
+
+ if (bfd_check_format(bfdh, bfd_archive))
+ goto err;
+ if (!bfd_check_format_matches (bfdh, bfd_object, &matching))
+ goto err;
+
+ if (bfd_read_minisymbols(bfdh, FALSE, (void *)&symtable, &unused) < 0)
+ goto err;
+ }
+ return 0;
+
+err:
+ return bfd_errmsg(bfd_get_error());
+}
+#elif defined(HAVE_LIBELF_H)
+/*
+ another possible implementation.
+*/
+#elif defined(MY_ADDR_RESOLVE_FORK)
+/*
+ yet another - just execute addr2line or eu-addr2line, whatever available,
+ pipe the addresses to it, and parse the output
+*/
+
+#include <m_string.h>
+#include <ctype.h>
+static int in[2], out[2];
+static int initialized= 0;
+static char output[1024];
+int my_addr_resolve(void *ptr, my_addr_loc *loc)
+{
+ char input[32], *s;
+ size_t len;
+
+ len= my_snprintf(input, sizeof(input), "%p\n", ptr);
+ if (write(in[1], input, len) <= 0)
+ return 1;
+ if (read(out[0], output, sizeof(output)) <= 0)
+ return 1;
+ loc->func= s= output;
+ while (*s != '\n')
+ s++;
+ *s++= 0;
+ loc->file= s;
+ while (*s != ':')
+ s++;
+ *s++= 0;
+ loc->line= 0;
+ while (isdigit(*s))
+ loc->line = loc->line * 10 + (*s++ - '0');
+ *s = 0;
+ loc->file= strip_path(loc->file);
+
+ return 0;
+}
+
+const char *my_addr_resolve_init()
+{
+ if (!initialized)
+ {
+ pid_t pid;
+
+ if (pipe(in) < 0)
+ return "pipe(in)";
+ if (pipe(out) < 0)
+ return "pipe(out)";
+
+ pid = fork();
+ if (pid == -1)
+ return "fork";
+
+ if (!pid) /* child */
+ {
+ dup2(in[0], 0);
+ dup2(out[1], 1);
+ close(in[0]);
+ close(in[1]);
+ close(out[0]);
+ close(out[1]);
+ execlp("addr2line", "addr2line", "-C", "-f", "-e", my_progname, NULL);
+ exit(1);
+ }
+
+ close(in[0]);
+ close(out[1]);
+ initialized= 1;
+ }
+ return 0;
+}
+#endif
diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c
index ca88dd5a38f..1054db6cee4 100644
--- a/mysys/my_alloc.c
+++ b/mysys/my_alloc.c
@@ -12,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* Routines to handle mallocing of results which will be freed the same time */
@@ -121,7 +120,7 @@ void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size,
{
/* remove block from the list and free it */
*prev= mem->next;
- my_free(mem, MYF(0));
+ my_free(mem);
}
else
prev= &mem->next;
@@ -164,7 +163,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
});
length+=ALIGN_SIZE(sizeof(USED_MEM));
- if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME))))
+ if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME | ME_FATALERROR))))
{
if (mem_root->error_handler)
(*mem_root->error_handler)();
@@ -215,7 +214,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
get_size= max(get_size, block_size);
- if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
+ if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME | ME_FATALERROR))))
{
if (mem_root->error_handler)
(*mem_root->error_handler)();
@@ -237,6 +236,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
mem_root->used= next;
mem_root->first_block_usage= 0;
}
+ TRASH_ALLOC(point, length);
DBUG_PRINT("exit",("ptr: 0x%lx", (ulong) point));
DBUG_RETURN((void*) point);
#endif
@@ -363,13 +363,13 @@ void free_root(MEM_ROOT *root, myf MyFlags)
{
old=next; next= next->next ;
if (old != root->pre_alloc)
- my_free(old,MYF(0));
+ my_free(old);
}
for (next=root->free ; next ;)
{
old=next; next= next->next;
if (old != root->pre_alloc)
- my_free(old,MYF(0));
+ my_free(old);
}
root->used=root->free=0;
if (root->pre_alloc)
diff --git a/mysys/my_append.c b/mysys/my_append.c
deleted file mode 100644
index d8789f95d95..00000000000
--- a/mysys/my_append.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Copyright (C) 2000 MySQL 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "mysys_priv.h"
-#include <sys/stat.h>
-#include <m_string.h>
-#if defined(HAVE_UTIME_H)
-#include <utime.h>
-#elif defined(HAVE_SYS_UTIME_H)
-#include <sys/utime.h>
-#elif !defined(HPUX10)
-struct utimbuf {
- time_t actime;
- time_t modtime;
-};
-#endif
-
-/*
- Append a file to another
-
- NOTES
- Don't set MY_FNABP or MY_NABP bits on when calling this function
-*/
-
-int my_append(const char *from, const char *to, myf MyFlags)
-{
- size_t Count;
- File from_file,to_file;
- uchar buff[IO_SIZE];
- DBUG_ENTER("my_append");
- DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));
-
- from_file= to_file= -1;
-
- if ((from_file=my_open(from,O_RDONLY,MyFlags)) >= 0)
- {
- if ((to_file=my_open(to,O_APPEND | O_WRONLY,MyFlags)) >= 0)
- {
- while ((Count=my_read(from_file,buff,IO_SIZE,MyFlags)) != 0)
- if (Count == (uint) -1 ||
- my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP)))
- goto err;
- if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags))
- DBUG_RETURN(-1); /* Error on close */
- DBUG_RETURN(0);
- }
- }
-err:
- if (from_file >= 0) VOID(my_close(from_file,MyFlags));
- if (to_file >= 0) VOID(my_close(to_file,MyFlags));
- DBUG_RETURN(-1);
-}
diff --git a/mysys/my_atomic.c b/mysys/my_atomic.c
index aa04d55f624..26348b518ae 100644
--- a/mysys/my_atomic.c
+++ b/mysys/my_atomic.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 MySQL AB
+/* Copyright (c) 2006, 2010, 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
@@ -11,17 +11,10 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <my_global.h>
-#include <my_pthread.h>
-
-#ifndef HAVE_INLINE
-/* the following will cause all inline functions to be instantiated */
-#define HAVE_INLINE
-#undef STATIC_INLINE
-#define STATIC_INLINE extern
-#endif
+#include <my_sys.h>
#include <my_atomic.h>
@@ -43,3 +36,32 @@ int my_atomic_initialize()
#endif
}
+#ifdef SAFE_MUTEX
+#undef pthread_mutex_init
+#undef pthread_mutex_destroy
+#undef pthread_mutex_lock
+#undef pthread_mutex_unlock
+
+void plain_pthread_mutex_init(safe_mutex_t *m)
+{
+ pthread_mutex_init(& m->mutex, NULL);
+}
+
+void plain_pthread_mutex_destroy(safe_mutex_t *m)
+{
+ pthread_mutex_destroy(& m->mutex);
+}
+
+void plain_pthread_mutex_lock(safe_mutex_t *m)
+{
+ pthread_mutex_lock(& m->mutex);
+}
+
+void plain_pthread_mutex_unlock(safe_mutex_t *m)
+{
+ pthread_mutex_unlock(& m->mutex);
+}
+
+#endif
+
+
diff --git a/mysys/my_basename.c b/mysys/my_basename.c
new file mode 100644
index 00000000000..9d1eaf53efa
--- /dev/null
+++ b/mysys/my_basename.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 2011 Monty Program 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-1301 USA */
+
+#include <my_sys.h>
+/**
+ @brief retrieve last component of the filename.
+ Loosely based on Single Unix Spec definition.
+
+ @fn my_basename()
+ @param filename Filename
+*/
+const char *my_basename(const char *filename)
+{
+ const char *last;
+ const char *s=filename;
+
+ /* Handle basename()'s special cases, as per single unix spec */
+ if (!filename || !filename[0])
+ return ".";
+ if(filename[0] == '/' && filename[1]== '\0')
+ return filename;
+
+ for(last= s; *s; s++)
+ {
+ if (*s == '/' || *s == '\\')
+ last= s + 1;
+ }
+ return last;
+}
diff --git a/mysys/my_bit.c b/mysys/my_bit.c
index 2881eb1ebd2..d36f52bb3c0 100644
--- a/mysys/my_bit.c
+++ b/mysys/my_bit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,17 +11,10 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <my_global.h>
-#ifndef HAVE_INLINE
-/* the following will cause all inline functions to be instantiated */
-#define HAVE_INLINE
-#undef STATIC_INLINE
-#define STATIC_INLINE extern
-#endif
-
#include <my_bit.h>
const char _my_bits_nbits[256] = {
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index fe5faff47bc..83d03177eba 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -13,8 +13,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Handling of uchar arrays as large bitmaps.
@@ -24,17 +23,13 @@
* the internal size is a set of 32 bit words
* the number of bits specified in creation can be any number > 0
- * there are THREAD safe versions of most calls called bitmap_lock_*
- many of those are not used and not compiled normally but the code
- already exist for them in an #ifdef:ed part. These can only be used
- if THREAD was specified in bitmap_init
TODO:
- Make assembler THREAD safe versions of these using test-and-set instructions
+ Make assembler thread safe versions of these using test-and-set instructions
Original version created by Sergei Golubchik 2001 - 2004.
New version written and test program added and some changes to the interface
- was made by Mikael Ronström 2005, with assistance of Tomas Ulin and Mats
+ was made by Mikael Ronstrom 2005, with assistance of Tomas Ulin and Mats
Kindahl.
*/
@@ -141,19 +136,14 @@ static inline my_bitmap_map last_word_mask(uint bit)
static inline void bitmap_lock(MY_BITMAP *map __attribute__((unused)))
{
-#ifdef THREAD
if (map->mutex)
- pthread_mutex_lock(map->mutex);
-#endif
+ mysql_mutex_lock(map->mutex);
}
-
static inline void bitmap_unlock(MY_BITMAP *map __attribute__((unused)))
{
-#ifdef THREAD
if (map->mutex)
- pthread_mutex_unlock(map->mutex);
-#endif
+ mysql_mutex_unlock(map->mutex);
}
@@ -165,30 +155,24 @@ my_bool bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits,
{
uint size_in_bytes= bitmap_buffer_size(n_bits);
uint extra= 0;
-#ifdef THREAD
if (thread_safe)
{
size_in_bytes= ALIGN_SIZE(size_in_bytes);
- extra= sizeof(pthread_mutex_t);
+ extra= sizeof(mysql_mutex_t);
}
map->mutex= 0;
-#endif
if (!(buf= (my_bitmap_map*) my_malloc(size_in_bytes+extra, MYF(MY_WME))))
DBUG_RETURN(1);
-#ifdef THREAD
if (thread_safe)
{
- map->mutex= (pthread_mutex_t *) ((char*) buf + size_in_bytes);
- pthread_mutex_init(map->mutex, MY_MUTEX_INIT_FAST);
+ map->mutex= (mysql_mutex_t *) ((char*) buf + size_in_bytes);
+ mysql_mutex_init(key_BITMAP_mutex, map->mutex, MY_MUTEX_INIT_FAST);
}
-#endif
}
-#ifdef THREAD
else
{
DBUG_ASSERT(thread_safe == 0);
}
-#endif
map->bitmap= buf;
map->n_bits= n_bits;
@@ -203,11 +187,9 @@ void bitmap_free(MY_BITMAP *map)
DBUG_ENTER("bitmap_free");
if (map->bitmap)
{
-#ifdef THREAD
if (map->mutex)
- pthread_mutex_destroy(map->mutex);
-#endif
- my_free((char*) map->bitmap, MYF(0));
+ mysql_mutex_destroy(map->mutex);
+ my_free(map->bitmap);
map->bitmap=0;
}
DBUG_VOID_RETURN;
@@ -327,43 +309,31 @@ void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size)
my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size)
{
- uint prefix_bits= prefix_size % 32;
- my_bitmap_map *word_ptr= map->bitmap, last_word;
- my_bitmap_map *end_prefix= word_ptr + prefix_size / 32;
- DBUG_ASSERT(word_ptr && prefix_size <= map->n_bits);
+ uint prefix_mask= last_byte_mask(prefix_size);
+ uchar *m= (uchar*) map->bitmap;
+ uchar *end_prefix= m+(prefix_size-1)/8;
+ uchar *end;
+ DBUG_ASSERT(m && prefix_size <= map->n_bits);
- /* 1: Words that should be filled with 1 */
- for (; word_ptr < end_prefix; word_ptr++)
- if (*word_ptr != 0xFFFFFFFF)
- return FALSE;
+ /* Empty prefix is always true */
+ if (!prefix_size)
+ return 1;
- last_word= *map->last_word_ptr & ~map->last_word_mask;
+ while (m < end_prefix)
+ if (*m++ != 0xff)
+ return 0;
- /* 2: Word which contains the end of the prefix (if any) */
- if (prefix_bits)
- {
- if (word_ptr == map->last_word_ptr)
- return uint4korr((uchar*)&last_word) == (uint32)((1 << prefix_bits) - 1);
- if (uint4korr((uchar*)word_ptr) != (uint32)((1 << prefix_bits) - 1))
- return FALSE;
- word_ptr++;
- }
+ end= ((uchar*) map->bitmap) + no_bytes_in_map(map) - 1;
+ if (m == end)
+ return ((*m & last_byte_mask(map->n_bits)) == prefix_mask);
- /* 3: Words that should be filled with 0 */
- for (; word_ptr < map->last_word_ptr; word_ptr++)
- if (*word_ptr != 0)
- return FALSE;
+ if (*m != prefix_mask)
+ return 0;
- /*
- We can end up here in two situations:
- 1) We went through the whole bitmap in step 1. This will happen if the
- whole bitmap is filled with 1 and prefix_size is a multiple of 32
- (i.e. the prefix does not end in the middle of a word).
- In this case word_ptr will be larger than map->last_word_ptr.
- 2) We have gone through steps 1-3 and just need to check that also
- the last word is 0.
- */
- return word_ptr > map->last_word_ptr || last_word == 0;
+ while (++m < end)
+ if (*m != 0)
+ return 0;
+ return ((*m & last_byte_mask(map->n_bits)) == 0);
}
@@ -371,7 +341,6 @@ my_bool bitmap_is_set_all(const MY_BITMAP *map)
{
my_bitmap_map *data_ptr= map->bitmap;
my_bitmap_map *end= map->last_word_ptr;
-
for (; data_ptr < end; data_ptr++)
if (*data_ptr != 0xFFFFFFFF)
return FALSE;
@@ -613,10 +582,10 @@ uint bitmap_bits_set(const MY_BITMAP *map)
return res;
}
-
void bitmap_copy(MY_BITMAP *map, const MY_BITMAP *map2)
{
my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end;
+
DBUG_ASSERT(map->bitmap && map2->bitmap &&
map->n_bits==map2->n_bits);
end= map->last_word_ptr;
@@ -715,189 +684,3 @@ void bitmap_lock_clear_bit(MY_BITMAP *map, uint bitmap_bit)
bitmap_unlock(map);
}
-
-#ifdef NOT_USED
-my_bool bitmap_lock_is_prefix(const MY_BITMAP *map, uint prefix_size)
-{
- my_bool res;
- bitmap_lock((MY_BITMAP *)map);
- res= bitmap_is_prefix(map, prefix_size);
- bitmap_unlock((MY_BITMAP *)map);
- return res;
-}
-
-
-void bitmap_lock_set_all(MY_BITMAP *map)
-{
- bitmap_lock(map);
- bitmap_set_all(map);
- bitmap_unlock(map);
-}
-
-
-void bitmap_lock_clear_all(MY_BITMAP *map)
-{
- bitmap_lock(map);
- bitmap_clear_all(map);
- bitmap_unlock(map);
-}
-
-
-void bitmap_lock_set_prefix(MY_BITMAP *map, uint prefix_size)
-{
- bitmap_lock(map);
- bitmap_set_prefix(map, prefix_size);
- bitmap_unlock(map);
-}
-
-
-my_bool bitmap_lock_is_clear_all(const MY_BITMAP *map)
-{
- uint res;
- bitmap_lock((MY_BITMAP *)map);
- res= bitmap_is_clear_all(map);
- bitmap_unlock((MY_BITMAP *)map);
- return res;
-}
-
-
-my_bool bitmap_lock_is_set_all(const MY_BITMAP *map)
-{
- uint res;
- bitmap_lock((MY_BITMAP *)map);
- res= bitmap_is_set_all(map);
- bitmap_unlock((MY_BITMAP *)map);
- return res;
-}
-
-
-my_bool bitmap_lock_is_set(const MY_BITMAP *map, uint bitmap_bit)
-{
- my_bool res;
- DBUG_ASSERT(map->bitmap && bitmap_bit < map->n_bits);
- bitmap_lock((MY_BITMAP *)map);
- res= bitmap_is_set(map, bitmap_bit);
- bitmap_unlock((MY_BITMAP *)map);
- return res;
-}
-
-
-my_bool bitmap_lock_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2)
-{
- uint res;
- bitmap_lock((MY_BITMAP *)map1);
- bitmap_lock((MY_BITMAP *)map2);
- res= bitmap_is_subset(map1, map2);
- bitmap_unlock((MY_BITMAP *)map2);
- bitmap_unlock((MY_BITMAP *)map1);
- return res;
-}
-
-
-my_bool bitmap_lock_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2)
-{
- uint res;
-
- DBUG_ASSERT(map1->bitmap && map2->bitmap &&
- map1->n_bits==map2->n_bits);
- bitmap_lock((MY_BITMAP *)map1);
- bitmap_lock((MY_BITMAP *)map2);
- res= bitmap_cmp(map1, map2);
- bitmap_unlock((MY_BITMAP *)map2);
- bitmap_unlock((MY_BITMAP *)map1);
- return res;
-}
-
-
-void bitmap_lock_intersect(MY_BITMAP *map, const MY_BITMAP *map2)
-{
- bitmap_lock(map);
- bitmap_lock((MY_BITMAP *)map2);
- bitmap_intersect(map, map2);
- bitmap_unlock((MY_BITMAP *)map2);
- bitmap_unlock(map);
-}
-
-
-void bitmap_lock_subtract(MY_BITMAP *map, const MY_BITMAP *map2)
-{
- bitmap_lock(map);
- bitmap_lock((MY_BITMAP *)map2);
- bitmap_subtract(map, map2);
- bitmap_unlock((MY_BITMAP *)map2);
- bitmap_unlock(map);
-}
-
-
-void bitmap_lock_union(MY_BITMAP *map, const MY_BITMAP *map2)
-{
- bitmap_lock(map);
- bitmap_lock((MY_BITMAP *)map2);
- bitmap_union(map, map2);
- bitmap_unlock((MY_BITMAP *)map2);
- bitmap_unlock(map);
-}
-
-
-/*
- SYNOPSIS
- bitmap_bits_set()
- map
- RETURN
- Number of set bits in the bitmap.
-*/
-uint bitmap_lock_bits_set(const MY_BITMAP *map)
-{
- uint res;
- bitmap_lock((MY_BITMAP *)map);
- DBUG_ASSERT(map->bitmap);
- res= bitmap_bits_set(map);
- bitmap_unlock((MY_BITMAP *)map);
- return res;
-}
-
-
-/*
- SYNOPSIS
- bitmap_get_first()
- map
- RETURN
- Number of first unset bit in the bitmap or MY_BIT_NONE if all bits are set.
-*/
-uint bitmap_lock_get_first(const MY_BITMAP *map)
-{
- uint res;
- bitmap_lock((MY_BITMAP*)map);
- res= bitmap_get_first(map);
- bitmap_unlock((MY_BITMAP*)map);
- return res;
-}
-
-
-uint bitmap_lock_get_first_set(const MY_BITMAP *map)
-{
- uint res;
- bitmap_lock((MY_BITMAP*)map);
- res= bitmap_get_first_set(map);
- bitmap_unlock((MY_BITMAP*)map);
- return res;
-}
-
-
-void bitmap_lock_set_bit(MY_BITMAP *map, uint bitmap_bit)
-{
- DBUG_ASSERT(map->bitmap && bitmap_bit < map->n_bits);
- bitmap_lock(map);
- bitmap_set_bit(map, bitmap_bit);
- bitmap_unlock(map);
-}
-
-
-void bitmap_lock_flip_bit(MY_BITMAP *map, uint bitmap_bit)
-{
- DBUG_ASSERT(map->bitmap && bitmap_bit < map->n_bits);
- bitmap_lock(map);
- bitmap_flip_bit(map, bitmap_bit);
- bitmap_unlock(map);
-}
-#endif /* NOT_USED */
diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c
index b9013811b34..63964916d6f 100644
--- a/mysys/my_chsize.c
+++ b/mysys/my_chsize.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000-2007 MySQL AB, 2009 Sun Microsystems, Inc.
+ 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
@@ -11,7 +12,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -66,13 +67,6 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
goto err;
}
DBUG_RETURN(0);
-#elif defined(HAVE_CHSIZE)
- if (chsize(fd, (off_t) newlength))
- {
- my_errno=errno;
- goto err;
- }
- DBUG_RETURN(0);
#else
/*
Fill space between requested length and true length with 'filler'
diff --git a/mysys/my_clock.c b/mysys/my_clock.c
deleted file mode 100644
index adc755028d5..00000000000
--- a/mysys/my_clock.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Copyright (C) 2000 MySQL 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "my_global.h"
-
-#if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(__NETWARE__)
-#include "mysys_priv.h"
-#include <sys/times.h>
-#endif
-
-long my_clock(void)
-{
-#if !defined(__WIN__) && !defined(__NETWARE__)
- struct tms tmsbuf;
- VOID(times(&tmsbuf));
- return (tmsbuf.tms_utime + tmsbuf.tms_stime);
-#else
- return clock();
-#endif
-}
diff --git a/mysys/my_compare.c b/mysys/my_compare.c
index 3a60faae727..9e192e52fb7 100644
--- a/mysys/my_compare.c
+++ b/mysys/my_compare.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Oracle and/or its affiliates
+/* Copyright (c) 2011, Oracle and/or its affiliates.
Copyright (C) 2009-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
@@ -13,10 +13,12 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "mysys_priv.h"
+
+#include <my_global.h>
+#include <m_ctype.h>
#include <my_base.h>
-#include "my_compare.h"
+#include <my_compare.h>
+#include <my_sys.h>
int ha_compare_text(CHARSET_INFO *charset_info, const uchar *a, uint a_length,
const uchar *b, uint b_length, my_bool part_key,
@@ -24,8 +26,7 @@ int ha_compare_text(CHARSET_INFO *charset_info, const uchar *a, uint a_length,
{
if (!part_key)
return charset_info->coll->strnncollsp(charset_info, a, a_length,
- b, b_length,
- (my_bool)!skip_end_space);
+ b, b_length, (my_bool)!skip_end_space);
return charset_info->coll->strnncoll(charset_info, a, a_length,
b, b_length, part_key);
}
@@ -117,8 +118,8 @@ static int compare_bin(const uchar *a, uint a_length,
#define FCMP(A,B) ((int) (A) - (int) (B))
-int ha_key_cmp(register HA_KEYSEG *keyseg, register const uchar *a,
- register const uchar *b, uint key_length, uint32 nextflag,
+int ha_key_cmp(HA_KEYSEG *keyseg, const uchar *a,
+ const uchar *b, uint key_length, uint32 nextflag,
uint *diff_pos)
{
int flag;
@@ -551,7 +552,6 @@ found:
return 0;
} /* ha_key_cmp */
-
/*
Find the first NULL value in index-suffix values tuple
@@ -641,34 +641,3 @@ HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, const uchar *a)
return keyseg;
}
-
-/*
- Register handler error messages for usage with my_error()
-
- NOTES
- This is safe to call multiple times as my_error_register()
- will ignore calls to register already registered error numbers.
-*/
-
-#include "my_handler_errors.h"
-
-void my_handler_error_register(void)
-{
- /*
- If you got compilation error here about compile_time_assert array, check
- that every HA_ERR_xxx constant has a corresponding error message in
- handler_error_messages[] list (check mysys/my_handler_errors.h and
- include/my_base.h).
- */
- compile_time_assert(HA_ERR_FIRST + array_elements(handler_error_messages) ==
- HA_ERR_LAST + 1);
- my_error_register(handler_error_messages, HA_ERR_FIRST,
- HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
-}
-
-
-void my_handler_error_unregister(void)
-{
- my_error_unregister(HA_ERR_FIRST,
- HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
-}
diff --git a/mysys/my_compress.c b/mysys/my_compress.c
index ade2742c4fc..ea56900db05 100644
--- a/mysys/my_compress.c
+++ b/mysys/my_compress.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* Written by Sinisa Milivojevic <sinisa@mysql.com> */
@@ -51,7 +51,7 @@ my_bool my_compress(uchar *packet, size_t *len, size_t *complen)
if (!compbuf)
DBUG_RETURN(*complen ? 0 : 1);
memcpy(packet,compbuf,*len);
- my_free(compbuf,MYF(MY_WME));
+ my_free(compbuf);
}
DBUG_RETURN(0);
}
@@ -89,7 +89,7 @@ void *my_az_allocator(void *dummy __attribute__((unused)), unsigned int items,
void my_az_free(void *dummy __attribute__((unused)), void *address)
{
- my_free(address, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(address);
}
/*
@@ -140,14 +140,14 @@ uchar *my_compress_alloc(const uchar *packet, size_t *len, size_t *complen)
if (res != Z_OK)
{
- my_free(compbuf, MYF(MY_WME));
+ my_free(compbuf);
return 0;
}
if (*complen >= *len)
{
*complen= 0;
- my_free(compbuf, MYF(MY_WME));
+ my_free(compbuf);
DBUG_PRINT("note",("Packet got longer on compression; Not compressed"));
return 0;
}
@@ -192,11 +192,11 @@ my_bool my_uncompress(uchar *packet, size_t len, size_t *complen)
if (error != Z_OK)
{ /* Probably wrong packet */
DBUG_PRINT("error",("Can't uncompress packet, error: %d",error));
- my_free(compbuf, MYF(MY_WME));
+ my_free(compbuf);
DBUG_RETURN(1);
}
memcpy(packet, compbuf, *complen);
- my_free(compbuf, MYF(MY_WME));
+ my_free(compbuf);
}
else
*complen= len;
@@ -317,7 +317,7 @@ int unpackfrm(uchar **unpack_data, size_t *unpack_len,
if (my_uncompress(data, complen, &orglen))
{
- my_free(data, MYF(0));
+ my_free(data);
DBUG_RETURN(3);
}
diff --git a/mysys/my_context.c b/mysys/my_context.c
new file mode 100644
index 00000000000..08dc0920f21
--- /dev/null
+++ b/mysys/my_context.c
@@ -0,0 +1,728 @@
+/*
+ Copyright 2011 Kristian Nielsen and Monty Program Ab
+
+ This file is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ Implementation of async context spawning using Posix ucontext and
+ swapcontext().
+*/
+
+#include "mysys_priv.h"
+#include "m_string.h"
+#include "my_context.h"
+
+#ifdef HAVE_VALGRIND
+#include <valgrind/valgrind.h>
+#endif
+
+#ifdef MY_CONTEXT_USE_UCONTEXT
+/*
+ The makecontext() only allows to pass integers into the created context :-(
+ We want to pass pointers, so we do it this kinda hackish way.
+ Anyway, it should work everywhere, and at least it does not break strict
+ aliasing.
+*/
+union pass_void_ptr_as_2_int {
+ int a[2];
+ void *p;
+};
+
+
+/*
+ We use old-style function definition here, as this is passed to
+ makecontext(). And the type of the makecontext() argument does not match
+ the actual type (as the actual type can differ from call to call).
+*/
+static void
+my_context_spawn_internal(i0, i1)
+int i0, i1;
+{
+ int err;
+ struct my_context *c;
+ union pass_void_ptr_as_2_int u;
+
+ u.a[0]= i0;
+ u.a[1]= i1;
+ c= (struct my_context *)u.p;
+
+ (*c->user_func)(c->user_data);
+ c->active= 0;
+ err= setcontext(&c->base_context);
+ fprintf(stderr, "Aieie, setcontext() failed: %d (errno=%d)\n", err, errno);
+}
+
+
+int
+my_context_continue(struct my_context *c)
+{
+ int err;
+
+ if (!c->active)
+ return 0;
+
+ DBUG_SWAP_CODE_STATE(&c->dbug_state);
+ err= swapcontext(&c->base_context, &c->spawned_context);
+ DBUG_SWAP_CODE_STATE(&c->dbug_state);
+ if (err)
+ {
+ fprintf(stderr, "Aieie, swapcontext() failed: %d (errno=%d)\n",
+ err, errno);
+ return -1;
+ }
+
+ return c->active;
+}
+
+
+int
+my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
+{
+ int err;
+ union pass_void_ptr_as_2_int u;
+
+ err= getcontext(&c->spawned_context);
+ if (err)
+ return -1;
+ c->spawned_context.uc_stack.ss_sp= c->stack;
+ c->spawned_context.uc_stack.ss_size= c->stack_size;
+ c->spawned_context.uc_link= NULL;
+ c->user_func= f;
+ c->user_data= d;
+ c->active= 1;
+ u.p= c;
+ makecontext(&c->spawned_context, my_context_spawn_internal, 2,
+ u.a[0], u.a[1]);
+
+ return my_context_continue(c);
+}
+
+
+int
+my_context_yield(struct my_context *c)
+{
+ int err;
+
+ if (!c->active)
+ return -1;
+
+ err= swapcontext(&c->spawned_context, &c->base_context);
+ if (err)
+ return -1;
+ return 0;
+}
+
+int
+my_context_init(struct my_context *c, size_t stack_size)
+{
+#if SIZEOF_CHARP > SIZEOF_INT*2
+#error Error: Unable to store pointer in 2 ints on this architecture
+#endif
+ bzero(c, sizeof(*c));
+ if (!(c->stack= malloc(stack_size)))
+ return -1; /* Out of memory */
+ c->stack_size= stack_size;
+#ifdef HAVE_VALGRIND
+ c->valgrind_stack_id=
+ VALGRIND_STACK_REGISTER(c->stack, ((unsigned char *)(c->stack))+stack_size);
+#endif
+ return 0;
+}
+
+void
+my_context_destroy(struct my_context *c)
+{
+ if (c->stack)
+ {
+#ifdef HAVE_VALGRIND
+ VALGRIND_STACK_DEREGISTER(c->valgrind_stack_id);
+#endif
+ free(c->stack);
+ }
+ DBUG_FREE_CODE_STATE(&c->dbug_state);
+}
+
+#endif /* MY_CONTEXT_USE_UCONTEXT */
+
+
+#ifdef MY_CONTEXT_USE_X86_64_GCC_ASM
+/*
+ GCC-amd64 implementation of my_context.
+
+ This is slightly optimized in the common case where we never yield
+ (eg. fetch next row and it is already fully received in buffer). In this
+ case we do not need to restore registers at return (though we still need to
+ save them as we cannot know if we will yield or not in advance).
+*/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/*
+ Layout of saved registers etc.
+ Since this is accessed through gcc inline assembler, it is simpler to just
+ use numbers than to try to define nice constants or structs.
+
+ 0 0 %rsp
+ 1 8 %rbp
+ 2 16 %rbx
+ 3 24 %r12
+ 4 32 %r13
+ 5 40 %r14
+ 6 48 %r15
+ 7 56 %rip for done
+ 8 64 %rip for yield/continue
+*/
+
+int
+my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
+{
+ int ret;
+
+ DBUG_SWAP_CODE_STATE(&c->dbug_state);
+
+ /*
+ There are 6 callee-save registers we need to save and restore when
+ suspending and continuing, plus stack pointer %rsp and instruction pointer
+ %rip.
+
+ However, if we never suspend, the user-supplied function will in any case
+ restore the 6 callee-save registers, so we can avoid restoring them in
+ this case.
+ */
+ __asm__ __volatile__
+ (
+ "movq %%rsp, (%[save])\n\t"
+ "movq %[stack], %%rsp\n\t"
+#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 && !defined(__INTEL_COMPILER)
+ /*
+ This emits a DWARF DW_CFA_undefined directive to make the return address
+ undefined. This indicates that this is the top of the stack frame, and
+ helps tools that use DWARF stack unwinding to obtain stack traces.
+ (I use numeric constant to avoid a dependency on libdwarf includes).
+ */
+ ".cfi_escape 0x07, 16\n\t"
+#endif
+ "movq %%rbp, 8(%[save])\n\t"
+ "movq %%rbx, 16(%[save])\n\t"
+ "movq %%r12, 24(%[save])\n\t"
+ "movq %%r13, 32(%[save])\n\t"
+ "movq %%r14, 40(%[save])\n\t"
+ "movq %%r15, 48(%[save])\n\t"
+ "leaq 1f(%%rip), %%rax\n\t"
+ "leaq 2f(%%rip), %%rcx\n\t"
+ "movq %%rax, 56(%[save])\n\t"
+ "movq %%rcx, 64(%[save])\n\t"
+ /*
+ Constraint below puts the argument to the user function into %rdi, as
+ needed for the calling convention.
+ */
+ "callq *%[f]\n\t"
+ "jmpq *56(%[save])\n"
+ /*
+ Come here when operation is done.
+ We do not need to restore callee-save registers, as the called function
+ will do this for us if needed.
+ */
+ "1:\n\t"
+ "movq (%[save]), %%rsp\n\t"
+ "xorl %[ret], %[ret]\n\t"
+ "jmp 3f\n"
+ /* Come here when operation was suspended. */
+ "2:\n\t"
+ "movl $1, %[ret]\n"
+ "3:\n"
+ : [ret] "=a" (ret),
+ [f] "+S" (f),
+ /* Need this in %rdi to follow calling convention. */
+ [d] "+D" (d)
+ : [stack] "a" (c->stack_top),
+ /* Need this in callee-save register to preserve in function call. */
+ [save] "b" (&c->save[0])
+ : "rcx", "rdx", "r8", "r9", "r10", "r11", "memory", "cc"
+ );
+
+ DBUG_SWAP_CODE_STATE(&c->dbug_state);
+
+ return ret;
+}
+
+int
+my_context_continue(struct my_context *c)
+{
+ int ret;
+
+ DBUG_SWAP_CODE_STATE(&c->dbug_state);
+
+ __asm__ __volatile__
+ (
+ "movq (%[save]), %%rax\n\t"
+ "movq %%rsp, (%[save])\n\t"
+ "movq %%rax, %%rsp\n\t"
+ "movq 8(%[save]), %%rax\n\t"
+ "movq %%rbp, 8(%[save])\n\t"
+ "movq %%rax, %%rbp\n\t"
+ "movq 24(%[save]), %%rax\n\t"
+ "movq %%r12, 24(%[save])\n\t"
+ "movq %%rax, %%r12\n\t"
+ "movq 32(%[save]), %%rax\n\t"
+ "movq %%r13, 32(%[save])\n\t"
+ "movq %%rax, %%r13\n\t"
+ "movq 40(%[save]), %%rax\n\t"
+ "movq %%r14, 40(%[save])\n\t"
+ "movq %%rax, %%r14\n\t"
+ "movq 48(%[save]), %%rax\n\t"
+ "movq %%r15, 48(%[save])\n\t"
+ "movq %%rax, %%r15\n\t"
+
+ "leaq 1f(%%rip), %%rax\n\t"
+ "leaq 2f(%%rip), %%rcx\n\t"
+ "movq %%rax, 56(%[save])\n\t"
+ "movq 64(%[save]), %%rax\n\t"
+ "movq %%rcx, 64(%[save])\n\t"
+
+ "movq 16(%[save]), %%rcx\n\t"
+ "movq %%rbx, 16(%[save])\n\t"
+ "movq %%rcx, %%rbx\n\t"
+
+ "jmpq *%%rax\n"
+ /*
+ Come here when operation is done.
+ Be sure to use the same callee-save register for %[save] here and in
+ my_context_spawn(), so we preserve the value correctly at this point.
+ */
+ "1:\n\t"
+ "movq (%[save]), %%rsp\n\t"
+ "movq 8(%[save]), %%rbp\n\t"
+ /* %rbx is preserved from my_context_spawn() in this case. */
+ "movq 24(%[save]), %%r12\n\t"
+ "movq 32(%[save]), %%r13\n\t"
+ "movq 40(%[save]), %%r14\n\t"
+ "movq 48(%[save]), %%r15\n\t"
+ "xorl %[ret], %[ret]\n\t"
+ "jmp 3f\n"
+ /* Come here when operation is suspended. */
+ "2:\n\t"
+ "movl $1, %[ret]\n"
+ "3:\n"
+ : [ret] "=a" (ret)
+ : /* Need this in callee-save register to preserve in function call. */
+ [save] "b" (&c->save[0])
+ : "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "memory", "cc"
+ );
+
+ DBUG_SWAP_CODE_STATE(&c->dbug_state);
+
+ return ret;
+}
+
+int
+my_context_yield(struct my_context *c)
+{
+ uint64_t *save= &c->save[0];
+ __asm__ __volatile__
+ (
+ "movq (%[save]), %%rax\n\t"
+ "movq %%rsp, (%[save])\n\t"
+ "movq %%rax, %%rsp\n\t"
+ "movq 8(%[save]), %%rax\n\t"
+ "movq %%rbp, 8(%[save])\n\t"
+ "movq %%rax, %%rbp\n\t"
+ "movq 16(%[save]), %%rax\n\t"
+ "movq %%rbx, 16(%[save])\n\t"
+ "movq %%rax, %%rbx\n\t"
+ "movq 24(%[save]), %%rax\n\t"
+ "movq %%r12, 24(%[save])\n\t"
+ "movq %%rax, %%r12\n\t"
+ "movq 32(%[save]), %%rax\n\t"
+ "movq %%r13, 32(%[save])\n\t"
+ "movq %%rax, %%r13\n\t"
+ "movq 40(%[save]), %%rax\n\t"
+ "movq %%r14, 40(%[save])\n\t"
+ "movq %%rax, %%r14\n\t"
+ "movq 48(%[save]), %%rax\n\t"
+ "movq %%r15, 48(%[save])\n\t"
+ "movq %%rax, %%r15\n\t"
+ "movq 64(%[save]), %%rax\n\t"
+ "leaq 1f(%%rip), %%rcx\n\t"
+ "movq %%rcx, 64(%[save])\n\t"
+
+ "jmpq *%%rax\n"
+
+ "1:\n"
+ : [save] "+D" (save)
+ :
+ : "rax", "rcx", "rdx", "rsi", "r8", "r9", "r10", "r11", "memory", "cc"
+ );
+ return 0;
+}
+
+int
+my_context_init(struct my_context *c, size_t stack_size)
+{
+ bzero(c, sizeof(*c));
+
+ if (!(c->stack_bot= malloc(stack_size)))
+ return -1; /* Out of memory */
+ /*
+ The x86_64 ABI specifies 16-byte stack alignment.
+ Also put two zero words at the top of the stack.
+ */
+ c->stack_top= (void *)
+ (( ((intptr)c->stack_bot + stack_size) & ~(intptr)0xf) - 16);
+ bzero(c->stack_top, 16);
+
+#ifdef HAVE_VALGRIND
+ c->valgrind_stack_id=
+ VALGRIND_STACK_REGISTER(c->stack_bot, c->stack_top);
+#endif
+ return 0;
+}
+
+void
+my_context_destroy(struct my_context *c)
+{
+ if (c->stack_bot)
+ {
+ free(c->stack_bot);
+#ifdef HAVE_VALGRIND
+ VALGRIND_STACK_DEREGISTER(c->valgrind_stack_id);
+#endif
+ }
+ DBUG_FREE_CODE_STATE(&c->dbug_state);
+}
+
+#endif /* MY_CONTEXT_USE_X86_64_GCC_ASM */
+
+
+#ifdef MY_CONTEXT_USE_I386_GCC_ASM
+/*
+ GCC-i386 implementation of my_context.
+
+ This is slightly optimized in the common case where we never yield
+ (eg. fetch next row and it is already fully received in buffer). In this
+ case we do not need to restore registers at return (though we still need to
+ save them as we cannot know if we will yield or not in advance).
+*/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/*
+ Layout of saved registers etc.
+ Since this is accessed through gcc inline assembler, it is simpler to just
+ use numbers than to try to define nice constants or structs.
+
+ 0 0 %esp
+ 1 4 %ebp
+ 2 8 %ebx
+ 3 12 %esi
+ 4 16 %edi
+ 5 20 %eip for done
+ 6 24 %eip for yield/continue
+*/
+
+int
+my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
+{
+ void (*tmp_f)(void *)= f;
+ void *tmp_d= d;
+ int ret;
+
+ DBUG_SWAP_CODE_STATE(&c->dbug_state);
+
+ /*
+ There are 4 callee-save registers we need to save and restore when
+ suspending and continuing, plus stack pointer %esp and instruction pointer
+ %eip.
+
+ However, if we never suspend, the user-supplied function will in any case
+ restore the 4 callee-save registers, so we can avoid restoring them in
+ this case.
+ */
+ __asm__ __volatile__
+ (
+ "movl %%esp, (%[save])\n\t"
+ "movl %[stack], %%esp\n\t"
+#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 && !defined(__INTEL_COMPILER)
+ /*
+ This emits a DWARF DW_CFA_undefined directive to make the return address
+ undefined. This indicates that this is the top of the stack frame, and
+ helps tools that use DWARF stack unwinding to obtain stack traces.
+ (I use numeric constant to avoid a dependency on libdwarf includes).
+ */
+ ".cfi_escape 0x07, 8\n\t"
+#endif
+ /* Push the parameter on the stack. */
+ "pushl %[d]\n\t"
+ "movl %%ebp, 4(%[save])\n\t"
+ "movl %%ebx, 8(%[save])\n\t"
+ "movl %%esi, 12(%[save])\n\t"
+ "movl %%edi, 16(%[save])\n\t"
+ /* Get label addresses in -fPIC-compatible way (no pc-relative on 32bit) */
+ "call 1f\n"
+ "1:\n\t"
+ "popl %%eax\n\t"
+ "addl $(2f-1b), %%eax\n\t"
+ "movl %%eax, 20(%[save])\n\t"
+ "addl $(3f-2f), %%eax\n\t"
+ "movl %%eax, 24(%[save])\n\t"
+ "call *%[f]\n\t"
+ "jmp *20(%[save])\n"
+ /*
+ Come here when operation is done.
+ We do not need to restore callee-save registers, as the called function
+ will do this for us if needed.
+ */
+ "2:\n\t"
+ "movl (%[save]), %%esp\n\t"
+ "xorl %[ret], %[ret]\n\t"
+ "jmp 4f\n"
+ /* Come here when operation was suspended. */
+ "3:\n\t"
+ "movl $1, %[ret]\n"
+ "4:\n"
+ : [ret] "=a" (ret),
+ [f] "+c" (tmp_f),
+ [d] "+d" (tmp_d)
+ : [stack] "a" (c->stack_top),
+ /* Need this in callee-save register to preserve across function call. */
+ [save] "D" (&c->save[0])
+ : "memory", "cc"
+ );
+
+ DBUG_SWAP_CODE_STATE(&c->dbug_state);
+
+ return ret;
+}
+
+int
+my_context_continue(struct my_context *c)
+{
+ int ret;
+
+ DBUG_SWAP_CODE_STATE(&c->dbug_state);
+
+ __asm__ __volatile__
+ (
+ "movl (%[save]), %%eax\n\t"
+ "movl %%esp, (%[save])\n\t"
+ "movl %%eax, %%esp\n\t"
+ "movl 4(%[save]), %%eax\n\t"
+ "movl %%ebp, 4(%[save])\n\t"
+ "movl %%eax, %%ebp\n\t"
+ "movl 8(%[save]), %%eax\n\t"
+ "movl %%ebx, 8(%[save])\n\t"
+ "movl %%eax, %%ebx\n\t"
+ "movl 12(%[save]), %%eax\n\t"
+ "movl %%esi, 12(%[save])\n\t"
+ "movl %%eax, %%esi\n\t"
+
+ "movl 24(%[save]), %%eax\n\t"
+ "call 1f\n"
+ "1:\n\t"
+ "popl %%ecx\n\t"
+ "addl $(2f-1b), %%ecx\n\t"
+ "movl %%ecx, 20(%[save])\n\t"
+ "addl $(3f-2f), %%ecx\n\t"
+ "movl %%ecx, 24(%[save])\n\t"
+
+ /* Must restore %edi last as it is also our %[save] register. */
+ "movl 16(%[save]), %%ecx\n\t"
+ "movl %%edi, 16(%[save])\n\t"
+ "movl %%ecx, %%edi\n\t"
+
+ "jmp *%%eax\n"
+ /*
+ Come here when operation is done.
+ Be sure to use the same callee-save register for %[save] here and in
+ my_context_spawn(), so we preserve the value correctly at this point.
+ */
+ "2:\n\t"
+ "movl (%[save]), %%esp\n\t"
+ "movl 4(%[save]), %%ebp\n\t"
+ "movl 8(%[save]), %%ebx\n\t"
+ "movl 12(%[save]), %%esi\n\t"
+ "movl 16(%[save]), %%edi\n\t"
+ "xorl %[ret], %[ret]\n\t"
+ "jmp 4f\n"
+ /* Come here when operation is suspended. */
+ "3:\n\t"
+ "movl $1, %[ret]\n"
+ "4:\n"
+ : [ret] "=a" (ret)
+ : /* Need this in callee-save register to preserve in function call. */
+ [save] "D" (&c->save[0])
+ : "ecx", "edx", "memory", "cc"
+ );
+
+ DBUG_SWAP_CODE_STATE(&c->dbug_state);
+
+ return ret;
+}
+
+int
+my_context_yield(struct my_context *c)
+{
+ uint64_t *save= &c->save[0];
+ __asm__ __volatile__
+ (
+ "movl (%[save]), %%eax\n\t"
+ "movl %%esp, (%[save])\n\t"
+ "movl %%eax, %%esp\n\t"
+ "movl 4(%[save]), %%eax\n\t"
+ "movl %%ebp, 4(%[save])\n\t"
+ "movl %%eax, %%ebp\n\t"
+ "movl 8(%[save]), %%eax\n\t"
+ "movl %%ebx, 8(%[save])\n\t"
+ "movl %%eax, %%ebx\n\t"
+ "movl 12(%[save]), %%eax\n\t"
+ "movl %%esi, 12(%[save])\n\t"
+ "movl %%eax, %%esi\n\t"
+ "movl 16(%[save]), %%eax\n\t"
+ "movl %%edi, 16(%[save])\n\t"
+ "movl %%eax, %%edi\n\t"
+
+ "movl 24(%[save]), %%eax\n\t"
+ "call 1f\n"
+ "1:\n\t"
+ "popl %%ecx\n\t"
+ "addl $(2f-1b), %%ecx\n\t"
+ "movl %%ecx, 24(%[save])\n\t"
+
+ "jmp *%%eax\n"
+
+ "2:\n"
+ : [save] "+d" (save)
+ :
+ : "eax", "ecx", "memory", "cc"
+ );
+ return 0;
+}
+
+int
+my_context_init(struct my_context *c, size_t stack_size)
+{
+ bzero(c, sizeof(*c));
+ if (!(c->stack_bot= malloc(stack_size)))
+ return -1; /* Out of memory */
+ c->stack_top= (void *)
+ (( ((intptr)c->stack_bot + stack_size) & ~(intptr)0xf) - 16);
+ bzero(c->stack_top, 16);
+
+#ifdef HAVE_VALGRIND
+ c->valgrind_stack_id=
+ VALGRIND_STACK_REGISTER(c->stack_bot, c->stack_top);
+#endif
+ return 0;
+}
+
+void
+my_context_destroy(struct my_context *c)
+{
+ if (c->stack_bot)
+ {
+ free(c->stack_bot);
+#ifdef HAVE_VALGRIND
+ VALGRIND_STACK_DEREGISTER(c->valgrind_stack_id);
+#endif
+ }
+ DBUG_FREE_CODE_STATE(&c->dbug_state);
+}
+
+#endif /* MY_CONTEXT_USE_I386_GCC_ASM */
+
+
+#ifdef MY_CONTEXT_USE_WIN32_FIBERS
+int
+my_context_yield(struct my_context *c)
+{
+ c->return_value= 1;
+ SwitchToFiber(c->app_fiber);
+ return 0;
+}
+
+
+static void WINAPI
+my_context_trampoline(void *p)
+{
+ struct my_context *c= (struct my_context *)p;
+ /*
+ Reuse the Fiber by looping infinitely, each time we are scheduled we
+ spawn the appropriate function and switch back when it is done.
+
+ This way we avoid the overhead of CreateFiber() for every asynchroneous
+ operation.
+ */
+ for(;;)
+ {
+ (*(c->user_func))(c->user_arg);
+ c->return_value= 0;
+ SwitchToFiber(c->app_fiber);
+ }
+}
+
+int
+my_context_init(struct my_context *c, size_t stack_size)
+{
+ bzero(c, sizeof(*c));
+ c->lib_fiber= CreateFiber(stack_size, my_context_trampoline, c);
+ if (c->lib_fiber)
+ return 0;
+ return -1;
+}
+
+void
+my_context_destroy(struct my_context *c)
+{
+ DBUG_FREE_CODE_STATE(&c->dbug_state);
+ if (c->lib_fiber)
+ {
+ DeleteFiber(c->lib_fiber);
+ c->lib_fiber= NULL;
+ }
+}
+
+int
+my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
+{
+ void *current_fiber;
+ c->user_func= f;
+ c->user_arg= d;
+ /*
+ This seems to be a common trick to run ConvertThreadToFiber() only on the
+ first occurence in a thread, in a way that works on multiple Windows
+ versions.
+ */
+ current_fiber= GetCurrentFiber();
+ if (current_fiber == NULL || current_fiber == (void *)0x1e00)
+ current_fiber= ConvertThreadToFiber(c);
+ c->app_fiber= current_fiber;
+ DBUG_SWAP_CODE_STATE(&c->dbug_state);
+ SwitchToFiber(c->lib_fiber);
+ DBUG_SWAP_CODE_STATE(&c->dbug_state);
+ return c->return_value;
+}
+
+int
+my_context_continue(struct my_context *c)
+{
+ DBUG_SWAP_CODE_STATE(&c->dbug_state);
+ SwitchToFiber(c->lib_fiber);
+ DBUG_SWAP_CODE_STATE(&c->dbug_state);
+ return c->return_value;
+}
+
+#endif /* MY_CONTEXT_USE_WIN32_FIBERS */
diff --git a/mysys/my_copy.c b/mysys/my_copy.c
index 7f2a3fffd62..21de1e953a2 100644
--- a/mysys/my_copy.c
+++ b/mysys/my_copy.c
@@ -12,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -118,36 +117,36 @@ int my_copy(const char *from, const char *to, myf MyFlags)
if (MyFlags & MY_FAE)
goto err;
}
-#if !defined(__WIN__) && !defined(__NETWARE__)
+#if !defined(__WIN__)
/* Copy ownership */
- if (chown(to, stat_buff.st_uid,stat_buff.st_gid))
+ if (chown(to, stat_buff.st_uid, stat_buff.st_gid))
{
my_errno= errno;
if (MyFlags & MY_WME)
- my_error(EE_CANT_COPY_OWNERSHIP, MYF(ME_JUST_WARNING), to, errno);
+ my_error(EE_CANT_COPY_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), to, errno);
if (MyFlags & MY_FAE)
goto err;
}
#endif
-#if !defined(VMS) && !defined(__ZTC__)
+
if (MyFlags & MY_COPYTIME)
{
struct utimbuf timep;
timep.actime = stat_buff.st_atime;
timep.modtime = stat_buff.st_mtime;
- VOID(utime((char*) to, &timep)); /* last accessed and modified times */
+ (void) utime((char*) to, &timep); /* last accessed and modified times */
}
-#endif
+
DBUG_RETURN(0);
}
err:
- if (from_file >= 0) VOID(my_close(from_file,MyFlags));
- if (to_file >= 0) VOID(my_close(to_file, MyFlags));
+ if (from_file >= 0) (void) my_close(from_file,MyFlags);
+ if (to_file >= 0) (void) my_close(to_file, MyFlags);
/* attempt to delete the to-file we've partially written */
if (file_created)
- VOID(my_delete(to, MyFlags));
+ (void) my_delete(to, MyFlags);
DBUG_RETURN(-1);
} /* my_copy */
diff --git a/mysys/my_create.c b/mysys/my_create.c
index d0436276d03..2e4e8eb1af2 100644
--- a/mysys/my_create.c
+++ b/mysys/my_create.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2001, 2005-2008 MySQL AB, 2009 Sun Microsystems, Inc.
+ 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
@@ -11,7 +12,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include <my_dir.h>
@@ -39,14 +40,11 @@ File my_create(const char *FileName, int CreateFlags, int access_flags,
DBUG_ENTER("my_create");
DBUG_PRINT("my",("Name: '%s' CreateFlags: %d AccessFlags: %d MyFlags: %d",
FileName, CreateFlags, access_flags, MyFlags));
-
-#if !defined(NO_OPEN_3)
- fd= open((char *) FileName, access_flags | O_CREAT,
- CreateFlags ? CreateFlags : my_umask);
-#elif defined(_WIN32)
+#if defined(_WIN32)
fd= my_win_open(FileName, access_flags | O_CREAT);
#else
- fd= open(FileName, access_flags);
+ fd= open((char *) FileName, access_flags | O_CREAT,
+ CreateFlags ? CreateFlags : my_umask);
#endif
if ((MyFlags & MY_SYNC_DIR) && (fd >=0) &&
diff --git a/mysys/my_delete.c b/mysys/my_delete.c
index 22425ed95fd..cf9573f592b 100644
--- a/mysys/my_delete.c
+++ b/mysys/my_delete.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -36,8 +36,8 @@ int my_delete(const char *name, myf MyFlags)
DBUG_RETURN(err);
} /* my_delete */
-#if defined(__WIN__) && defined(__NT__)
-/*
+#if defined(__WIN__)
+/**
Delete file which is possibly not closed.
This function is intended to be used exclusively as a temporal solution
@@ -53,6 +53,20 @@ int my_delete(const char *name, myf MyFlags)
renamed to <name>.<num>.deleted where <name> - the initial name of the
file, <num> - a hexadecimal number chosen to make the temporal name to
be unique.
+
+ @param the name of the being deleted file
+ @param the flags instructing how to react on an error internally in
+ the function
+
+ @note The per-thread @c my_errno holds additional info for a caller to
+ decide how critical the error can be.
+
+ @retval
+ 0 ok
+ @retval
+ 1 error
+
+
*/
int nt_share_delete(const char *name, myf MyFlags)
{
@@ -63,6 +77,7 @@ int nt_share_delete(const char *name, myf MyFlags)
for (cnt= GetTickCount(); cnt; cnt--)
{
+ errno= 0;
sprintf(buf, "%s.%08X.deleted", name, cnt);
if (MoveFile(name, buf))
break;
@@ -79,14 +94,32 @@ int nt_share_delete(const char *name, myf MyFlags)
break;
}
- if (DeleteFile(buf))
- DBUG_RETURN(0);
+ if (errno == ERROR_FILE_NOT_FOUND)
+ {
+ my_errno= ENOENT; // marking, that `name' doesn't exist
+ }
+ else if (errno == 0)
+ {
+ if (DeleteFile(buf))
+ DBUG_RETURN(0);
+ /*
+ The below is more complicated than necessary. For some reason, the
+ assignment to my_errno clears the error number, which is retrieved
+ by GetLastError() (VC2005EE). Assigning to errno first, allows to
+ retrieve the correct value.
+ */
+ errno= GetLastError();
+ if (errno == 0)
+ my_errno= ENOENT; // marking, that `buf' doesn't exist
+ else
+ my_errno= errno;
+ }
+ else
+ my_errno= errno;
- my_errno= GetLastError();
if (MyFlags & (MY_FAE+MY_WME))
my_error(EE_DELETE, MYF(ME_BELL + ME_WAITTANG + (MyFlags & ME_NOINPUT)),
- name, my_errno);
-
+ name, my_errno);
DBUG_RETURN(-1);
}
#endif
diff --git a/mysys/my_dup.c b/mysys/my_dup.c
deleted file mode 100644
index 5fdd6e9f364..00000000000
--- a/mysys/my_dup.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (C) 2000 MySQL 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "mysys_priv.h"
-#include "mysys_err.h"
-#include <my_dir.h>
-#include <errno.h>
-#if defined(__WIN__)
-#include <share.h>
-#endif
-
- /* Open a file */
-
-File my_dup(File file, myf MyFlags)
-{
- File fd;
- const char *filename;
- DBUG_ENTER("my_dup");
- DBUG_PRINT("my",("file: %d MyFlags: %d", file, MyFlags));
-#ifdef _WIN32
- fd= my_win_dup(file);
-#else
- fd= dup(file);
-#endif
- filename= (((uint) file < my_file_limit) ?
- my_file_info[(int) file].name : "Unknown");
- DBUG_RETURN(my_register_filename(fd, filename, FILE_BY_DUP,
- EE_FILENOTFOUND, MyFlags));
-} /* my_open */
diff --git a/mysys/my_error.c b/mysys/my_error.c
index 78130ecc0f6..3302add688b 100644
--- a/mysys/my_error.c
+++ b/mysys/my_error.c
@@ -1,6 +1,4 @@
-/*
- Copyright (c) 2000-2004, 2006, 2007 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* Copyright (c) 2000, 2010, 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
@@ -13,8 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -25,7 +22,6 @@
/* Max length of a error message. Should be kept in sync with MYSQL_ERRMSG_SIZE. */
#define ERRMSGSIZE (512)
-
/* Define some external variables for error handling */
/*
@@ -52,11 +48,11 @@
*/
static struct my_err_head
{
- struct my_err_head *meh_next; /* chain link */
- const char **meh_errmsgs; /* error messages array */
- int meh_first; /* error number matching array slot 0 */
- int meh_last; /* error number matching last slot */
-} my_errmsgs_globerrs = {NULL, globerrs, EE_ERROR_FIRST, EE_ERROR_LAST};
+ struct my_err_head *meh_next; /* chain link */
+ const char** (*get_errmsgs) (); /* returns error message format */
+ int meh_first; /* error number matching array slot 0 */
+ int meh_last; /* error number matching last slot */
+} my_errmsgs_globerrs = {NULL, get_global_errmsgs, EE_ERROR_FIRST, EE_ERROR_LAST};
static struct my_err_head *my_errmsgs_list= &my_errmsgs_globerrs;
@@ -70,12 +66,9 @@ static struct my_err_head *my_errmsgs_list= &my_errmsgs_globerrs;
MyFlags Flags
... variable list
- RETURN
- What (*error_handler_hook)() returns:
- 0 OK
*/
-int my_error(int nr, myf MyFlags, ...)
+void my_error(int nr, myf MyFlags, ...)
{
const char *format;
struct my_err_head *meh_p;
@@ -91,15 +84,17 @@ int my_error(int nr, myf MyFlags, ...)
/* get the error message string. Default, if NULL or empty string (""). */
if (! (format= (meh_p && (nr >= meh_p->meh_first)) ?
- meh_p->meh_errmsgs[nr - meh_p->meh_first] : NULL) || ! *format)
- (void) my_snprintf(ebuff, sizeof(ebuff), "Unknown error %d", nr);
+ meh_p->get_errmsgs()[nr - meh_p->meh_first] : NULL) || ! *format)
+ (void) my_snprintf (ebuff, sizeof(ebuff), "Unknown error %d", nr);
else
{
va_start(args,MyFlags);
- (void) my_vsnprintf(ebuff, sizeof(ebuff), format, args);
+ (void) my_vsnprintf_ex(&my_charset_utf8_general_ci, ebuff,
+ sizeof(ebuff), format, args);
va_end(args);
}
- DBUG_RETURN((*error_handler_hook)(nr, ebuff, MyFlags));
+ (*error_handler_hook)(nr, ebuff, MyFlags);
+ DBUG_VOID_RETURN;
}
@@ -114,7 +109,7 @@ int my_error(int nr, myf MyFlags, ...)
... variable list
*/
-int my_printf_error(uint error, const char *format, myf MyFlags, ...)
+void my_printf_error(uint error, const char *format, myf MyFlags, ...)
{
va_list args;
char ebuff[ERRMSGSIZE];
@@ -123,12 +118,13 @@ int my_printf_error(uint error, const char *format, myf MyFlags, ...)
error, MyFlags, errno, format));
va_start(args,MyFlags);
- (void) my_vsnprintf(ebuff, sizeof(ebuff), format, args);
+ (void) my_vsnprintf_ex(&my_charset_utf8_general_ci, ebuff,
+ sizeof(ebuff), format, args);
va_end(args);
- DBUG_RETURN((*error_handler_hook)(error, ebuff, MyFlags));
+ (*error_handler_hook)(error, ebuff, MyFlags);
+ DBUG_VOID_RETURN;
}
-
/*
Error with va_list
@@ -140,15 +136,16 @@ int my_printf_error(uint error, const char *format, myf MyFlags, ...)
... variable list
*/
-int my_printv_error(uint error, const char *format, myf MyFlags, va_list ap)
+void my_printv_error(uint error, const char *format, myf MyFlags, va_list ap)
{
- char ebuff[ERRMSGSIZE+20];
+ char ebuff[ERRMSGSIZE];
DBUG_ENTER("my_printv_error");
DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d format: %s",
error, MyFlags, errno, format));
(void) my_vsnprintf(ebuff, sizeof(ebuff), format, ap);
- DBUG_RETURN((*error_handler_hook)(error, ebuff, MyFlags));
+ (*error_handler_hook)(error, ebuff, MyFlags);
+ DBUG_VOID_RETURN;
}
@@ -162,9 +159,9 @@ int my_printv_error(uint error, const char *format, myf MyFlags, va_list ap)
MyFlags Flags
*/
-int my_message(uint error, const char *str, register myf MyFlags)
+void my_message(uint error, const char *str, register myf MyFlags)
{
- return (*error_handler_hook)(error, str, MyFlags);
+ (*error_handler_hook)(error, str, MyFlags);
}
@@ -190,7 +187,7 @@ int my_message(uint error, const char *str, register myf MyFlags)
!= 0 Error
*/
-int my_error_register(const char **errmsgs, int first, int last)
+int my_error_register(const char** (*get_errmsgs) (), int first, int last)
{
struct my_err_head *meh_p;
struct my_err_head **search_meh_pp;
@@ -199,7 +196,7 @@ int my_error_register(const char **errmsgs, int first, int last)
if (! (meh_p= (struct my_err_head*) my_malloc(sizeof(struct my_err_head),
MYF(MY_WME))))
return 1;
- meh_p->meh_errmsgs= errmsgs;
+ meh_p->get_errmsgs= get_errmsgs;
meh_p->meh_first= first;
meh_p->meh_last= last;
@@ -215,7 +212,7 @@ int my_error_register(const char **errmsgs, int first, int last)
/* Error numbers must be unique. No overlapping is allowed. */
if (*search_meh_pp && ((*search_meh_pp)->meh_first <= last))
{
- my_free((uchar*)meh_p, MYF(0));
+ my_free(meh_p);
return 1;
}
@@ -270,8 +267,8 @@ const char **my_error_unregister(int first, int last)
*search_meh_pp= meh_p->meh_next;
/* Save the return value and free the header. */
- errmsgs= meh_p->meh_errmsgs;
- my_free((uchar*) meh_p, MYF(0));
+ errmsgs= meh_p->get_errmsgs();
+ my_free(meh_p);
return errmsgs;
}
@@ -286,7 +283,7 @@ void my_error_unregister_all(void)
/* We need this ptr, but we're about to free its container, so save it. */
saved_next= cursor->meh_next;
- my_free((uchar*) cursor, MYF(0));
+ my_free(cursor);
}
my_errmsgs_globerrs.meh_next= NULL; /* Freed in first iteration above. */
diff --git a/mysys/my_file.c b/mysys/my_file.c
index f0dd51bdcd5..8d01285a94b 100644
--- a/mysys/my_file.c
+++ b/mysys/my_file.c
@@ -12,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "my_static.h"
@@ -129,7 +128,7 @@ void my_free_open_file_info()
/* Copy data back for my_print_open_files */
memcpy((char*) my_file_info_default, my_file_info,
sizeof(*my_file_info_default)* MY_NFILE);
- my_free((char*) my_file_info, MYF(0));
+ my_free(my_file_info);
my_file_info= my_file_info_default;
my_file_limit= MY_NFILE;
}
diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c
index ae631a59353..54469d2c05a 100644
--- a/mysys/my_fopen.c
+++ b/mysys/my_fopen.c
@@ -68,18 +68,18 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags)
thread_safe_increment(my_stream_opened,&THR_LOCK_open);
DBUG_RETURN(fd); /* safeguard */
}
- pthread_mutex_lock(&THR_LOCK_open);
+ mysql_mutex_lock(&THR_LOCK_open);
if ((my_file_info[filedesc].name= (char*)
my_strdup(filename,MyFlags)))
{
my_stream_opened++;
my_file_total_opened++;
my_file_info[filedesc].type= STREAM_BY_FOPEN;
- pthread_mutex_unlock(&THR_LOCK_open);
+ mysql_mutex_unlock(&THR_LOCK_open);
DBUG_PRINT("exit",("stream: 0x%lx", (long) fd));
DBUG_RETURN(fd);
}
- pthread_mutex_unlock(&THR_LOCK_open);
+ mysql_mutex_unlock(&THR_LOCK_open);
(void) my_fclose(fd,MyFlags);
my_errno=ENOMEM;
}
@@ -231,7 +231,7 @@ int my_fclose(FILE *fd, myf MyFlags)
DBUG_ENTER("my_fclose");
DBUG_PRINT("my",("stream: 0x%lx MyFlags: %d", (long) fd, MyFlags));
- pthread_mutex_lock(&THR_LOCK_open);
+ mysql_mutex_lock(&THR_LOCK_open);
file= my_fileno(fd);
#ifndef _WIN32
err= fclose(fd);
@@ -250,9 +250,9 @@ int my_fclose(FILE *fd, myf MyFlags)
if ((uint) file < my_file_limit && my_file_info[file].type != UNOPEN)
{
my_file_info[file].type = UNOPEN;
- my_free(my_file_info[file].name, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(my_file_info[file].name);
}
- pthread_mutex_unlock(&THR_LOCK_open);
+ mysql_mutex_unlock(&THR_LOCK_open);
DBUG_RETURN(err);
} /* my_fclose */
@@ -282,7 +282,7 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
}
else
{
- pthread_mutex_lock(&THR_LOCK_open);
+ mysql_mutex_lock(&THR_LOCK_open);
my_stream_opened++;
if ((uint) Filedes < (uint) my_file_limit)
{
@@ -296,7 +296,7 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
}
my_file_info[Filedes].type = STREAM_BY_FDOPEN;
}
- pthread_mutex_unlock(&THR_LOCK_open);
+ mysql_mutex_unlock(&THR_LOCK_open);
}
DBUG_PRINT("exit",("stream: 0x%lx", (long) fd));
diff --git a/mysys/my_fstream.c b/mysys/my_fstream.c
index 8cee4819ed2..e758609741b 100644
--- a/mysys/my_fstream.c
+++ b/mysys/my_fstream.c
@@ -1,6 +1,4 @@
-/*
- Copyright (c) 2000, 2001, 2004, 2006, 2007 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* 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
@@ -13,8 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* USE_MY_STREAM isn't set because we can't thrust my_fclose! */
@@ -122,21 +119,20 @@ size_t my_fwrite(FILE *stream, const uchar *Buffer, size_t Count, myf MyFlags)
#ifdef EINTR
if (errno == EINTR)
{
- VOID(my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0)));
+ (void) my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0));
continue;
}
#endif
#if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM)
-#ifdef THREAD
if (my_thread_var->abort)
MyFlags&= ~ MY_WAIT_IF_FULL; /* End if aborted by user */
-#endif
+
if ((errno == ENOSPC || errno == EDQUOT) &&
(MyFlags & MY_WAIT_IF_FULL))
{
wait_for_free_space("[stream]", errors);
errors++;
- VOID(my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0)));
+ (void) my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0));
continue;
}
#endif
diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c
index c4ab39dbcf1..74dae29f235 100644
--- a/mysys/my_gethwaddr.c
+++ b/mysys/my_gethwaddr.c
@@ -1,5 +1,6 @@
/*
Copyright (c) 2004, 2010, Oracle and/or its affiliates
+ Copyright (c) 2011, Monty Program 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
@@ -12,13 +13,11 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* get hardware address for an interface */
/* if there are many available, any non-zero one can be used */
-#define DONT_DEFINE_VOID /* windows includes break if we do */
#include "mysys_priv.h"
#include <m_string.h>
@@ -131,6 +130,7 @@ err:
#elif defined(_WIN32)
#include <winsock2.h>
#include <iphlpapi.h>
+#pragma comment(lib, "iphlpapi.lib")
#define ETHER_ADDR_LEN 6
@@ -144,7 +144,7 @@ my_bool my_gethwaddr(uchar *to)
if (GetAdaptersInfo(info, &info_len) != ERROR_BUFFER_OVERFLOW)
goto err;
- info= alloca(info_len);
+ info= (IP_ADAPTER_INFO *)alloca(info_len);
if (GetAdaptersInfo(info, &info_len) != NO_ERROR)
goto err;
@@ -163,7 +163,7 @@ err:
return res;
}
-#else /* neither FreeBSD nor linux not Windows */
+#else /* unsupported system */
/* just fail */
my_bool my_gethwaddr(uchar *to __attribute__((unused)))
{
diff --git a/mysys/my_getncpus.c b/mysys/my_getncpus.c
index 6a101aeb703..cc2c3843e0e 100644
--- a/mysys/my_getncpus.c
+++ b/mysys/my_getncpus.c
@@ -12,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* get the number of (online) CPUs */
@@ -32,7 +31,15 @@ int my_getncpus()
ncpus= sysconf(_SC_NPROCESSORS_ONLN);
#elif defined(__WIN__)
SYSTEM_INFO sysinfo;
+
+ /*
+ * We are not calling GetNativeSystemInfo here because (1) we
+ * don't believe that they return different values for number
+ * of processors and (2) if WOW64 limits processors for Win32
+ * then we don't want to try to override that.
+ */
GetSystemInfo(&sysinfo);
+
ncpus= sysinfo.dwNumberOfProcessors;
#else
/* unknown so play safe: assume SMP and forbid uniprocessor build */
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index 7e56c4ebe22..7905ad90877 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002, 2010, Oracle and/or its affiliates
+ Copyright (c) 2002, 2011, Oracle and/or its affiliates
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
@@ -12,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include <m_string.h>
@@ -30,24 +29,15 @@ typedef void (*init_func_p)(const struct my_option *option, void *variable,
static void default_reporter(enum loglevel level, const char *format, ...);
my_error_reporter my_getopt_error_reporter= &default_reporter;
-static int findopt(char *optpat, uint length,
- const struct my_option **opt_res,
- const char **ffname);
-my_bool getopt_compare_strings(const char *s,
- const char *t,
- uint length);
+static int findopt(char *, uint, const struct my_option **, const char **);
+my_bool getopt_compare_strings(const char *, const char *, uint);
static longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
-static ulonglong getopt_ull(char *arg, const struct my_option *optp,
- int *err);
+static ulonglong getopt_ull(char *, const struct my_option *, int *);
static double getopt_double(char *arg, const struct my_option *optp, int *err);
-static void init_variables(const struct my_option *options,
- init_func_p init_one_value);
-static void init_one_value(const struct my_option *option, void *variable,
- longlong value);
-static void fini_one_value(const struct my_option *option, void *variable,
- longlong value);
-static int setval(const struct my_option *opts, void *value, char *argument,
- my_bool set_maximum_value);
+static void init_variables(const struct my_option *, init_func_p);
+static void init_one_value(const struct my_option *, void *, longlong);
+static void fini_one_value(const struct my_option *, void *, longlong);
+static int setval(const struct my_option *, void *, char *, my_bool);
static char *check_struct_option(char *cur_arg, char *key_name);
/*
@@ -62,6 +52,7 @@ enum enum_special_opt
{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
char *disabled_my_option= (char*) "0";
+char *enabled_my_option= (char*) "1";
/*
This is a flag that can be set in client programs. 0 means that
@@ -82,6 +73,8 @@ static void default_reporter(enum loglevel level,
const char *format, ...)
{
va_list args;
+ DBUG_ENTER("default_reporter");
+
va_start(args, format);
if (level == WARNING_LEVEL)
fprintf(stderr, "%s", "Warning: ");
@@ -91,18 +84,9 @@ static void default_reporter(enum loglevel level,
va_end(args);
fputc('\n', stderr);
fflush(stderr);
+ DBUG_VOID_RETURN;
}
-/*
- function: handle_options
-
- Sort options; put options first, until special end of options (--), or
- until end of argv. Parse options; check that the given option matches with
- one of the options in struct 'my_option', return error in case of ambiguous
- or unknown option. Check that option was given an argument if it requires
- one. Call function 'get_one_option()' once for each option.
-*/
-
static my_getopt_value getopt_get_addr;
void my_getopt_register_get_addr(my_getopt_value func_addr)
@@ -110,6 +94,65 @@ void my_getopt_register_get_addr(my_getopt_value func_addr)
getopt_get_addr= func_addr;
}
+/**
+ Handle command line options.
+ Sort options.
+ Put options first, until special end of options (--),
+ or until the end of argv. Parse options, check that the given option
+ matches with one of the options in struct 'my_option'.
+ Check that option was given an argument if it requires one
+ Call the optional 'get_one_option()' function once for each option.
+
+ Note that handle_options() can be invoked multiple times to
+ parse a command line in several steps.
+ In this case, use the global flag @c my_getopt_skip_unknown to indicate
+ that options unknown in the current step should be preserved in the
+ command line for later parsing in subsequent steps.
+
+ For 'long' options (--a_long_option), @c my_getopt_skip_unknown is
+ fully supported. Command line parameters such as:
+ - "--a_long_option"
+ - "--a_long_option=value"
+ - "--a_long_option value"
+ will be preserved as is when the option is not known.
+
+ For 'short' options (-S), support for @c my_getopt_skip_unknown
+ comes with some limitation, because several short options
+ can also be specified together in the same command line argument,
+ as in "-XYZ".
+
+ The first use case supported is: all short options are declared.
+ handle_options() will be able to interpret "-XYZ" as one of:
+ - an unknown X option
+ - "-X -Y -Z", three short options with no arguments
+ - "-X -YZ", where Y is a short option with argument Z
+ - "-XYZ", where X is a short option with argument YZ
+ based on the full short options specifications.
+
+ The second use case supported is: no short option is declared.
+ handle_options() will reject "-XYZ" as unknown, to be parsed later.
+
+ The use case that is explicitly not supported is to provide
+ only a partial list of short options to handle_options().
+ This function can not be expected to extract some option Y
+ in the middle of the string "-XYZ" in these conditions,
+ without knowing if X will be declared an option later.
+
+ Note that this limitation only impacts parsing of several
+ short options from the same command line argument,
+ as in "mysqld -anW5".
+ When each short option is properly separated out in the command line
+ argument, for example in "mysqld -a -n -w5", the code would actually
+ work even with partial options specs given at each stage.
+
+ @param [in, out] argc command line options (count)
+ @param [in, out] argv command line options (values)
+ @param [in] longopts descriptor of all valid options
+ @param [in] get_one_option optional callback function to process each option,
+ can be NULL.
+ @return error in case of ambiguous or unknown options,
+ 0 on success.
+*/
int handle_options(int *argc, char ***argv,
const struct my_option *longopts,
my_get_one_option get_one_option)
@@ -118,10 +161,12 @@ int handle_options(int *argc, char ***argv,
my_bool end_of_options= 0, must_be_var, set_maximum_value,
option_is_loose;
char **pos, **pos_end, *optend, *opt_str, key_name[FN_REFLEN];
- const char *prev_found;
+ const char *UNINIT_VAR(prev_found);
const struct my_option *optp;
void *value;
int error, i;
+ my_bool is_cmdline_arg= 1;
+ DBUG_ENTER("handle_options");
/* handle_options() assumes arg0 (program name) always exists */
DBUG_ASSERT(argc && *argc >= 1);
@@ -130,10 +175,35 @@ int handle_options(int *argc, char ***argv,
(*argv)++; /* --- || ---- */
init_variables(longopts, init_one_value);
+ /*
+ Search for args_separator, if found, then the first part of the
+ arguments are loaded from configs
+ */
+ for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
+ {
+ if (my_getopt_is_args_separator(*pos))
+ {
+ is_cmdline_arg= 0;
+ break;
+ }
+ }
+
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
{
char **first= pos;
char *cur_arg= *pos;
+ opt_found= 0;
+ if (!is_cmdline_arg && (my_getopt_is_args_separator(cur_arg)))
+ {
+ is_cmdline_arg= 1;
+
+ /* save the separator too if skip unkown options */
+ if (my_getopt_skip_unknown)
+ (*argv)[argvpos++]= cur_arg;
+ else
+ (*argc)--;
+ continue;
+ }
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
{
char *argument= 0;
@@ -142,78 +212,15 @@ int handle_options(int *argc, char ***argv,
option_is_loose= 0;
cur_arg++; /* skip '-' */
- if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
- { /* --set-variable, or -O */
- if (*cur_arg == 'O')
- {
- my_getopt_error_reporter(WARNING_LEVEL,
- "%s: Option '-O' is deprecated. "
- "Use --variable-name=value instead.",
- my_progname);
- must_be_var= 1;
-
- if (!(*++cur_arg)) /* If not -Ovar=# */
- {
- /* the argument must be in next argv */
- if (!*++pos)
- {
- if (my_getopt_print_errors)
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: Option '-O' requires an argument",
- my_progname);
- return EXIT_ARGUMENT_REQUIRED;
- }
- cur_arg= *pos;
- (*argc)--;
- }
- }
- else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
- {
- my_getopt_error_reporter(WARNING_LEVEL,
- "%s: Option '--set-variable' is deprecated. "
- "Use --variable-name=value instead.",
- my_progname);
-
- must_be_var= 1;
- if (cur_arg[13] == '=')
- {
- cur_arg+= 14;
- if (!*cur_arg)
- {
- if (my_getopt_print_errors)
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: Option '--set-variable' requires an argument",
- my_progname);
- return EXIT_ARGUMENT_REQUIRED;
- }
- }
- else if (cur_arg[14]) /* garbage, or another option. break out */
- must_be_var= 0;
- else
- {
- /* the argument must be in next argv */
- if (!*++pos)
- {
- if (my_getopt_print_errors)
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: Option '--set-variable' requires an argument",
- my_progname);
- return EXIT_ARGUMENT_REQUIRED;
- }
- cur_arg= *pos;
- (*argc)--;
- }
- }
- else if (!must_be_var)
- {
- if (!*++cur_arg) /* skip the double dash */
- {
- /* '--' means end of options, look no further */
- end_of_options= 1;
- (*argc)--;
- continue;
- }
- }
+ if (*cur_arg == '-') /* check for long option, */
+ {
+ if (!*++cur_arg) /* skip the double dash */
+ {
+ /* '--' means end of options, look no further */
+ end_of_options= 1;
+ (*argc)--;
+ continue;
+ }
opt_str= check_struct_option(cur_arg, key_name);
optend= strcend(opt_str, '=');
length= (uint) (optend - opt_str);
@@ -226,7 +233,6 @@ int handle_options(int *argc, char ***argv,
Find first the right option. Return error in case of an ambiguous,
or unknown option
*/
- LINT_INIT(prev_found);
optp= longopts;
if (!(opt_found= findopt(opt_str, length, &optp, &prev_found)))
{
@@ -260,9 +266,9 @@ int handle_options(int *argc, char ***argv,
my_getopt_error_reporter(ERROR_LEVEL,
"%s: ambiguous option '--%s-%s' (--%s-%s)",
my_progname, special_opt_prefix[i],
- cur_arg, special_opt_prefix[i],
+ opt_str, special_opt_prefix[i],
prev_found);
- return EXIT_AMBIGUOUS_OPTION;
+ DBUG_RETURN(EXIT_AMBIGUOUS_OPTION);
}
switch (i) {
case OPT_SKIP:
@@ -272,11 +278,11 @@ int handle_options(int *argc, char ***argv,
for example: --skip-option=0 -> option = TRUE
*/
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
- (char*) "1" : disabled_my_option;
+ enabled_my_option : disabled_my_option;
break;
case OPT_ENABLE:
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
- disabled_my_option : (char*) "1";
+ disabled_my_option : enabled_my_option;
break;
case OPT_MAXIMUM:
set_maximum_value= 1;
@@ -293,12 +299,7 @@ int handle_options(int *argc, char ***argv,
{
if (my_getopt_skip_unknown)
{
- /*
- preserve all the components of this unknown option, this may
- occurr when the user provides options like: "-O foo" or
- "--set-variable foo" (note that theres a space in there)
- Generally, these kind of options are to be avoided
- */
+ /* Preserve all the components of this unknown option. */
do {
(*argv)[argvpos++]= *first++;
} while (first <= pos);
@@ -312,7 +313,7 @@ int handle_options(int *argc, char ***argv,
"%s: unknown variable '%s'",
my_progname, cur_arg);
if (!option_is_loose)
- return EXIT_UNKNOWN_VARIABLE;
+ DBUG_RETURN(EXIT_UNKNOWN_VARIABLE);
}
else
{
@@ -322,7 +323,7 @@ int handle_options(int *argc, char ***argv,
"%s: unknown option '--%s'",
my_progname, cur_arg);
if (!option_is_loose)
- return EXIT_UNKNOWN_OPTION;
+ DBUG_RETURN(EXIT_UNKNOWN_OPTION);
}
if (option_is_loose)
{
@@ -339,7 +340,7 @@ int handle_options(int *argc, char ***argv,
my_getopt_error_reporter(ERROR_LEVEL,
"%s: variable prefix '%s' is not unique",
my_progname, opt_str);
- return EXIT_VAR_PREFIX_NOT_UNIQUE;
+ DBUG_RETURN(EXIT_VAR_PREFIX_NOT_UNIQUE);
}
else
{
@@ -348,7 +349,7 @@ int handle_options(int *argc, char ***argv,
"%s: ambiguous option '--%s' (%s, %s)",
my_progname, opt_str, prev_found,
optp->name);
- return EXIT_AMBIGUOUS_OPTION;
+ DBUG_RETURN(EXIT_AMBIGUOUS_OPTION);
}
}
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
@@ -362,32 +363,29 @@ int handle_options(int *argc, char ***argv,
(*argc)--;
continue;
}
- return EXIT_OPTION_DISABLED;
- }
- if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
- {
- if (my_getopt_print_errors)
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: option '%s' cannot take an argument",
- my_progname, optp->name);
- return EXIT_NO_ARGUMENT_ALLOWED;
+ DBUG_RETURN(EXIT_OPTION_DISABLED);
}
error= 0;
value= optp->var_type & GET_ASK_ADDR ?
(*getopt_get_addr)(key_name, (uint) strlen(key_name), optp, &error) :
optp->value;
if (error)
- return error;
+ DBUG_RETURN(error);
if (optp->arg_type == NO_ARG)
{
+ /*
+ Due to historical reasons GET_BOOL var_types still accepts arguments
+ despite the NO_ARG arg_type attribute. This can seems a bit unintuitive
+ and care should be taken when refactoring this code.
+ */
if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
{
if (my_getopt_print_errors)
my_getopt_error_reporter(ERROR_LEVEL,
"%s: option '--%s' cannot take an argument",
my_progname, optp->name);
- return EXIT_NO_ARGUMENT_ALLOWED;
+ DBUG_RETURN(EXIT_NO_ARGUMENT_ALLOWED);
}
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
{
@@ -395,7 +393,7 @@ int handle_options(int *argc, char ***argv,
Set bool to 1 if no argument or if the user has used
--enable-'option-name'.
*optend was set to '0' if one used --disable-option
- */
+ */
(*argc)--;
if (!optend || *optend == '1' ||
!my_strcasecmp(&my_charset_latin1, optend, "true") ||
@@ -408,43 +406,32 @@ int handle_options(int *argc, char ***argv,
else
{
my_getopt_error_reporter(WARNING_LEVEL,
- "%s: ignoring option '--%s' due to "
- "invalid value '%s'",
+ "%s: ignoring option '--%s' "
+ "due to invalid value '%s'",
my_progname, optp->name, optend);
continue;
}
- if (get_one_option(optp->id, optp,
+ if (get_one_option && get_one_option(optp->id, optp,
*((my_bool*) value) ?
- (char*) "1" : disabled_my_option))
- return EXIT_ARGUMENT_INVALID;
+ enabled_my_option : disabled_my_option))
+ DBUG_RETURN(EXIT_ARGUMENT_INVALID);
continue;
}
argument= optend;
}
- else if (optp->arg_type == OPT_ARG &&
- (((optp->var_type & GET_TYPE_MASK) == GET_BOOL) ||
- (optp->var_type & GET_TYPE_MASK) == GET_ENUM))
- {
- if (optend == disabled_my_option)
- init_one_value(optp, value, 0);
- else
- {
- if (!optend) /* No argument -> enable option */
- init_one_value(optp, value, 1);
- else
- argument= optend;
- }
- }
else if (optp->arg_type == REQUIRED_ARG && !optend)
{
- /* Check if there are more arguments after this one */
- if (!*++pos)
+ /* Check if there are more arguments after this one,
+ Note: options loaded from config file that requires value
+ should always be in the form '--option=value'.
+ */
+ if (!is_cmdline_arg || !*++pos)
{
if (my_getopt_print_errors)
my_getopt_error_reporter(ERROR_LEVEL,
"%s: option '--%s' requires an argument",
my_progname, optp->name);
- return EXIT_ARGUMENT_REQUIRED;
+ DBUG_RETURN(EXIT_ARGUMENT_REQUIRED);
}
argument= *pos;
(*argc)--;
@@ -457,9 +444,9 @@ int handle_options(int *argc, char ***argv,
for (optend= cur_arg; *optend; optend++)
{
opt_found= 0;
- for (optp= longopts; optp->id; optp++)
+ for (optp= longopts; optp->name; optp++)
{
- if (optp->id == (int) (uchar) *optend)
+ if (optp->id && optp->id == (int) (uchar) *optend)
{
/* Option recognized. Find next what to do with it */
opt_found= 1;
@@ -469,14 +456,14 @@ int handle_options(int *argc, char ***argv,
fprintf(stderr,
"%s: ERROR: Option '-%c' used, but is disabled\n",
my_progname, optp->id);
- return EXIT_OPTION_DISABLED;
+ DBUG_RETURN(EXIT_OPTION_DISABLED);
}
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
optp->arg_type == NO_ARG)
{
*((my_bool*) optp->value)= (my_bool) 1;
- if (get_one_option(optp->id, optp, argument))
- return EXIT_UNSPECIFIED_ERROR;
+ if (get_one_option && get_one_option(optp->id, optp, argument))
+ DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
continue;
}
else if (optp->arg_type == REQUIRED_ARG ||
@@ -495,8 +482,8 @@ int handle_options(int *argc, char ***argv,
{
if (optp->var_type == GET_BOOL)
*((my_bool*) optp->value)= (my_bool) 1;
- if (get_one_option(optp->id, optp, argument))
- return EXIT_UNSPECIFIED_ERROR;
+ if (get_one_option && get_one_option(optp->id, optp, argument))
+ DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
continue;
}
/* Check if there are more arguments after this one */
@@ -506,7 +493,7 @@ int handle_options(int *argc, char ***argv,
my_getopt_error_reporter(ERROR_LEVEL,
"%s: option '-%c' requires an argument",
my_progname, optp->id);
- return EXIT_ARGUMENT_REQUIRED;
+ DBUG_RETURN(EXIT_ARGUMENT_REQUIRED);
}
argument= *++pos;
(*argc)--;
@@ -515,40 +502,57 @@ int handle_options(int *argc, char ***argv,
}
if ((error= setval(optp, optp->value, argument,
set_maximum_value)))
- {
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: Error while setting value '%s' to '%s'",
- my_progname, argument, optp->name);
- return error;
- }
- if (get_one_option(optp->id, optp, argument))
- return EXIT_UNSPECIFIED_ERROR;
+ DBUG_RETURN(error);
+ if (get_one_option && get_one_option(optp->id, optp, argument))
+ DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
break;
}
}
if (!opt_found)
{
- if (my_getopt_print_errors)
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: unknown option '-%c'",
- my_progname, *optend);
- return EXIT_UNKNOWN_OPTION;
+ if (my_getopt_skip_unknown)
+ {
+ /*
+ We are currently parsing a single argv[] argument
+ of the form "-XYZ".
+ One or the argument found (say Y) is not an option.
+ Hack the string "-XYZ" to make a "-YZ" substring in it,
+ and push that to the output as an unrecognized parameter.
+ */
+ DBUG_ASSERT(optend > *pos);
+ DBUG_ASSERT(optend >= cur_arg);
+ DBUG_ASSERT(optend <= *pos + strlen(*pos));
+ DBUG_ASSERT(*optend);
+ optend--;
+ optend[0]= '-'; /* replace 'X' or '-' by '-' */
+ (*argv)[argvpos++]= optend;
+ /*
+ Do not continue to parse at the current "-XYZ" argument,
+ skip to the next argv[] argument instead.
+ */
+ optend= (char*) " ";
+ }
+ else
+ {
+ if (my_getopt_print_errors)
+ my_getopt_error_reporter(ERROR_LEVEL,
+ "%s: unknown option '-%c'",
+ my_progname, *optend);
+ DBUG_RETURN(EXIT_UNKNOWN_OPTION);
+ }
}
}
- (*argc)--; /* option handled (short), decrease argument count */
+ if (opt_found)
+ (*argc)--; /* option handled (short), decrease argument count */
continue;
}
- if ((error= setval(optp, value, argument, set_maximum_value)))
- {
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: Error while setting value '%s' to '%s'",
- my_progname, argument, optp->name);
- return error;
- }
- if (get_one_option(optp->id, optp, argument))
- return EXIT_UNSPECIFIED_ERROR;
+ if (((error= setval(optp, value, argument, set_maximum_value))) &&
+ !option_is_loose)
+ DBUG_RETURN(error);
+ if (get_one_option && get_one_option(optp->id, optp, argument))
+ DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
- (*argc)--; /* option handled (short or long), decrease argument count */
+ (*argc)--; /* option handled (long), decrease argument count */
}
else /* non-option found */
(*argv)[argvpos++]= cur_arg;
@@ -560,7 +564,7 @@ int handle_options(int *argc, char ***argv,
to the program, yet to be (possibly) handled.
*/
(*argv)[argvpos]= 0;
- return 0;
+ DBUG_RETURN(0);
}
@@ -581,6 +585,7 @@ int handle_options(int *argc, char ***argv,
static char *check_struct_option(char *cur_arg, char *key_name)
{
char *ptr, *end;
+ DBUG_ENTER("check_struct_option");
ptr= strcend(cur_arg + 1, '.'); /* Skip the first character */
end= strcend(cur_arg, '=');
@@ -597,15 +602,43 @@ static char *check_struct_option(char *cur_arg, char *key_name)
uint len= (uint) (ptr - cur_arg);
set_if_smaller(len, FN_REFLEN-1);
strmake(key_name, cur_arg, len);
- return ++ptr;
+ DBUG_RETURN(++ptr);
}
else
{
key_name[0]= 0;
- return cur_arg;
+ DBUG_RETURN(cur_arg);
}
}
+/**
+ Parse a boolean command line argument
+
+ "ON", "TRUE" and "1" will return true,
+ other values will return false.
+
+ @param[in] argument The value argument
+ @return boolean value
+*/
+static my_bool get_bool_argument(const struct my_option *opts,
+ const char *argument)
+{
+ DBUG_ENTER("get_bool_argument");
+
+ if (!my_strcasecmp(&my_charset_latin1, argument, "true") ||
+ !my_strcasecmp(&my_charset_latin1, argument, "on") ||
+ !my_strcasecmp(&my_charset_latin1, argument, "1"))
+ DBUG_RETURN(1);
+ else if (!my_strcasecmp(&my_charset_latin1, argument, "false") ||
+ !my_strcasecmp(&my_charset_latin1, argument, "off") ||
+ !my_strcasecmp(&my_charset_latin1, argument, "0"))
+ DBUG_RETURN(0);
+ my_getopt_error_reporter(WARNING_LEVEL,
+ "option '%s': boolean value '%s' wasn't recognized. Set to OFF.",
+ opts->name, argument);
+ DBUG_RETURN(0);
+}
+
/*
function: setval
@@ -616,53 +649,64 @@ static char *check_struct_option(char *cur_arg, char *key_name)
static int setval(const struct my_option *opts, void *value, char *argument,
my_bool set_maximum_value)
{
- int err= 0;
+ int err= 0, res= 0;
+ DBUG_ENTER("setval");
- if (value && argument)
- {
- void *result_pos= ((set_maximum_value) ? opts->u_max_value : value);
+ if (!argument)
+ argument= enabled_my_option;
- if (!result_pos)
- return EXIT_NO_PTR_TO_VARIABLE;
+ if (value)
+ {
+ if (set_maximum_value && !(value= opts->u_max_value))
+ {
+ my_getopt_error_reporter(ERROR_LEVEL,
+ "%s: Maximum value of '%s' cannot be set",
+ my_progname, opts->name);
+ DBUG_RETURN(EXIT_NO_PTR_TO_VARIABLE);
+ }
switch ((opts->var_type & GET_TYPE_MASK)) {
case GET_BOOL: /* If argument differs from 0, enable option, else disable */
- *((my_bool*) result_pos)= (my_bool) atoi(argument) != 0;
+ *((my_bool*) value)= get_bool_argument(opts, argument);
break;
case GET_INT:
- *((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
+ *((int*) value)= (int) getopt_ll(argument, opts, &err);
break;
case GET_UINT:
- *((uint*) result_pos)= (uint) getopt_ull(argument, opts, &err);
+ *((uint*) value)= (uint) getopt_ull(argument, opts, &err);
break;
case GET_LONG:
- *((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
+ *((long*) value)= (long) getopt_ll(argument, opts, &err);
break;
case GET_ULONG:
- *((long*) result_pos)= (long) getopt_ull(argument, opts, &err);
+ *((long*) value)= (long) getopt_ull(argument, opts, &err);
break;
case GET_LL:
- *((longlong*) result_pos)= getopt_ll(argument, opts, &err);
+ *((longlong*) value)= getopt_ll(argument, opts, &err);
break;
case GET_ULL:
- *((ulonglong*) result_pos)= getopt_ull(argument, opts, &err);
+ *((ulonglong*) value)= getopt_ull(argument, opts, &err);
break;
case GET_DOUBLE:
- *((double*) result_pos)= getopt_double(argument, opts, &err);
+ *((double*) value)= getopt_double(argument, opts, &err);
break;
case GET_STR:
- *((char**) result_pos)= argument;
+ /* If no argument or --enable-string-option, set string to "" */
+ *((char**) value)= argument == enabled_my_option ? (char*) "" : argument;
break;
case GET_STR_ALLOC:
- if ((*((char**) result_pos)))
- my_free((*(char**) result_pos), MYF(MY_WME | MY_FAE));
- if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME))))
- return EXIT_OUT_OF_MEMORY;
+ my_free(*((char**) value));
+ if (!(*((char**) value)= my_strdup(argument == enabled_my_option ? "" :
+ argument, MYF(MY_WME))))
+ {
+ res= EXIT_OUT_OF_MEMORY;
+ goto ret;
+ };
break;
case GET_ENUM:
{
- int type= find_type(argument, opts->typelib, 2);
- if (type < 1)
+ int type= find_type(argument, opts->typelib, FIND_TYPE_BASIC);
+ if (type == 0)
{
/*
Accept an integer representation of the enumerated item.
@@ -670,25 +714,71 @@ static int setval(const struct my_option *opts, void *value, char *argument,
char *endptr;
ulong arg= strtoul(argument, &endptr, 10);
if (*endptr || arg >= opts->typelib->count)
- return EXIT_ARGUMENT_INVALID;
- *((ulong*) result_pos)= arg;
+ {
+ res= EXIT_ARGUMENT_INVALID;
+ goto ret;
+ }
+ *(ulong*)value= arg;
+ }
+ else if (type < 0)
+ {
+ res= EXIT_AMBIGUOUS_OPTION;
+ goto ret;
}
else
- *((ulong*) result_pos)= type - 1;
+ *(ulong*)value= type - 1;
}
break;
case GET_SET:
- *((ulonglong*)result_pos)= find_typeset(argument, opts->typelib, &err);
+ *((ulonglong*)value)= find_typeset(argument, opts->typelib, &err);
if (err)
- return EXIT_ARGUMENT_INVALID;
+ {
+ /* Accept an integer representation of the set */
+ char *endptr;
+ ulonglong arg= (ulonglong) strtol(argument, &endptr, 10);
+ if (*endptr || (arg >> 1) >= (1ULL << (opts->typelib->count-1)))
+ {
+ res= EXIT_ARGUMENT_INVALID;
+ goto ret;
+ };
+ *(ulonglong*)value= arg;
+ err= 0;
+ }
+ break;
+ case GET_FLAGSET:
+ {
+ char *error;
+ uint error_len;
+
+ *((ulonglong*)value)=
+ find_set_from_flags(opts->typelib, opts->typelib->count,
+ *(ulonglong *)value, opts->def_value,
+ argument, strlen(argument),
+ &error, &error_len);
+ if (error)
+ {
+ res= EXIT_ARGUMENT_INVALID;
+ goto ret;
+ };
+ }
break;
- default: /* dummy default to avoid compiler warnings */
+ case GET_NO_ARG: /* get_one_option has taken care of the value already */
+ default: /* dummy default to avoid compiler warnings */
break;
}
if (err)
- return EXIT_UNKNOWN_SUFFIX;
+ {
+ res= EXIT_UNKNOWN_SUFFIX;
+ goto ret;
+ };
}
- return 0;
+ DBUG_RETURN(0);
+
+ret:
+ my_getopt_error_reporter(ERROR_LEVEL,
+ "%s: Error while setting value '%s' to '%s'",
+ my_progname, argument, opts->name);
+ DBUG_RETURN(res);
}
@@ -720,6 +810,7 @@ static int findopt(char *optpat, uint length,
{
uint count;
const struct my_option *opt= *opt_res;
+ DBUG_ENTER("findopt");
for (count= 0; opt->name; opt++)
{
@@ -727,7 +818,7 @@ static int findopt(char *optpat, uint length,
{
(*opt_res)= opt;
if (!opt->name[length]) /* Exact match */
- return 1;
+ DBUG_RETURN(1);
if (!count)
{
/* We only need to know one prev */
@@ -744,7 +835,7 @@ static int findopt(char *optpat, uint length,
}
}
}
- return count;
+ DBUG_RETURN(count);
}
@@ -759,12 +850,14 @@ my_bool getopt_compare_strings(register const char *s, register const char *t,
uint length)
{
char const *end= s + length;
+ DBUG_ENTER("getopt_compare_strings");
+
for (;s != end ; s++, t++)
{
if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
- return 1;
+ DBUG_RETURN(1);
}
- return 0;
+ DBUG_RETURN(0);
}
/*
@@ -778,6 +871,8 @@ static longlong eval_num_suffix(char *argument, int *error, char *option_name)
{
char *endchar;
longlong num;
+ DBUG_ENTER("eval_num_suffix");
+
*error= 0;
errno= 0;
@@ -787,7 +882,7 @@ static longlong eval_num_suffix(char *argument, int *error, char *option_name)
my_getopt_error_reporter(ERROR_LEVEL,
"Incorrect integer value: '%s'", argument);
*error= 1;
- return 0;
+ DBUG_RETURN(0);
}
if (*endchar == 'k' || *endchar == 'K')
num*= 1024L;
@@ -801,9 +896,9 @@ static longlong eval_num_suffix(char *argument, int *error, char *option_name)
"Unknown suffix '%c' used for variable '%s' (value '%s')\n",
*endchar, option_name, argument);
*error= 1;
- return 0;
+ DBUG_RETURN(0);
}
- return num;
+ DBUG_RETURN(num);
}
/*
@@ -837,6 +932,7 @@ longlong getopt_ll_limit_value(longlong num, const struct my_option *optp,
my_bool adjusted= FALSE;
char buf1[255], buf2[255];
ulonglong block_size= (optp->block_size ? (ulonglong) optp->block_size : 1L);
+ DBUG_ENTER("getopt_ll_limit_value");
if (num > 0 && ((ulonglong) num > (ulonglong) optp->max_value) &&
optp->max_value) /* if max value is not set -> no upper limit */
@@ -867,7 +963,7 @@ longlong getopt_ll_limit_value(longlong num, const struct my_option *optp,
break;
}
- num= ((num - optp->sub_size) / block_size);
+ num= (num / block_size);
num= (longlong) (num * block_size);
if (num < optp->min_value)
@@ -878,12 +974,12 @@ longlong getopt_ll_limit_value(longlong num, const struct my_option *optp,
}
if (fix)
- *fix= adjusted;
+ *fix= old != num;
else if (adjusted)
my_getopt_error_reporter(WARNING_LEVEL,
"option '%s': signed value %s adjusted to %s",
optp->name, llstr(old, buf1), llstr(num, buf2));
- return num;
+ DBUG_RETURN(num);
}
/*
@@ -906,6 +1002,7 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp,
my_bool adjusted= FALSE;
ulonglong old= num;
char buf1[255], buf2[255];
+ DBUG_ENTER("getopt_ull_limit_value");
if ((ulonglong) num > (ulonglong) optp->max_value &&
optp->max_value) /* if max value is not set -> no upper limit */
@@ -950,14 +1047,40 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp,
}
if (fix)
- *fix= adjusted;
+ *fix= old != num;
else if (adjusted)
my_getopt_error_reporter(WARNING_LEVEL,
"option '%s': unsigned value %s adjusted to %s",
optp->name, ullstr(old, buf1), ullstr(num, buf2));
- return num;
+
+ DBUG_RETURN(num);
}
+double getopt_double_limit_value(double num, const struct my_option *optp,
+ my_bool *fix)
+{
+ my_bool adjusted= FALSE;
+ double old= num;
+ DBUG_ENTER("getopt_double_limit_value");
+
+ if (optp->max_value && num > (double) optp->max_value)
+ {
+ num= (double) optp->max_value;
+ adjusted= TRUE;
+ }
+ if (num < (double) optp->min_value)
+ {
+ num= (double) optp->min_value;
+ adjusted= TRUE;
+ }
+ if (fix)
+ *fix= adjusted;
+ else if (adjusted)
+ my_getopt_error_reporter(WARNING_LEVEL,
+ "option '%s': value %g adjusted to %g",
+ optp->name, old, num);
+ DBUG_RETURN(num);
+}
/*
Get double value withing ranges
@@ -979,15 +1102,12 @@ static double getopt_double(char *arg, const struct my_option *optp, int *err)
num= my_strtod(arg, &end, &error);
if (end[0] != 0 || error)
{
- fprintf(stderr,
- "%s: ERROR: Invalid decimal value for option '%s'\n",
- my_progname, optp->name);
+ my_getopt_error_reporter(ERROR_LEVEL,
+ "Invalid decimal value for option '%s'\n", optp->name);
*err= EXIT_ARGUMENT_INVALID;
return 0.0;
}
- if (optp->max_value && num > (double) optp->max_value)
- num= (double) optp->max_value;
- return max(num, (double) optp->min_value);
+ return getopt_double_limit_value(num, optp, NULL);
}
/*
@@ -1029,10 +1149,11 @@ static void init_one_value(const struct my_option *option, void *variable,
*((ulonglong*) variable)= (ulonglong) getopt_ull_limit_value((ulonglong) value, option, NULL);
break;
case GET_SET:
+ case GET_FLAGSET:
*((ulonglong*) variable)= (ulonglong) value;
break;
case GET_DOUBLE:
- *((double*) variable)= (double) value;
+ *((double*) variable)= ulonglong2double(value);
break;
case GET_STR:
/*
@@ -1053,8 +1174,9 @@ static void init_one_value(const struct my_option *option, void *variable,
*/
if ((char*) (intptr) value)
{
- my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
- *((char**) variable)= my_strdup((char*) (intptr) value, MYF(MY_WME));
+ char **pstr= (char **) variable;
+ my_free(*pstr);
+ *pstr= my_strdup((char*) (intptr) value, MYF(MY_WME));
}
break;
default: /* dummy default to avoid compiler warnings */
@@ -1079,7 +1201,7 @@ static void fini_one_value(const struct my_option *option, void *variable,
DBUG_ENTER("fini_one_value");
switch ((option->var_type & GET_TYPE_MASK)) {
case GET_STR_ALLOC:
- my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
+ my_free(*((char**) variable));
*((char**) variable)= NULL;
break;
default: /* dummy default to avoid compiler warnings */
@@ -1091,7 +1213,9 @@ static void fini_one_value(const struct my_option *option, void *variable,
void my_cleanup_options(const struct my_option *options)
{
+ DBUG_ENTER("my_cleanup_options");
init_variables(options, fini_one_value);
+ DBUG_VOID_RETURN;
}
@@ -1104,7 +1228,7 @@ void my_cleanup_options(const struct my_option *options)
NOTES
We will initialize the value that is pointed to by options->value.
- If the value is of type GET_ASK_ADDR, we will also ask for the address
+ If the value is of type GET_ASK_ADDR, we will ask for the address
for a value and initialize.
*/
@@ -1114,7 +1238,7 @@ static void init_variables(const struct my_option *options,
DBUG_ENTER("init_variables");
for (; options->name; options++)
{
- void *variable;
+ void *value;
DBUG_PRINT("options", ("name: '%s'", options->name));
/*
We must set u_max_value first as for some variables
@@ -1123,15 +1247,23 @@ static void init_variables(const struct my_option *options,
*/
if (options->u_max_value)
init_one_value(options, options->u_max_value, options->max_value);
- if (options->value)
- init_one_value(options, options->value, options->def_value);
- if (options->var_type & GET_ASK_ADDR &&
- (variable= (*getopt_get_addr)("", 0, options, 0)))
- init_one_value(options, variable, options->def_value);
+ value= (options->var_type & GET_ASK_ADDR ?
+ (*getopt_get_addr)("", 0, options, 0) : options->value);
+ if (value)
+ init_one_value(options, value, options->def_value);
}
DBUG_VOID_RETURN;
}
+/** Prints variable or option name, replacing _ with - */
+static uint print_name(const struct my_option *optp)
+{
+ const char *s= optp->name;
+
+ for (;*s;s++)
+ putchar(*s == '_' ? '-' : *s);
+ return s - optp->name;
+}
/*
function: my_print_options
@@ -1139,17 +1271,16 @@ static void init_variables(const struct my_option *options,
Print help for all options and variables.
*/
-#include <help_start.h>
-
void my_print_help(const struct my_option *options)
{
uint col, name_space= 22, comment_space= 57;
const char *line_end;
const struct my_option *optp;
+ DBUG_ENTER("my_print_help");
- for (optp= options; optp->id; optp++)
+ for (optp= options; optp->name; optp++)
{
- if (optp->id < 256)
+ if (optp->id && optp->id < 256)
{
printf(" -%c%s", optp->id, strlen(optp->name) ? ", " : " ");
col= 6;
@@ -1161,21 +1292,24 @@ void my_print_help(const struct my_option *options)
}
if (strlen(optp->name))
{
- printf("--%s", optp->name);
- col+= 2 + (uint) strlen(optp->name);
- if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
- (optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
+ printf("--");
+ col+= 2 + print_name(optp);
+ if (optp->arg_type == NO_ARG ||
+ (optp->var_type & GET_TYPE_MASK) == GET_BOOL)
+ {
+ putchar(' ');
+ col++;
+ }
+ else if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
+ (optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC ||
+ (optp->var_type & GET_TYPE_MASK) == GET_ENUM ||
+ (optp->var_type & GET_TYPE_MASK) == GET_SET ||
+ (optp->var_type & GET_TYPE_MASK) == GET_FLAGSET )
{
printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
optp->arg_type == OPT_ARG ? "]" : "");
col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
}
- else if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
- (optp->var_type & GET_TYPE_MASK) == GET_BOOL)
- {
- putchar(' ');
- col++;
- }
else
{
printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
@@ -1207,7 +1341,17 @@ void my_print_help(const struct my_option *options)
printf("%s", comment);
}
putchar('\n');
+ if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
+ {
+ if (optp->def_value != 0)
+ {
+ printf("%*s(Defaults to on; use --skip-", name_space, "");
+ print_name(optp);
+ printf(" to disable.)\n");
+ }
+ }
}
+ DBUG_VOID_RETURN;
}
@@ -1220,35 +1364,53 @@ void my_print_help(const struct my_option *options)
void my_print_variables(const struct my_option *options)
{
uint name_space= 34, length, nr;
- ulonglong bit, llvalue;
+ ulonglong llvalue;
char buff[255];
const struct my_option *optp;
+ DBUG_ENTER("my_print_variables");
+
+ for (optp= options; optp->name; optp++)
+ {
+ length= strlen(optp->name)+1;
+ if (length > name_space)
+ name_space= length;
+ }
printf("\nVariables (--variable-name=value)\n");
- printf("and boolean options {FALSE|TRUE} Value (after reading options)\n");
- printf("--------------------------------- -----------------------------\n");
- for (optp= options; optp->id; optp++)
+ printf("%-*s%s", name_space, "and boolean options {FALSE|TRUE}",
+ "Value (after reading options)\n");
+ for (length=1; length < 75; length++)
+ putchar(length == name_space ? ' ' : '-');
+ putchar('\n');
+
+ for (optp= options; optp->name; optp++)
{
void *value= (optp->var_type & GET_ASK_ADDR ?
(*getopt_get_addr)("", 0, optp, 0) : optp->value);
if (value)
{
- printf("%s ", optp->name);
- length= (uint) strlen(optp->name)+1;
+ length= print_name(optp);
for (; length < name_space; length++)
putchar(' ');
switch ((optp->var_type & GET_TYPE_MASK)) {
case GET_SET:
if (!(llvalue= *(ulonglong*) value))
- printf("%s\n", "(No default value)");
+ printf("%s\n", "");
else
- for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
+ for (nr= 0; llvalue && nr < optp->typelib->count; nr++, llvalue >>=1)
{
- if (!(bit & llvalue))
- continue;
- llvalue&= ~bit;
- printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
+ if (llvalue & 1)
+ printf( llvalue > 1 ? "%s," : "%s\n", get_type(optp->typelib, nr));
+ }
+ break;
+ case GET_FLAGSET:
+ llvalue= *(ulonglong*) value;
+ for (nr= 0; llvalue && nr < optp->typelib->count; nr++, llvalue >>=1)
+ {
+ printf("%s%s=", (nr ? "," : ""), get_type(optp->typelib, nr));
+ printf(llvalue & 1 ? "on" : "off");
}
+ printf("\n");
break;
case GET_ENUM:
printf("%s\n", get_type(optp->typelib, *(ulong*) value));
@@ -1283,12 +1445,14 @@ void my_print_variables(const struct my_option *options)
case GET_DOUBLE:
printf("%g\n", *(double*) value);
break;
+ case GET_NO_ARG:
+ printf("(No default value)\n");
+ break;
default:
printf("(Disabled)\n");
break;
}
}
}
+ DBUG_VOID_RETURN;
}
-
-#include <help_end.h>
diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c
index 8a3e97cffa7..2a23a699f69 100644
--- a/mysys/my_getsystime.c
+++ b/mysys/my_getsystime.c
@@ -18,9 +18,7 @@
#include "mysys_priv.h"
#include "my_static.h"
-#ifdef __NETWARE__
-#include <nks/time.h>
-#elif defined(__WIN__)
+#ifdef __WIN__
#define OFFSET_TO_EPOC 116444736000000000LL
static ulonglong query_performance_frequency;
#endif
@@ -70,10 +68,6 @@ ulonglong my_interval_timer()
GetSystemTimeAsFileTime((FILETIME*)&newtime);
return newtime*100ULL;
}
-#elif defined(__NETWARE__)
- NXTime_t tm;
- NXGetTime(NX_SINCE_1970, NX_NSECONDS, &tm);
- return (ulonglong)tm;
#else
/* TODO: check for other possibilities for hi-res timestamping */
struct timeval tv;
@@ -134,7 +128,6 @@ ulonglong my_getcputime()
if (syscall(__NR_clock_gettime, CLOCK_THREAD_CPUTIME_ID, &tp))
return 0;
return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100;
-#else
+#endif /* CLOCK_THREAD_CPUTIME_ID */
return 0;
-#endif /* HAVE_CLOCK_GETTIME */
}
diff --git a/mysys/my_getwd.c b/mysys/my_getwd.c
index a0a1dbe5b60..444ed4273b5 100644
--- a/mysys/my_getwd.c
+++ b/mysys/my_getwd.c
@@ -12,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* my_setwd() and my_getwd() works with intern_filenames !! */
@@ -56,7 +55,7 @@ int my_getwd(char * buf, size_t size, myf MyFlags)
DBUG_RETURN(-1);
if (curr_dir[0]) /* Current pos is saved here */
- VOID(strmake(buf,&curr_dir[0],size-1));
+ (void) strmake(buf,&curr_dir[0],size-1);
else
{
#if defined(HAVE_GETCWD)
@@ -74,16 +73,6 @@ int my_getwd(char * buf, size_t size, myf MyFlags)
getwd(pathname);
strmake(buf,pathname,size-1);
}
-#elif defined(VMS)
- if (size < 2)
- DBUG_RETURN(-1);
- if (!getcwd(buf,size-2,1) && MyFlags & MY_WME)
- {
- my_errno=errno;
- my_error(EE_GETWD,MYF(ME_BELL+ME_WAITTANG),errno);
- DBUG_RETURN(-1);
- }
- intern_filename(buf,buf);
#else
#error "No way to get current directory"
#endif
@@ -105,27 +94,12 @@ int my_setwd(const char *dir, myf MyFlags)
int res;
size_t length;
char *start, *pos;
-#if defined(VMS)
- char buff[FN_REFLEN];
-#endif
DBUG_ENTER("my_setwd");
DBUG_PRINT("my",("dir: '%s' MyFlags %d", dir, MyFlags));
start=(char *) dir;
if (! dir[0] || (dir[0] == FN_LIBCHAR && dir[1] == 0))
dir=FN_ROOTDIR;
-#ifdef VMS
- {
- pos=strmov(buff,dir);
- if (pos[-1] != FN_LIBCHAR)
- {
- pos[0]=FN_LIBCHAR; /* Mark as directory */
- pos[1]=0;
- }
- system_filename(buff,buff); /* Change to VMS format */
- dir=buff;
- }
-#endif /* VMS */
if ((res=chdir((char*) dir)) != 0)
{
my_errno=errno;
diff --git a/mysys/my_handler_errors.h b/mysys/my_handler_errors.h
index 92d9266ae73..8b3b359ea95 100644
--- a/mysys/my_handler_errors.h
+++ b/mysys/my_handler_errors.h
@@ -1,5 +1,7 @@
-/* Copyright (c) 2008 MySQL AB
- Use is subject to license terms.
+#ifndef MYSYS_MY_HANDLER_ERRORS_INCLUDED
+#define MYSYS_MY_HANDLER_ERRORS_INCLUDED
+
+/* Copyright (c) 2008, 2012, Oracle and/or its affiliates.
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
@@ -11,8 +13,8 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
/*
Errors a handler can give you
@@ -63,8 +65,7 @@ static const char *handler_error_messages[]=
"There's no partition in table for the given value",
"Row-based binary logging of row failed",
"Index needed in foreign key constraint",
- "Upholding foreign key constraints would lead to a duplicate key error in "
- "some other table",
+ "Upholding foreign key constraints would lead to a duplicate key error in some other table",
"Table needs to be upgraded before it can be used",
"Table is read only",
"Failed to get next auto increment value",
@@ -79,8 +80,13 @@ static const char *handler_error_messages[]=
"File too short; Expected more data in file",
"Read page with wrong checksum",
"Too many active concurrent transactions",
- "Operation was interrupted by end user (probably kill command?)",
- "Disk full",
+ "Index column length exceeds limit",
+ "Index corrupted",
+ "Undo record too big",
+ "Table is being used in foreign key check",
"Row is not visible by the current transaction",
- "Table is being used in foreign key check" /* HA_ERR_TABLE_IN_FK_CHECK */
+ "Operation was interrupted by end user (probably kill command?)",
+ "Disk full"
};
+
+#endif /* MYSYS_MY_HANDLER_ERRORS_INCLUDED */
diff --git a/mysys/my_init.c b/mysys/my_init.c
index 89ac2f322cf..193c8281577 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates
+ Copyright (c) 2000, 2012, Oracle and/or its affiliates
+ Copyright (c) 2009, 2011, Monty Program 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
@@ -12,8 +13,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "my_static.h"
@@ -21,14 +21,12 @@
#include <m_string.h>
#include <m_ctype.h>
#include <signal.h>
-#ifdef VMS
-#include <my_static.c>
-#include <m_ctype.h>
-#endif
#ifdef __WIN__
#ifdef _MSC_VER
#include <locale.h>
#include <crtdbg.h>
+/* WSAStartup needs winsock library*/
+#pragma comment(lib, "ws2_32")
#endif
my_bool have_tcpip=0;
static void my_win_init(void);
@@ -36,16 +34,16 @@ static my_bool win32_init_tcp_ip();
#else
#define my_win_init()
#endif
-#ifdef __NETWARE__
-static void netware_init();
-#else
-#define netware_init()
-#endif
+
+extern pthread_key(struct st_my_thread_var*, THR_KEY_mysys);
+
+#define SCALE_SEC 100
+#define SCALE_USEC 10000
my_bool my_init_done= 0;
uint mysys_usage_id= 0; /* Incremented for each my_init() */
-ulong my_thread_stack_size= (sizeof(void*) <= 4)? 65536: ((256-16)*1024);
+ulonglong my_thread_stack_size= (sizeof(void*) <= 4)? 65536: ((256-16)*1024);
static ulong atoi_octal(const char *str)
{
@@ -58,71 +56,64 @@ static ulong atoi_octal(const char *str)
return (ulong) tmp;
}
+MYSQL_FILE *mysql_stdin= NULL;
+static MYSQL_FILE instrumented_stdin;
-/*
- Init my_sys functions and my_sys variabels
- SYNOPSIS
- my_init()
+/**
+ Initialize my_sys functions, resources and variables
- RETURN
- 0 ok
- 1 Couldn't initialize environment
+ @return Initialization result
+ @retval 0 Success
+ @retval 1 Error. Couldn't initialize environment
*/
-
my_bool my_init(void)
{
- char * str;
+ char *str;
+
if (my_init_done)
return 0;
- my_init_done=1;
+
+ my_init_done= 1;
+
mysys_usage_id++;
my_umask= 0660; /* Default umask for new files */
my_umask_dir= 0700; /* Default umask for new directories */
my_global_flags= 0;
+ /* Default creation of new files */
+ if ((str= getenv("UMASK")) != 0)
+ my_umask= (int) (atoi_octal(str) | 0600);
+ /* Default creation of new dir's */
+ if ((str= getenv("UMASK_DIR")) != 0)
+ my_umask_dir= (int) (atoi_octal(str) | 0700);
+
init_glob_errs();
+
+ instrumented_stdin.m_file= stdin;
+ instrumented_stdin.m_psi= NULL; /* not yet instrumented */
+ mysql_stdin= & instrumented_stdin;
+
my_progname_short= "unknown";
if (my_progname)
my_progname_short= my_progname + dirname_length(my_progname);
- /* first initialize systems and global libraries */
- netware_init();
-#ifdef THREAD
-#if defined(HAVE_PTHREAD_INIT)
- pthread_init(); /* Must be called before DBUG_ENTER */
-#endif
/* Initalize our mutex handling */
my_mutex_init();
- /* Initialize mysys global variables and global mutex */
+
if (my_thread_global_init())
return 1;
-#if !defined( __WIN__) && !defined(__NETWARE__)
- sigfillset(&my_signals); /* signals blocked by mf_brkhant */
-#endif
-#endif /* THREAD */
+
+ /* $HOME is needed early to parse configuration files located in ~/ */
+ if ((home_dir= getenv("HOME")) != 0)
+ home_dir= intern_filename(home_dir_buff, home_dir);
+
{
DBUG_ENTER("my_init");
DBUG_PROCESS((char*) (my_progname ? my_progname : "unknown"));
- if (!home_dir)
- { /* Don't initialize twice */
- my_time_init();
- my_win_init();
- if ((home_dir=getenv("HOME")) != 0)
- home_dir=intern_filename(home_dir_buff,home_dir);
-#ifndef VMS
- /* Default creation of new files */
- if ((str=getenv("UMASK")) != 0)
- my_umask=(int) (atoi_octal(str) | 0600);
- /* Default creation of new dir's */
- if ((str=getenv("UMASK_DIR")) != 0)
- my_umask_dir=(int) (atoi_octal(str) | 0700);
-#endif
-#ifdef VMS
- init_ctype(); /* Stupid linker don't link _ctype.c */
-#endif
- DBUG_PRINT("exit",("home: '%s'",home_dir));
- }
+ my_time_init();
+ my_win_init();
+ DBUG_PRINT("exit", ("home: '%s'", home_dir));
#ifdef __WIN__
win32_init_tcp_ip();
#endif
@@ -166,7 +157,7 @@ void my_end(int infoflag)
char ebuff[512];
my_snprintf(ebuff, sizeof(ebuff), EE(EE_OPEN_WARNING),
my_file_opened, my_stream_opened);
- my_message_no_curses(EE_OPEN_WARNING, ebuff, ME_BELL);
+ my_message_stderr(EE_OPEN_WARNING, ebuff, ME_BELL);
DBUG_PRINT("error", ("%s", ebuff));
my_print_open_files();
}
@@ -174,9 +165,6 @@ void my_end(int infoflag)
free_charsets();
my_error_unregister_all();
my_once_free();
-#ifdef THREAD
- my_thread_destroy_mutex();
-#endif
if ((infoflag & MY_GIVE_INFO) || print_info)
{
@@ -203,16 +191,7 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
rus.ru_msgsnd, rus.ru_msgrcv, rus.ru_nsignals,
rus.ru_nvcsw, rus.ru_nivcsw);
#endif
-#if defined(__NETWARE__) && !defined(__WIN__)
- fprintf(info_file,"\nRun time: %.1f\n",(double) clock()/CLOCKS_PER_SEC);
-#endif
-#if defined(SAFEMALLOC)
- /* Wait for other threads to free mysys_var */
-#ifdef THREAD
- (void) my_wait_for_other_threads_to_die(1);
-#endif
- TERMINATE(stderr, (infoflag & MY_GIVE_INFO) != 0);
-#elif defined(__WIN__) && defined(_MSC_VER)
+#if defined(__WIN__) && defined(_MSC_VER)
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
@@ -223,18 +202,13 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
_CrtDumpMemoryLeaks();
#endif
}
- else if (infoflag & MY_CHECK_ERROR)
- {
- TERMINATE(stderr, 0); /* Print memory leaks on screen */
- }
- if (!(infoflag & MY_DONT_FREE_DBUG))
- {
- DBUG_END(); /* Must be done before my_thread_end */
- }
-#ifdef THREAD
my_thread_end();
my_thread_global_end();
+
+ if (!(infoflag & MY_DONT_FREE_DBUG))
+ DBUG_END(); /* Must be done as late as possible */
+
my_mutex_end();
#if defined(SAFE_MUTEX)
/*
@@ -244,12 +218,14 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
safe_mutex_end((infoflag & (MY_GIVE_INFO | MY_CHECK_ERROR)) ? stderr :
(FILE *) 0);
#endif /* defined(SAFE_MUTEX) */
-#endif /* THREAD */
#ifdef __WIN__
if (have_tcpip)
WSACleanup();
#endif /* __WIN__ */
+
+ /* At very last, delete mysys key, it is used everywhere including DBUG */
+ pthread_key_delete(THR_KEY_mysys);
my_init_done=0;
} /* my_end */
@@ -263,6 +239,7 @@ void my_debug_put_break_here(void)
#ifdef __WIN__
+
/*
my_parameter_handler
@@ -304,11 +281,66 @@ int handle_rtc_failure(int err_type, const char *file, int line,
va_end(args);
(void) fflush(stderr);
__debugbreak();
+
return 0; /* Error is handled */
}
#pragma runtime_checks("", restore)
#endif
+/*
+ Open HKEY_LOCAL_MACHINE\SOFTWARE\MySQL and set any strings found
+ there as environment variables
+*/
+static void win_init_registry(void)
+{
+ HKEY key_handle;
+
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)"SOFTWARE\\MySQL",
+ 0, KEY_READ, &key_handle) == ERROR_SUCCESS)
+ {
+ LONG ret;
+ DWORD index= 0;
+ DWORD type;
+ char key_name[256], key_data[1024];
+ DWORD key_name_len= sizeof(key_name) - 1;
+ DWORD key_data_len= sizeof(key_data) - 1;
+
+ while ((ret= RegEnumValue(key_handle, index++,
+ key_name, &key_name_len,
+ NULL, &type, (LPBYTE)&key_data,
+ &key_data_len)) != ERROR_NO_MORE_ITEMS)
+ {
+ char env_string[sizeof(key_name) + sizeof(key_data) + 2];
+
+ if (ret == ERROR_MORE_DATA)
+ {
+ /* Registry value larger than 'key_data', skip it */
+ DBUG_PRINT("error", ("Skipped registry value that was too large"));
+ }
+ else if (ret == ERROR_SUCCESS)
+ {
+ if (type == REG_SZ)
+ {
+ strxmov(env_string, key_name, "=", key_data, NullS);
+
+ /* variable for putenv must be allocated ! */
+ putenv(strdup(env_string)) ;
+ }
+ }
+ else
+ {
+ /* Unhandled error, break out of loop */
+ break;
+ }
+
+ key_name_len= sizeof(key_name) - 1;
+ key_data_len= sizeof(key_data) - 1;
+ }
+
+ RegCloseKey(key_handle);
+ }
+}
+
static void my_win_init(void)
{
@@ -316,17 +348,18 @@ static void my_win_init(void)
#if defined(_MSC_VER)
#if _MSC_VER < 1300
- /*
+ /*
Clear the OS system variable TZ and avoid the 100% CPU usage
Only for old versions of Visual C++
*/
- _putenv( "TZ=" );
-#endif
+ _putenv("TZ=");
+#endif
#if _MSC_VER >= 1400
/* this is required to make crt functions return -1 appropriately */
_set_invalid_parameter_handler(my_parameter_handler);
#endif
-#endif
+#endif
+
#ifdef __MSVC_RUNTIME_CHECKS
/*
Install handler to send RTC (Runtime Error Check) warnings
@@ -337,58 +370,9 @@ static void my_win_init(void)
_tzset();
- {
- /*
- Open HKEY_LOCAL_MACHINE\SOFTWARE\MySQL and set any strings found
- there as environment variables
- */
- HKEY key_handle;
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)"SOFTWARE\\MySQL",
- 0, KEY_READ, &key_handle) == ERROR_SUCCESS)
- {
- LONG ret;
- DWORD index= 0;
- DWORD type;
- char key_name[256], key_data[1024];
- DWORD key_name_len= sizeof(key_name) - 1;
- DWORD key_data_len= sizeof(key_data) - 1;
-
- while ((ret= RegEnumValue(key_handle, index++,
- key_name, &key_name_len,
- NULL, &type, (LPBYTE)&key_data,
- &key_data_len)) != ERROR_NO_MORE_ITEMS)
- {
- char env_string[sizeof(key_name) + sizeof(key_data) + 2];
+ win_init_registry();
- if (ret == ERROR_MORE_DATA)
- {
- /* Registry value larger than 'key_data', skip it */
- DBUG_PRINT("error", ("Skipped registry value that was too large"));
- }
- else if (ret == ERROR_SUCCESS)
- {
- if (type == REG_SZ)
- {
- strxmov(env_string, key_name, "=", key_data, NullS);
-
- /* variable for putenv must be allocated ! */
- putenv(strdup(env_string)) ;
- }
- }
- else
- {
- /* Unhandled error, break out of loop */
- break;
- }
-
- key_name_len= sizeof(key_name) - 1;
- key_data_len= sizeof(key_data) - 1;
- }
-
- RegCloseKey(key_handle) ;
- }
- }
- DBUG_VOID_RETURN ;
+ DBUG_VOID_RETURN;
}
@@ -427,7 +411,7 @@ static my_bool win32_init_tcp_ip()
{
if (win32_have_tcpip())
{
- WORD wVersionRequested = MAKEWORD( 2, 0 );
+ WORD wVersionRequested = MAKEWORD( 2, 2 );
WSADATA wsaData;
/* Be a good citizen: maybe another lib has already initialised
sockets, so dont clobber them unless necessary */
@@ -456,56 +440,121 @@ static my_bool win32_init_tcp_ip()
}
#endif /* __WIN__ */
+#ifdef HAVE_PSI_INTERFACE
-#ifdef __NETWARE__
-/*
- Basic initialisation for netware
-*/
+#if !defined(HAVE_PREAD) && !defined(_WIN32)
+PSI_mutex_key key_my_file_info_mutex;
+#endif /* !defined(HAVE_PREAD) && !defined(_WIN32) */
+
+#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
+PSI_mutex_key key_LOCK_localtime_r;
+#endif /* !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_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_my_thread_var_mutex, key_THR_LOCK_charset, key_THR_LOCK_heap,
+ key_THR_LOCK_isam, 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_TMPDIR_mutex, key_THR_LOCK_myisam_mmap, key_LOCK_uuid_generator;
-static void netware_init()
+static PSI_mutex_info all_mysys_mutexes[]=
{
- char cwd[PATH_MAX], *name;
+#if !defined(HAVE_PREAD) && !defined(_WIN32)
+ { &key_my_file_info_mutex, "st_my_file_info:mutex", 0},
+#endif /* !defined(HAVE_PREAD) && !defined(_WIN32) */
+#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
+ { &key_LOCK_localtime_r, "LOCK_localtime_r", PSI_FLAG_GLOBAL},
+#endif /* !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) */
+ { &key_BITMAP_mutex, "BITMAP::mutex", 0},
+ { &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_my_thread_var_mutex, "my_thread_var::mutex", 0},
+ { &key_THR_LOCK_charset, "THR_LOCK_charset", PSI_FLAG_GLOBAL},
+ { &key_THR_LOCK_heap, "THR_LOCK_heap", PSI_FLAG_GLOBAL},
+ { &key_THR_LOCK_isam, "THR_LOCK_isam", PSI_FLAG_GLOBAL},
+ { &key_THR_LOCK_lock, "THR_LOCK_lock", PSI_FLAG_GLOBAL},
+ { &key_THR_LOCK_malloc, "THR_LOCK_malloc", PSI_FLAG_GLOBAL},
+ { &key_THR_LOCK_mutex, "THR_LOCK::mutex", 0},
+ { &key_THR_LOCK_myisam, "THR_LOCK_myisam", PSI_FLAG_GLOBAL},
+ { &key_THR_LOCK_net, "THR_LOCK_net", PSI_FLAG_GLOBAL},
+ { &key_THR_LOCK_open, "THR_LOCK_open", PSI_FLAG_GLOBAL},
+ { &key_THR_LOCK_threads, "THR_LOCK_threads", PSI_FLAG_GLOBAL},
+ { &key_TMPDIR_mutex, "TMPDIR_mutex", PSI_FLAG_GLOBAL},
+ { &key_THR_LOCK_myisam_mmap, "THR_LOCK_myisam_mmap", PSI_FLAG_GLOBAL},
+ { &key_LOCK_uuid_generator, "LOCK_uuid_generator", PSI_FLAG_GLOBAL }
+};
+
+PSI_cond_key key_COND_alarm, 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_IO_CACHE_SHARE_cond, "IO_CACHE_SHARE::cond", 0},
+ { &key_IO_CACHE_SHARE_cond_writer, "IO_CACHE_SHARE::cond_writer", 0},
+ { &key_my_thread_var_suspend, "my_thread_var::suspend", 0},
+ { &key_THR_COND_threads, "THR_COND_threads", PSI_FLAG_GLOBAL},
+ { &key_WT_RESOURCE_cond, "WT_RESOURCE::cond", 0}
+};
- DBUG_ENTER("netware_init");
+PSI_rwlock_key key_SAFEHASH_mutex;
- /* init only if we are not a client library */
- if (my_progname)
- {
-#if SUPPORTED_BY_LIBC /* Removed until supported in Libc */
- struct termios tp;
- /* Disable control characters */
- tcgetattr(STDIN_FILENO, &tp);
- tp.c_cc[VINTR] = _POSIX_VDISABLE;
- tp.c_cc[VEOF] = _POSIX_VDISABLE;
- tp.c_cc[VSUSP] = _POSIX_VDISABLE;
- tcsetattr(STDIN_FILENO, TCSANOW, &tp);
-#endif /* SUPPORTED_BY_LIBC */
-
- /* With stdout redirection */
- if (!isatty(STDOUT_FILENO))
- {
- setscreenmode(SCR_AUTOCLOSE_ON_EXIT); /* auto close the screen */
- }
- else
- {
- setscreenmode(SCR_NO_MODE); /* keep the screen up */
- }
+static PSI_rwlock_info all_mysys_rwlocks[]=
+{
+ { &key_SAFEHASH_mutex, "SAFE_HASH::mutex", 0}
+};
- /* Parse program name and change to base format */
- name= (char*) my_progname;
- for (; *name; name++)
- {
- if (*name == '\\')
- {
- *name = '/';
- }
- else
- {
- *name = tolower(*name);
- }
- }
- }
+#ifdef USE_ALARM_THREAD
+PSI_thread_key key_thread_alarm;
- DBUG_VOID_RETURN;
+static PSI_thread_info all_mysys_threads[]=
+{
+ { &key_thread_alarm, "alarm", PSI_FLAG_GLOBAL}
+};
+#endif /* USE_ALARM_THREAD */
+
+#ifdef HUGETLB_USE_PROC_MEMINFO
+PSI_file_key key_file_proc_meminfo;
+#endif /* HUGETLB_USE_PROC_MEMINFO */
+PSI_file_key key_file_charset, key_file_cnf;
+
+static PSI_file_info all_mysys_files[]=
+{
+#ifdef HUGETLB_USE_PROC_MEMINFO
+ { &key_file_proc_meminfo, "proc_meminfo", 0},
+#endif /* HUGETLB_USE_PROC_MEMINFO */
+ { &key_file_charset, "charset", 0},
+ { &key_file_cnf, "cnf", 0}
+};
+
+void my_init_mysys_psi_keys()
+{
+ const char* category= "mysys";
+ int count;
+
+ if (PSI_server == NULL)
+ return;
+
+ count= sizeof(all_mysys_mutexes)/sizeof(all_mysys_mutexes[0]);
+ PSI_server->register_mutex(category, all_mysys_mutexes, count);
+
+ count= sizeof(all_mysys_conds)/sizeof(all_mysys_conds[0]);
+ PSI_server->register_cond(category, all_mysys_conds, count);
+
+ count= sizeof(all_mysys_rwlocks)/sizeof(all_mysys_rwlocks[0]);
+ PSI_server->register_rwlock(category, all_mysys_rwlocks, count);
+
+#ifdef USE_ALARM_THREAD
+ count= sizeof(all_mysys_threads)/sizeof(all_mysys_threads[0]);
+ PSI_server->register_thread(category, all_mysys_threads, count);
+#endif /* USE_ALARM_THREAD */
+
+ count= sizeof(all_mysys_files)/sizeof(all_mysys_files[0]);
+ PSI_server->register_file(category, all_mysys_files, count);
}
-#endif /* __NETWARE__ */
+#endif /* HAVE_PSI_INTERFACE */
+
diff --git a/mysys/my_largepage.c b/mysys/my_largepage.c
index ecb61802842..59f815a9d87 100644
--- a/mysys/my_largepage.c
+++ b/mysys/my_largepage.c
@@ -1,6 +1,4 @@
-/*
- Copyright (c) 2004, 2006, 2007 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* Copyright (c) 2004, 2010, 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
@@ -13,8 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
@@ -30,7 +27,7 @@
static uint my_get_large_page_size_int(void);
static uchar* my_large_malloc_int(size_t size, myf my_flags);
-static my_bool my_large_free_int(uchar* ptr, myf my_flags);
+static my_bool my_large_free_int(uchar* ptr);
/* Gets the size of large pages from the OS */
@@ -73,7 +70,7 @@ uchar* my_large_malloc(size_t size, myf my_flags)
to my_free_lock() in case of failure
*/
-void my_large_free(uchar* ptr, myf my_flags __attribute__((unused)))
+void my_large_free(uchar* ptr)
{
DBUG_ENTER("my_large_free");
@@ -82,9 +79,8 @@ void my_large_free(uchar* ptr, myf my_flags __attribute__((unused)))
my_large_malloc_int(), i.e. my_malloc_lock() was used so we should free it
with my_free_lock()
*/
- if (!my_use_large_pages || !my_large_page_size ||
- !my_large_free_int(ptr, my_flags))
- my_free_lock(ptr, my_flags);
+ if (!my_use_large_pages || !my_large_page_size || !my_large_free_int(ptr))
+ my_free_lock(ptr);
DBUG_VOID_RETURN;
}
@@ -94,19 +90,20 @@ void my_large_free(uchar* ptr, myf my_flags __attribute__((unused)))
uint my_get_large_page_size_int(void)
{
- FILE *f;
+ MYSQL_FILE *f;
uint size = 0;
char buf[256];
DBUG_ENTER("my_get_large_page_size_int");
- if (!(f = my_fopen("/proc/meminfo", O_RDONLY, MYF(MY_WME))))
+ if (!(f= mysql_file_fopen(key_file_proc_meminfo, "/proc/meminfo",
+ O_RDONLY, MYF(MY_WME))))
goto finish;
- while (fgets(buf, sizeof(buf), f))
+ while (mysql_file_fgets(buf, sizeof(buf), f))
if (sscanf(buf, "Hugepagesize: %u kB", &size))
break;
- my_fclose(f, MYF(MY_WME));
+ mysql_file_fclose(f, MYF(MY_WME));
finish:
DBUG_RETURN(size * 1024);
@@ -131,7 +128,7 @@ uchar* my_large_malloc_int(size_t size, myf my_flags)
{
if (my_flags & MY_WME)
fprintf(stderr,
- "Warning: Failed to allocate %lu bytesx from HugeTLB memory."
+ "Warning: Failed to allocate %lu bytes from HugeTLB memory."
" errno %d\n", (ulong) size, errno);
DBUG_RETURN(NULL);
@@ -159,7 +156,7 @@ uchar* my_large_malloc_int(size_t size, myf my_flags)
/* Linux-specific large pages deallocator */
-my_bool my_large_free_int(uchar *ptr, myf my_flags __attribute__((unused)))
+my_bool my_large_free_int(uchar *ptr)
{
DBUG_ENTER("my_large_free_int");
DBUG_RETURN(shmdt(ptr) == 0);
diff --git a/mysys/my_lib.c b/mysys/my_lib.c
index 864c1e96d27..71969f23d85 100644
--- a/mysys/my_lib.c
+++ b/mysys/my_lib.c
@@ -15,7 +15,6 @@
*/
/* TODO: check for overun of memory for names. */
-/* Convert MSDOS-TIME to standar time_t (still needed?) */
#include "mysys_priv.h"
#include <m_string.h>
@@ -42,13 +41,8 @@
# endif
# endif
#endif
-#ifdef VMS
-#include <rms.h>
-#include <iodef.h>
-#include <descrip.h>
-#endif
-#if defined(THREAD) && defined(HAVE_READDIR_R)
+#if defined(HAVE_READDIR_R)
#define READDIR(A,B,C) ((errno=readdir_r(A,B,&C)) != 0 || !C)
#else
#define READDIR(A,B,C) (!(C=readdir(A)))
@@ -78,7 +72,7 @@ void my_dirend(MY_DIR *buffer)
ALIGN_SIZE(sizeof(MY_DIR))));
free_root((MEM_ROOT*)((char*)buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))), MYF(0));
- my_free((uchar*) buffer,MYF(0));
+ my_free(buffer);
}
DBUG_VOID_RETURN;
} /* my_dirend */
@@ -104,14 +98,13 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
DIR *dirp;
struct dirent *dp;
char tmp_path[FN_REFLEN + 2], *tmp_file;
-#ifdef THREAD
char dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1];
-#endif
+
DBUG_ENTER("my_dir");
DBUG_PRINT("my",("path: '%s' MyFlags: %d",path,MyFlags));
-#if defined(THREAD) && !defined(HAVE_READDIR_R)
- pthread_mutex_lock(&THR_LOCK_open);
+#if !defined(HAVE_READDIR_R)
+ mysql_mutex_lock(&THR_LOCK_open);
#endif
dirp = opendir(directory_file_name(tmp_path,(char *) path));
@@ -132,7 +125,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
ENTRIES_START_SIZE, ENTRIES_INCREMENT))
{
- my_free((uchar*) buffer,MYF(0));
+ my_free(buffer);
goto error;
}
init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
@@ -142,11 +135,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
tmp_file=strend(tmp_path);
-#ifdef THREAD
dp= (struct dirent*) dirent_tmp;
-#else
- dp=0;
-#endif
while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp)))
{
@@ -160,8 +149,8 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
goto error;
bzero(finfo.mystat, sizeof(MY_STAT));
- VOID(strmov(tmp_file,dp->d_name));
- VOID(my_stat(tmp_path, finfo.mystat, MyFlags));
+ (void) strmov(tmp_file,dp->d_name);
+ (void) my_stat(tmp_path, finfo.mystat, MyFlags);
if (!(finfo.mystat->st_mode & MY_S_IREAD))
continue;
}
@@ -173,8 +162,8 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
}
(void) closedir(dirp);
-#if defined(THREAD) && !defined(HAVE_READDIR_R)
- pthread_mutex_unlock(&THR_LOCK_open);
+#if !defined(HAVE_READDIR_R)
+ mysql_mutex_unlock(&THR_LOCK_open);
#endif
result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
result->number_off_files= dir_entries_storage->elements;
@@ -185,8 +174,8 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
DBUG_RETURN(result);
error:
-#if defined(THREAD) && !defined(HAVE_READDIR_R)
- pthread_mutex_unlock(&THR_LOCK_open);
+#if !defined(HAVE_READDIR_R)
+ mysql_mutex_unlock(&THR_LOCK_open);
#endif
my_errno=errno;
if (dirp)
@@ -200,9 +189,6 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
/*
* Convert from directory name to filename.
- * On VMS:
- * xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
- * xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
* On UNIX, it's simple: just make sure there is a terminating /
* Returns pointer to dst;
@@ -210,11 +196,8 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
char * directory_file_name (char * dst, const char *src)
{
-#ifndef VMS
-
/* Process as Unix format: just remove test the final slash. */
-
- char * end;
+ char *end;
DBUG_ASSERT(strlen(src) < (FN_REFLEN + 1));
if (src[0] == 0)
@@ -226,125 +209,7 @@ char * directory_file_name (char * dst, const char *src)
end[1]='\0';
}
return dst;
-
-#else /* VMS */
-
- long slen;
- long rlen;
- char * ptr, rptr;
- char bracket;
- struct FAB fab = cc$rms_fab;
- struct NAM nam = cc$rms_nam;
- char esa[NAM$C_MAXRSS];
-
- if (! src[0])
- src="[.]"; /* Empty is == current dir */
-
- slen = strlen (src) - 1;
- if (src[slen] == FN_C_AFTER_DIR || src[slen] == FN_C_AFTER_DIR_2 ||
- src[slen] == FN_DEVCHAR)
- {
- /* VMS style - convert [x.y.z] to [x.y]z, [x] to [000000]x */
- fab.fab$l_fna = src;
- fab.fab$b_fns = slen + 1;
- fab.fab$l_nam = &nam;
- fab.fab$l_fop = FAB$M_NAM;
-
- nam.nam$l_esa = esa;
- nam.nam$b_ess = sizeof esa;
- nam.nam$b_nop |= NAM$M_SYNCHK;
-
- /* We call SYS$PARSE to handle such things as [--] for us. */
- if (SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL)
- {
- slen = nam.nam$b_esl - 1;
- if (esa[slen] == ';' && esa[slen - 1] == '.')
- slen -= 2;
- esa[slen + 1] = '\0';
- src = esa;
- }
- if (src[slen] != FN_C_AFTER_DIR && src[slen] != FN_C_AFTER_DIR_2)
- {
- /* what about when we have logical_name:???? */
- if (src[slen] == FN_DEVCHAR)
- { /* Xlate logical name and see what we get */
- VOID(strmov(dst,src));
- dst[slen] = 0; /* remove colon */
- if (!(src = getenv (dst)))
- return dst; /* Can't translate */
-
- /* should we jump to the beginning of this procedure?
- Good points: allows us to use logical names that xlate
- to Unix names,
- Bad points: can be a problem if we just translated to a device
- name...
- For now, I'll punt and always expect VMS names, and hope for
- the best! */
-
- slen = strlen (src) - 1;
- if (src[slen] != FN_C_AFTER_DIR && src[slen] != FN_C_AFTER_DIR_2)
- { /* no recursion here! */
- VOID(strmov(dst, src));
- return(dst);
- }
- }
- else
- { /* not a directory spec */
- VOID(strmov(dst, src));
- return(dst);
- }
- }
-
- bracket = src[slen]; /* End char */
- if (!(ptr = strchr (src, bracket - 2)))
- { /* no opening bracket */
- VOID(strmov (dst, src));
- return dst;
- }
- if (!(rptr = strrchr (src, '.')))
- rptr = ptr;
- slen = rptr - src;
- VOID(strmake (dst, src, slen));
-
- if (*rptr == '.')
- { /* Put bracket and add */
- dst[slen++] = bracket; /* (rptr+1) after this */
- }
- else
- {
- /* If we have the top-level of a rooted directory (i.e. xx:[000000]),
- then translate the device and recurse. */
-
- if (dst[slen - 1] == ':'
- && dst[slen - 2] != ':' /* skip decnet nodes */
- && strcmp(src + slen, "[000000]") == 0)
- {
- dst[slen - 1] = '\0';
- if ((ptr = getenv (dst))
- && (rlen = strlen (ptr) - 1) > 0
- && (ptr[rlen] == FN_C_AFTER_DIR || ptr[rlen] == FN_C_AFTER_DIR_2)
- && ptr[rlen - 1] == '.')
- {
- VOID(strmov(esa,ptr));
- esa[rlen - 1] = FN_C_AFTER_DIR;
- esa[rlen] = '\0';
- return (directory_file_name (dst, esa));
- }
- else
- dst[slen - 1] = ':';
- }
- VOID(strmov(dst+slen,"[000000]"));
- slen += 8;
- }
- VOID(strmov(strmov(dst+slen,rptr+1)-1,".DIR.1"));
- return dst;
- }
- VOID(strmov(dst, src));
- if (dst[slen] == '/' && slen > 1)
- dst[slen] = 0;
- return dst;
-#endif /* VMS */
-} /* directory_file_name */
+}
#else
@@ -402,7 +267,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
ENTRIES_START_SIZE, ENTRIES_INCREMENT))
{
- my_free((uchar*) buffer,MYF(0));
+ my_free(buffer);
goto error;
}
init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
@@ -549,7 +414,7 @@ MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags)
DBUG_PRINT("error",("Got errno: %d from stat", errno));
my_errno= errno;
if (m_used) /* Free if new area */
- my_free((uchar*) stat_area,MYF(0));
+ my_free(stat_area);
error:
if (my_flags & (MY_FAE+MY_WME))
diff --git a/mysys/my_lock.c b/mysys/my_lock.c
index 6bbb177e4b6..54ec3838b58 100644
--- a/mysys/my_lock.c
+++ b/mysys/my_lock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -22,9 +22,6 @@
#undef NO_ALARM_LOOP
#endif
#include <my_alarm.h>
-#ifdef __NETWARE__
-#include <nks/fsio.h>
-#endif
#ifdef _WIN32
#define WIN_LOCK_INFINITE -1
@@ -145,59 +142,14 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
int value;
ALARM_VARIABLES;
#endif
-#ifdef __NETWARE__
- int nxErrno;
-#endif
+
DBUG_ENTER("my_lock");
DBUG_PRINT("my",("fd: %d Op: %d start: %ld Length: %ld MyFlags: %d",
fd,locktype,(long) start,(long) length,MyFlags));
-#ifdef VMS
- DBUG_RETURN(0);
-#else
if (my_disable_locking && ! (MyFlags & MY_FORCE_LOCK))
DBUG_RETURN(0);
-#if defined(__NETWARE__)
- {
- NXSOffset_t nxLength = length;
- unsigned long nxLockFlags = 0;
-
- if (length == F_TO_EOF)
- {
- /* EOF is interpreted as a very large length. */
- nxLength = 0x7FFFFFFFFFFFFFFF;
- }
-
- if (locktype == F_UNLCK)
- {
- /* The lock flags are currently ignored by NKS. */
- if (!(nxErrno= NXFileRangeUnlock(fd, 0L, start, nxLength)))
- DBUG_RETURN(0);
- }
- else
- {
- if (locktype == F_RDLCK)
- {
- /* A read lock is mapped to a shared lock. */
- nxLockFlags = NX_RANGE_LOCK_SHARED;
- }
- else
- {
- /* A write lock is mapped to an exclusive lock. */
- nxLockFlags = NX_RANGE_LOCK_EXCL;
- }
-
- if (MyFlags & MY_NO_WAIT)
- {
- /* Don't block on the lock. */
- nxLockFlags |= NX_RANGE_LOCK_TRYLOCK;
- }
-
- if (!(nxErrno= NXFileRangeLock(fd, nxLockFlags, start, nxLength)))
- DBUG_RETURN(0);
- }
- }
-#elif defined(_WIN32)
+#if defined(_WIN32)
{
int timeout_sec;
if (MyFlags & MY_NO_WAIT)
@@ -205,8 +157,8 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
else
timeout_sec= WIN_LOCK_INFINITE;
- if(win_lock(fd, locktype, start, length, timeout_sec) == 0)
- DBUG_RETURN(0);
+ if (win_lock(fd, locktype, start, length, timeout_sec) == 0)
+ DBUG_RETURN(0);
}
#else
#if defined(HAVE_FCNTL)
@@ -260,14 +212,11 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
if (lockf(fd,locktype,length) != -1)
DBUG_RETURN(0);
#endif /* HAVE_FCNTL */
-#endif /* HAVE_LOCKING */
+#endif /* _WIN32 */
-#ifdef __NETWARE__
- my_errno = nxErrno;
-#else
- /* We got an error. We don't want EACCES errors */
+ /* We got an error. We don't want EACCES errors */
my_errno=(errno == EACCES) ? EAGAIN : errno ? errno : -1;
-#endif
+
if (MyFlags & MY_WME)
{
if (locktype == F_UNLCK)
@@ -277,5 +226,4 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
}
DBUG_PRINT("error",("my_errno: %d (%d)",my_errno,errno));
DBUG_RETURN(-1);
-#endif /* ! VMS */
} /* my_lock */
diff --git a/mysys/my_lockmem.c b/mysys/my_lockmem.c
index b96331cd3cf..8f06192d9f8 100644
--- a/mysys/my_lockmem.c
+++ b/mysys/my_lockmem.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* Alloc a block of locked memory */
@@ -59,40 +59,39 @@ uchar *my_malloc_lock(uint size,myf MyFlags)
/* Add block in a list for munlock */
if (!(element=(struct st_mem_list*) my_malloc(sizeof(*element),MyFlags)))
{
- VOID(munlock((uchar*) ptr,size));
+ (void) munlock((uchar*) ptr,size);
free(ptr);
DBUG_RETURN(0);
}
element->list.data=(uchar*) element;
element->page=ptr;
element->size=size;
- pthread_mutex_lock(&THR_LOCK_malloc);
+ mysql_mutex_lock(&THR_LOCK_malloc);
mem_list=list_add(mem_list,&element->list);
- pthread_mutex_unlock(&THR_LOCK_malloc);
+ mysql_mutex_unlock(&THR_LOCK_malloc);
}
DBUG_RETURN(ptr);
}
-void my_free_lock(uchar *ptr,myf Myflags __attribute__((unused)))
+void my_free_lock(uchar *ptr)
{
LIST *list;
struct st_mem_list *element=0;
- pthread_mutex_lock(&THR_LOCK_malloc);
+ mysql_mutex_lock(&THR_LOCK_malloc);
for (list=mem_list ; list ; list=list->next)
{
element=(struct st_mem_list*) list->data;
if (ptr == element->page)
{ /* Found locked mem */
- VOID(munlock((uchar*) ptr,element->size));
+ (void) munlock((uchar*) ptr,element->size);
mem_list=list_delete(mem_list,list);
break;
}
}
- pthread_mutex_unlock(&THR_LOCK_malloc);
- if (element)
- my_free((uchar*) element,MYF(0));
+ mysql_mutex_unlock(&THR_LOCK_malloc);
+ my_free(element);
free(ptr); /* Free even if not locked */
}
diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c
index 9a219ca2b73..1a9caf71380 100644
--- a/mysys/my_malloc.c
+++ b/mysys/my_malloc.c
@@ -12,22 +12,20 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-/* my_global.h may define SAFEMALLOC (through my_config.h). */
-#include <my_global.h>
-
-#ifdef SAFEMALLOC /* We don't need SAFEMALLOC here */
-#undef SAFEMALLOC
-#endif
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
#include <m_string.h>
- /* My memory allocator */
+/**
+ Allocate a sized block of memory.
+
+ @param size The size of the memory block in bytes.
+ @param flags Failure action modifiers (bitmasks).
+ @return A pointer to the allocated memory block, or NULL on failure.
+*/
void *my_malloc(size_t size, myf my_flags)
{
void* point;
@@ -36,13 +34,14 @@ void *my_malloc(size_t size, myf my_flags)
if (!(my_flags & (MY_WME | MY_FAE)))
my_flags|= my_global_flags;
+ /* Safety */
if (!size)
- size=1; /* Safety */
+ size=1;
- point= (char *) malloc(size);
+ point= sf_malloc(size);
DBUG_EXECUTE_IF("simulate_out_of_memory",
{
- free(point);
+ my_free(point);
point= NULL;
});
@@ -61,33 +60,71 @@ void *my_malloc(size_t size, myf my_flags)
exit(1);
}
else if (my_flags & MY_ZEROFILL)
- bzero(point,size);
- DBUG_PRINT("exit",("ptr: 0x%lx", (long) point));
- DBUG_RETURN((void*) point);
-} /* my_malloc */
+ bzero(point, size);
+ DBUG_PRINT("exit",("ptr: %p", point));
+ DBUG_RETURN(point);
+}
+
+/**
+ @brief wrapper around realloc()
- /* Free memory allocated with my_malloc */
- /*ARGSUSED*/
+ @param oldpoint pointer to currently allocated area
+ @param size new size requested, must be >0
+ @param my_flags flags
-void my_no_flags_free(void* ptr)
+ @note if size==0 realloc() may return NULL; my_realloc() treats this as an
+ error which is not the intention of realloc()
+*/
+void *my_realloc(void *oldpoint, size_t size, myf my_flags)
+{
+ void *point;
+ DBUG_ENTER("my_realloc");
+ DBUG_PRINT("my",("ptr: %p size: %lu my_flags: %d", oldpoint,
+ (ulong) size, my_flags));
+
+ DBUG_ASSERT(size > 0);
+ if (!oldpoint && (my_flags & MY_ALLOW_ZERO_PTR))
+ DBUG_RETURN(my_malloc(size, my_flags));
+ if ((point= sf_realloc(oldpoint, size)) == NULL)
+ {
+ if (my_flags & MY_FREE_ON_ERROR)
+ my_free(oldpoint);
+ if (my_flags & MY_HOLD_ON_ERROR)
+ DBUG_RETURN(oldpoint);
+ my_errno=errno;
+ if (my_flags & (MY_FAE+MY_WME))
+ my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG), size);
+ }
+ DBUG_PRINT("exit",("ptr: %p", point));
+ DBUG_RETURN(point);
+}
+
+
+/**
+ Free memory allocated with my_malloc.
+
+ @remark Relies on free being able to handle a NULL argument.
+
+ @param ptr Pointer to the memory allocated by my_malloc.
+*/
+void my_free(void *ptr)
{
DBUG_ENTER("my_free");
- DBUG_PRINT("my",("ptr: 0x%lx", (long) ptr));
- if (ptr)
- free(ptr);
+ DBUG_PRINT("my",("ptr: %p", ptr));
+ sf_free(ptr);
DBUG_VOID_RETURN;
-} /* my_free */
-
+}
- /* malloc and copy */
-void* my_memdup(const void *from, size_t length, myf my_flags)
+void *my_memdup(const void *from, size_t length, myf my_flags)
{
void *ptr;
+ DBUG_ENTER("my_memdup");
+
if ((ptr= my_malloc(length,my_flags)) != 0)
memcpy(ptr, from, length);
- return(ptr);
+ DBUG_RETURN(ptr);
}
@@ -95,19 +132,24 @@ char *my_strdup(const char *from, myf my_flags)
{
char *ptr;
size_t length= strlen(from)+1;
+ DBUG_ENTER("my_strdup");
+
if ((ptr= (char*) my_malloc(length, my_flags)))
- memcpy((uchar*) ptr, (uchar*) from,(size_t) length);
- return(ptr);
+ memcpy(ptr, from, length);
+ DBUG_RETURN(ptr);
}
char *my_strndup(const char *from, size_t length, myf my_flags)
{
char *ptr;
- if ((ptr= (char*) my_malloc(length+1,my_flags)) != 0)
+ DBUG_ENTER("my_strndup");
+
+ if ((ptr= (char*) my_malloc(length+1, my_flags)))
{
- memcpy((uchar*) ptr, (uchar*) from, length);
- ptr[length]=0;
+ memcpy(ptr, from, length);
+ ptr[length]= 0;
}
- return((char*) ptr);
+ DBUG_RETURN(ptr);
}
+
diff --git a/mysys/my_messnc.c b/mysys/my_mess.c
index e2431959b7a..8ee816b385a 100644
--- a/mysys/my_messnc.c
+++ b/mysys/my_mess.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,22 +11,18 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
-int my_message_no_curses(uint error __attribute__((unused)),
- const char *str, myf MyFlags)
+void my_message_stderr(uint error __attribute__((unused)),
+ const char *str, myf MyFlags)
{
- DBUG_ENTER("my_message_no_curses");
+ DBUG_ENTER("my_message_stderr");
DBUG_PRINT("enter",("message: %s",str));
(void) fflush(stdout);
if (MyFlags & ME_BELL)
-#ifdef __NETWARE__
- ringbell(); /* Bell */
-#else
- (void) fputc('\007',stderr); /* Bell */
-#endif /* __NETWARE__ */
+ (void) fputc('\007', stderr);
if (my_progname)
{
(void)fputs(my_progname,stderr); (void)fputs(": ",stderr);
@@ -34,5 +30,5 @@ int my_message_no_curses(uint error __attribute__((unused)),
(void)fputs(str,stderr);
(void)fputc('\n',stderr);
(void)fflush(stderr);
- DBUG_RETURN(0);
+ DBUG_VOID_RETURN;
}
diff --git a/mysys/my_mmap.c b/mysys/my_mmap.c
index 303d8efaf30..acd4862eaca 100644
--- a/mysys/my_mmap.c
+++ b/mysys/my_mmap.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
@@ -38,13 +38,16 @@ void *my_mmap(void *addr, size_t len, int prot,
HANDLE hFileMap;
LPVOID ptr;
HANDLE hFile= (HANDLE)my_get_osfhandle(fd);
+ DBUG_ENTER("my_mmap");
+ DBUG_PRINT("mysys", ("map fd: %d", fd));
+
if (hFile == INVALID_HANDLE_VALUE)
- return MAP_FAILED;
+ DBUG_RETURN(MAP_FAILED);
hFileMap=CreateFileMapping(hFile, &mmap_security_attributes,
PAGE_READWRITE, 0, (DWORD) len, NULL);
if (hFileMap == 0)
- return MAP_FAILED;
+ DBUG_RETURN(MAP_FAILED);
ptr=MapViewOfFile(hFileMap,
prot & PROT_WRITE ? FILE_MAP_WRITE : FILE_MAP_READ,
@@ -59,14 +62,19 @@ void *my_mmap(void *addr, size_t len, int prot,
CloseHandle(hFileMap);
if (ptr)
- return ptr;
+ {
+ DBUG_PRINT("mysys", ("mapped addr: %p", ptr));
+ DBUG_RETURN(ptr);
+ }
- return MAP_FAILED;
+ DBUG_RETURN(MAP_FAILED);
}
int my_munmap(void *addr, size_t len)
{
- return UnmapViewOfFile(addr) ? 0 : -1;
+ DBUG_ENTER("my_munmap");
+ DBUG_PRINT("mysys", ("unmap addr: %p", addr));
+ DBUG_RETURN(UnmapViewOfFile(addr) ? 0 : -1);
}
int my_msync(int fd, void *addr, size_t len, int flags)
diff --git a/mysys/my_net.c b/mysys/my_net.c
deleted file mode 100644
index 72f6078c5d9..00000000000
--- a/mysys/my_net.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* thread safe version of some common functions */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-
-/* for thread safe my_inet_ntoa */
-#if !defined(__WIN__)
-#include <netdb.h>
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#endif /* !defined(__WIN__) */
-#include "my_net.h"
-
-
-void my_inet_ntoa(struct in_addr in, char *buf)
-{
- char *ptr;
- pthread_mutex_lock(&THR_LOCK_net);
- ptr=inet_ntoa(in);
- strmov(buf,ptr);
- pthread_mutex_unlock(&THR_LOCK_net);
-}
-
-/* This code is not needed if my_gethostbyname_r is a macro */
-#if !defined(my_gethostbyname_r)
-
-/*
- Emulate SOLARIS style calls, not because it's better, but just to make the
- usage of getbostbyname_r simpler.
-*/
-
-#if defined(HAVE_GETHOSTBYNAME_R)
-
-#if defined(HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE)
-
-struct hostent *my_gethostbyname_r(const char *name,
- struct hostent *result, char *buffer,
- int buflen, int *h_errnop)
-{
- struct hostent *hp;
- DBUG_ASSERT((size_t) buflen >= sizeof(*result));
- if (gethostbyname_r(name,result, buffer, (size_t) buflen, &hp, h_errnop))
- return 0;
- return hp;
-}
-
-#elif defined(HAVE_GETHOSTBYNAME_R_RETURN_INT)
-
-struct hostent *my_gethostbyname_r(const char *name,
- struct hostent *result, char *buffer,
- int buflen, int *h_errnop)
-{
- if (gethostbyname_r(name,result,(struct hostent_data *) buffer) == -1)
- {
- *h_errnop= errno;
- return 0;
- }
- return result;
-}
-
-#else
-
-/* gethostbyname_r with similar interface as gethostbyname() */
-
-struct hostent *my_gethostbyname_r(const char *name,
- struct hostent *result, char *buffer,
- int buflen, int *h_errnop)
-{
- struct hostent *hp;
- DBUG_ASSERT(buflen >= sizeof(struct hostent_data));
- hp= gethostbyname_r(name,result,(struct hostent_data *) buffer);
- *h_errnop= errno;
- return hp;
-}
-#endif /* GLIBC2_STYLE_GETHOSTBYNAME_R */
-
-#else /* !HAVE_GETHOSTBYNAME_R */
-
-#ifdef THREAD
-extern pthread_mutex_t LOCK_gethostbyname_r;
-#endif
-
-/*
- No gethostbyname_r() function exists.
- In this case we have to keep a mutex over the call to ensure that no
- other thread is going to reuse the internal memory.
-
- The user is responsible to call my_gethostbyname_r_free() when he
- is finished with the structure.
-*/
-
-struct hostent *
-my_gethostbyname_r(const char *name,
- struct hostent *result __attribute__((unused)),
- char *buffer __attribute__((unused)),
- int buflen __attribute__((unused)),
- int *h_errnop)
-{
- struct hostent *hp;
- pthread_mutex_lock(&LOCK_gethostbyname_r);
- hp= gethostbyname(name);
- *h_errnop= h_errno;
- return hp;
-}
-
-void my_gethostbyname_r_free()
-{
- pthread_mutex_unlock(&LOCK_gethostbyname_r);
-}
-
-#endif /* !HAVE_GETHOSTBYNAME_R */
-#endif /* !my_gethostbyname_r */
diff --git a/mysys/my_netware.c b/mysys/my_netware.c
deleted file mode 100644
index 5b5c39c0ac0..00000000000
--- a/mysys/my_netware.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/* Copyright (C) 2003 MySQL 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*
- Functions specific to netware
-*/
-
-#include <mysys_priv.h>
-#ifdef __NETWARE__
- #include <string.h>
- #include <library.h>
-
-/*
- PMUserLicenseRequest is an API exported by the polimgr.nlm
- (loaded by the NetWare OS when it comes up) for use by other
- NLM-based NetWare products/services.
- PMUserLicenseRequest provides a couple of functions:
- 1) it will optionally request a User license or ensure that
- one already exists for the specified User in userInfo
- 2) it utilizes the NetWare usage metering service to
- record usage information about your product/service.
-*/
-
-long PMMeteredUsageRequest
-(
- /*
- NDS distinguished name or IP address or ??. asciiz string, e.g.
- ".CN=Admin.O=this.T=MYTREE."
- */
- char *userInfo,
- long infoType, /* see defined values */
- /*
- string used to identify the calling service, used to index the
- metered info e.g. "iPrint"
- */
- char *serviceID,
- char tranAddrType, /* type of address that follows */
- char *tranAddr, /* ptr to a 10-byte array */
- long flags, /* see defined values */
- /* NLS error code, if any. NULL input is okay */
- long *licRequestErrCode,
- /* meter service error code, if any. NULL input is okay */
- long *storeMeterInfoErrCode,
- /*
- error code from NLSMeter if
- storeMeterInfoErrCode == PM_LICREQ_NLSMETERERROR.
- NULL input is okay
- */
- long *NLSMeterErrCode
-);
-
-typedef long(*PMUR)(const char*, long, const char*, char,
- const char*, long, long*, long*, long*);
-
-/* infoType */
-/* indicates that the info in the userInfo param is an NDS user */
-#define PM_USERINFO_TYPE_NDS 1
-/* indicates that the info in the userInfo param is NOT an NDS user */
-#define PM_USERINFO_TYPE_ADDRESS 2
-
-/* Flags */
-
-/*
- Tells the service that it should not check to see if the NDS user
- contained in the userInfo param has a NetWare User License - just
- record metering information; this is ignored if infoType !=
- PM_USERINFO_TYPE_NDS
-*/
-
-#define PM_FLAGS_METER_ONLY 0x0000001
-
-/*
- Indicates that the values in the userInfo and serviceID parameters
- are unicode strings, so that the metering service bypasses
- converting these to unicode (again)
-*/
-#define PM_LICREQ_ALREADY_UNICODE 0x0000002
-/*
- Useful only if infoType is PM_USERINFO_TYPE_NDS - indicates a "no
- stop" policy of the calling service
-*/
-#define PM_LICREQ_ALWAYS_METER 0x0000004
-
-
-/*
- net Address Types - system-defined types of net addresses that can
- be used in the tranAddrType field
-*/
-
-#define NLS_TRAN_TYPE_IPX 0x00000001 /* An IPX address */
-#define NLS_TRAN_TYPE_IP 0x00000008 /* An IP address */
-#define NLS_ADDR_TYPE_MAC 0x000000F1 /* a MAC address */
-
-/*
- Net Address Sizes - lengths that correspond to the tranAddrType
- field (just fyi)
-*/
-#define NLS_IPX_ADDR_SIZE 10 /* the size of an IPX address */
-#define NLS_IP_ADDR_SIZE 4 /* the size of an IP address */
-#define NLS_MAC_ADDR_SIZE 6 /* the size of a MAC address */
-
-
-void netware_reg_user(const char *ip, const char *user,
- const char *application)
-{
- PMUR usage_request;
- long licRequestErrCode = 0;
- long storeMeterInfoErrCode = 0;
- long nlsMeterErrCode = 0;
-
- /* import the symbol */
- usage_request= ((PMUR)ImportPublicObject(getnlmhandle(),
- "PMMeteredUsageRequest"));
- if (usage_request != NULL)
- {
- unsigned long iaddr;
- char addr[NLS_IPX_ADDR_SIZE];
-
- /* create address */
- iaddr = htonl(inet_addr(ip));
- bzero(addr, NLS_IPX_ADDR_SIZE);
- memcpy(addr, &iaddr, NLS_IP_ADDR_SIZE);
-
- /* call to NLS */
- usage_request(user,
- PM_USERINFO_TYPE_ADDRESS,
- application,
- NLS_TRAN_TYPE_IP,
- addr,
- PM_FLAGS_METER_ONLY,
- &licRequestErrCode,
- &storeMeterInfoErrCode,
- &nlsMeterErrCode);
- /* release symbol */
- UnImportPublicObject(getnlmhandle(), "PMMeteredUsageRequest");
- }
-}
-#endif /* __NETWARE__ */
diff --git a/mysys/my_new.cc b/mysys/my_new.cc
index edc393a5b55..4266452da43 100644
--- a/mysys/my_new.cc
+++ b/mysys/my_new.cc
@@ -1,5 +1,4 @@
-/*
- Copyright (c) 2000, 2001, 2003-2006 MySQL AB, 2009 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2001, 2003-2006 MySQL AB, 2009 Sun Microsystems, Inc.
Use is subject to license terms.
This program is free software; you can redistribute it and/or modify
@@ -13,38 +12,59 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
This is a replacement of new/delete operators to be used when compiling
- with gcc 3.0.x to avoid including libstdc++
+ with gcc 3.0.x to avoid including libstdc++
+
+ It is also used to make all memory allocations to go through
+ my_malloc/my_free wrappers (for debugging/safemalloc and accounting)
*/
#include "mysys_priv.h"
+#include <new>
#ifdef USE_MYSYS_NEW
void *operator new (size_t sz)
{
- return (void *) malloc (sz ? sz : 1);
+ return (void *) my_malloc (sz ? sz : 1, MYF(0));
}
void *operator new[] (size_t sz)
{
- return (void *) malloc (sz ? sz : 1);
+ return (void *) my_malloc (sz ? sz : 1, MYF(0));
+}
+
+void* operator new(std::size_t sz, const std::nothrow_t&) throw()
+{
+ return (void *) my_malloc (sz ? sz : 1, MYF(0));
+}
+
+void* operator new[](std::size_t sz, const std::nothrow_t&) throw()
+{
+ return (void *) my_malloc (sz ? sz : 1, MYF(0));
}
void operator delete (void *ptr)
{
- if (ptr)
- free(ptr);
+ my_free(ptr);
}
void operator delete[] (void *ptr) throw ()
{
- if (ptr)
- free(ptr);
+ my_free(ptr);
+}
+
+void operator delete(void* ptr, const std::nothrow_t&) throw()
+{
+ my_free(ptr);
+}
+
+void operator delete[](void* ptr, const std::nothrow_t&) throw()
+{
+ my_free(ptr);
}
C_MODE_START
@@ -56,6 +76,11 @@ int __cxa_pure_virtual()
}
C_MODE_END
-
+#else
+/*
+ Define a dummy symbol, just to avoid compiler/linker warnings
+ about compiling an essentially empty file.
+*/
+int my_new_cc_symbol;
#endif /* USE_MYSYS_NEW */
diff --git a/mysys/my_once.c b/mysys/my_once.c
index 73bdd0166e6..7df9b0a1981 100644
--- a/mysys/my_once.c
+++ b/mysys/my_once.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,24 +11,18 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* Not MT-SAFE */
-/* my_global.h may define SAFEMALLOC (through my_config.h). */
-#include <my_global.h>
-
-#ifdef SAFEMALLOC /* We don't need SAFEMALLOC here */
-#undef SAFEMALLOC
-#endif
-
#include "mysys_priv.h"
#include "my_static.h"
#include "mysys_err.h"
#include <m_string.h>
/*
- Alloc for things we don't nead to free
+ Alloc for things we don't nend to free run-time (that only
+ should be free'd on exit)
SYNOPSIS
my_once_alloc()
@@ -103,7 +97,7 @@ void *my_once_memdup(const void *src, size_t len, myf myflags)
/*
- Deallocate everything used by my_once_alloc
+ Deallocate everything that was allocated with my_once_alloc
SYNOPSIS
my_once_free()
diff --git a/mysys/my_open.c b/mysys/my_open.c
index dc2fcaf04c6..645d6709358 100644
--- a/mysys/my_open.c
+++ b/mysys/my_open.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -51,8 +51,9 @@ File my_open(const char *FileName, int Flags, myf MyFlags)
fd = open((char *) FileName, Flags);
#endif
- DBUG_RETURN(my_register_filename(fd, FileName, FILE_BY_OPEN,
- EE_FILENOTFOUND, MyFlags));
+ fd= my_register_filename(fd, FileName, FILE_BY_OPEN,
+ EE_FILENOTFOUND, MyFlags);
+ DBUG_RETURN(fd);
} /* my_open */
@@ -74,7 +75,7 @@ int my_close(File fd, myf MyFlags)
if (!(MyFlags & (MY_WME | MY_FAE)))
MyFlags|= my_global_flags;
- pthread_mutex_lock(&THR_LOCK_open);
+ mysql_mutex_lock(&THR_LOCK_open);
#ifndef _WIN32
do
{
@@ -93,11 +94,11 @@ int my_close(File fd, myf MyFlags)
}
if ((uint) fd < my_file_limit && my_file_info[fd].type != UNOPEN)
{
- my_free(my_file_info[fd].name, MYF(0));
+ my_free(my_file_info[fd].name);
my_file_info[fd].type = UNOPEN;
}
my_file_opened--;
- pthread_mutex_unlock(&THR_LOCK_open);
+ mysql_mutex_unlock(&THR_LOCK_open);
DBUG_RETURN(err);
} /* my_close */
@@ -132,17 +133,17 @@ File my_register_filename(File fd, const char *FileName, enum file_type
}
else
{
- pthread_mutex_lock(&THR_LOCK_open);
+ mysql_mutex_lock(&THR_LOCK_open);
if ((my_file_info[fd].name = (char*) my_strdup(FileName,MyFlags)))
{
my_file_opened++;
my_file_total_opened++;
my_file_info[fd].type = type_of_file;
- pthread_mutex_unlock(&THR_LOCK_open);
+ mysql_mutex_unlock(&THR_LOCK_open);
DBUG_PRINT("exit",("fd: %d",fd));
DBUG_RETURN(fd);
}
- pthread_mutex_unlock(&THR_LOCK_open);
+ mysql_mutex_unlock(&THR_LOCK_open);
my_errno= ENOMEM;
}
(void) my_close(fd, MyFlags);
diff --git a/mysys/my_pread.c b/mysys/my_pread.c
index dad346264bb..51b4c5f5599 100644
--- a/mysys/my_pread.c
+++ b/mysys/my_pread.c
@@ -1,6 +1,5 @@
-/*
- Copyright (c) 2000, 2001, 2004, 2006, 2007 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2011, Monty Program 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
@@ -13,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -52,13 +50,11 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
size_t readbytes;
int error= 0;
-#ifndef DBUG_OFF
- char llbuf[22];
DBUG_ENTER("my_pread");
- DBUG_PRINT("my",("fd: %d Seek: %s Buffer: 0x%lx Count: %lu MyFlags: %d",
- Filedes, ullstr(offset, llbuf), (long) Buffer,
- (ulong)Count, MyFlags));
-#endif
+
+ DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d",
+ Filedes, (ulonglong)offset, Buffer, (ulong)Count, MyFlags));
+
if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP)))
MyFlags|= my_global_flags;
@@ -80,14 +76,12 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
my_errno= HA_ERR_FILE_TOO_SHORT;
DBUG_PRINT("warning",("Read only %d bytes off %u from %d, errno: %d",
(int) readbytes, (uint) Count,Filedes,my_errno));
-#ifdef THREAD
if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR)
{
DBUG_PRINT("debug", ("my_pread() was interrupted and returned %d",
(int) readbytes));
continue; /* Interrupted */
}
-#endif
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
{
if (readbytes == (size_t) -1)
@@ -135,13 +129,9 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
{
size_t writtenbytes, written;
uint errors;
-#ifndef DBUG_OFF
- char llbuf[22];
DBUG_ENTER("my_pwrite");
- DBUG_PRINT("my",("fd: %d Seek: %s Buffer: 0x%lx Count: %lu MyFlags: %d",
- Filedes, ullstr(offset, llbuf), (long) Buffer,
- (ulong)Count, MyFlags));
-#endif
+ DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d",
+ Filedes, (ulonglong)offset, Buffer, (ulong)Count, MyFlags));
errors= 0;
written= 0;
if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP)))
@@ -166,10 +156,8 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
}
DBUG_PRINT("error",("Write only %u bytes", (uint) writtenbytes));
#ifndef NO_BACKGROUND
-#ifdef THREAD
if (my_thread_var->abort)
MyFlags&= ~ MY_WAIT_IF_FULL; /* End if aborted by user */
-#endif
if ((my_errno == ENOSPC || my_errno == EDQUOT) &&
(MyFlags & MY_WAIT_IF_FULL))
{
diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c
index e97bbe89be0..20e53a23ab5 100644
--- a/mysys/my_pthread.c
+++ b/mysys/my_pthread.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* 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
@@ -11,14 +11,13 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* Functions to get threads more portable */
#define DONT_REMAP_PTHREAD_FUNCTIONS
#include "mysys_priv.h"
-#ifdef THREAD
#include <signal.h>
#include <m_string.h>
#include <thr_alarm.h>
@@ -31,88 +30,6 @@
uint thd_lib_detected= 0;
-#ifndef my_pthread_setprio
-void my_pthread_setprio(pthread_t thread_id,int prior)
-{
-#ifdef HAVE_PTHREAD_SETSCHEDPARAM
- struct sched_param tmp_sched_param;
- bzero((char*) &tmp_sched_param,sizeof(tmp_sched_param));
- tmp_sched_param.sched_priority=prior;
- VOID(pthread_setschedparam(thread_id,SCHED_POLICY,&tmp_sched_param));
-#endif
-}
-#endif
-
-#ifndef my_pthread_getprio
-int my_pthread_getprio(pthread_t thread_id)
-{
-#ifdef HAVE_PTHREAD_SETSCHEDPARAM
- struct sched_param tmp_sched_param;
- int policy;
- if (!pthread_getschedparam(thread_id,&policy,&tmp_sched_param))
- {
- return tmp_sched_param.sched_priority;
- }
-#endif
- return -1;
-}
-#endif
-
-#ifndef my_pthread_attr_setprio
-void my_pthread_attr_setprio(pthread_attr_t *attr, int priority)
-{
-#ifdef HAVE_PTHREAD_SETSCHEDPARAM
- struct sched_param tmp_sched_param;
- bzero((char*) &tmp_sched_param,sizeof(tmp_sched_param));
- tmp_sched_param.sched_priority=priority;
- VOID(pthread_attr_setschedparam(attr,&tmp_sched_param));
-#endif
-}
-#endif
-
-
-/* To allow use of pthread_getspecific with two arguments */
-
-#ifdef HAVE_NONPOSIX_PTHREAD_GETSPECIFIC
-#undef pthread_getspecific
-
-void *my_pthread_getspecific_imp(pthread_key_t key)
-{
- void *value;
- if (pthread_getspecific(key,(void *) &value))
- return 0;
- return value;
-}
-#endif
-
-#ifdef __NETWARE__
-/*
- Don't kill the LibC Reaper thread or the main thread
-*/
-#include <nks/thread.h>
-#undef pthread_exit
-void my_pthread_exit(void *status)
-{
- NXThreadId_t tid;
- NXContext_t ctx;
- char name[NX_MAX_OBJECT_NAME_LEN+1] = "";
-
- tid= NXThreadGetId();
- if (tid == NX_INVALID_THREAD_ID || !tid)
- return;
- if (NXThreadGetContext(tid, &ctx) ||
- NXContextGetName(ctx, name, sizeof(name)-1))
- return;
-
- /*
- "MYSQLD.NLM's LibC Reaper" or "MYSQLD.NLM's main thread"
- with a debug build of LibC the reaper can have different names
- */
- if (!strindex(name, "\'s"))
- pthread_exit(status);
-}
-#endif
-
/*
Some functions for RTS threads, AIX, Siemens Unix and UnixWare 7
(and DEC OSF/1 3.2 too)
@@ -120,23 +37,11 @@ void my_pthread_exit(void *status)
int my_pthread_create_detached=1;
-#if defined(HAVE_NONPOSIX_SIGWAIT) || defined(HAVE_DEC_3_2_THREADS)
-
-int my_sigwait(const sigset_t *set,int *sig)
-{
- int signal=sigwait((sigset_t*) set);
- if (signal < 0)
- return errno;
- *sig=signal;
- return 0;
-}
-#endif
-
/* localtime_r for SCO 3.2V4.2 */
#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
-extern pthread_mutex_t LOCK_localtime_r;
+extern mysql_mutex_t LOCK_localtime_r;
#endif
@@ -144,10 +49,10 @@ extern pthread_mutex_t LOCK_localtime_r;
struct tm *localtime_r(const time_t *clock, struct tm *res)
{
struct tm *tmp;
- pthread_mutex_lock(&LOCK_localtime_r);
+ mysql_mutex_lock(&LOCK_localtime_r);
tmp=localtime(clock);
*res= *tmp;
- pthread_mutex_unlock(&LOCK_localtime_r);
+ mysql_mutex_unlock(&LOCK_localtime_r);
return res;
}
#endif
@@ -161,10 +66,10 @@ struct tm *localtime_r(const time_t *clock, struct tm *res)
struct tm *gmtime_r(const time_t *clock, struct tm *res)
{
struct tm *tmp;
- pthread_mutex_lock(&LOCK_localtime_r);
+ mysql_mutex_lock(&LOCK_localtime_r);
tmp= gmtime(clock);
*res= *tmp;
- pthread_mutex_unlock(&LOCK_localtime_r);
+ mysql_mutex_unlock(&LOCK_localtime_r);
return res;
}
#endif
@@ -186,7 +91,7 @@ struct tm *gmtime_r(const time_t *clock, struct tm *res)
** Author: Gary Wisniewski <garyw@spidereye.com.au>, much modified by Monty
****************************************************************************/
-#if !defined(HAVE_SIGWAIT) && !defined(sigwait) && !defined(__WIN__) && !defined(HAVE_rts_threads) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS)
+#if !defined(HAVE_SIGWAIT) && !defined(sigwait) && !defined(__WIN__) && !defined(HAVE_rts_threads)
#if !defined(DONT_USE_SIGSUSPEND)
@@ -206,7 +111,7 @@ void sigwait_setup(sigset_t *set)
sact.sa_flags = 0;
sact.sa_handler = px_handle_sig;
- memcpy_fixed(&sact.sa_mask,set,sizeof(*set)); /* handler isn't thread_safe */
+ memcpy(&sact.sa_mask, set, sizeof(*set)); /* handler isn't thread_safe */
sigemptyset(&unblock_mask);
pthread_sigmask(SIG_UNBLOCK,(sigset_t*) 0,&rev_sigwait_set);
@@ -232,7 +137,7 @@ void sigwait_setup(sigset_t *set)
}
}
}
- memcpy_fixed(&sigwait_set,set,sizeof(*set));
+ memcpy(&sigwait_set, set, sizeof(*set));
pthread_sigmask(SIG_BLOCK,(sigset_t*) set,(sigset_t*) 0);
pthread_sigmask(SIG_UNBLOCK,&unblock_mask,(sigset_t*) 0);
}
@@ -308,7 +213,7 @@ void sigwait_handle_sig(int sig)
{
pthread_mutex_lock(&LOCK_sigwait);
sigaddset(&pending_set, sig);
- VOID(pthread_cond_signal(&COND_sigwait)); /* inform sigwait() about signal */
+ pthread_cond_signal(&COND_sigwait); /* inform sigwait() about signal */
pthread_mutex_unlock(&LOCK_sigwait);
}
@@ -320,7 +225,7 @@ void *sigwait_thread(void *set_arg)
struct sigaction sact;
sact.sa_flags = 0;
sact.sa_handler = sigwait_handle_sig;
- memcpy_fixed(&sact.sa_mask,set,sizeof(*set)); /* handler isn't thread_safe */
+ memcpy(&sact.sa_mask, set, sizeof(*set)); /* handler isn't thread_safe */
sigemptyset(&pending_set);
for (i = 1; i <= sizeof(pending_set)*8; i++)
@@ -338,13 +243,7 @@ void *sigwait_thread(void *set_arg)
for (;;)
{ /* Wait for signals */
-#ifdef HAVE_NOT_BROKEN_SELECT
- fd_set fd;
- FD_ZERO(&fd);
- select(0,&fd,0,0,0);
-#else
sleep(1); /* Because of broken BSDI */
-#endif
}
}
@@ -357,16 +256,15 @@ int sigwait(sigset_t *setp, int *sigp)
pthread_t sigwait_thread_id;
inited=1;
sigemptyset(&pending_set);
- pthread_mutex_init(&LOCK_sigwait,MY_MUTEX_INIT_FAST);
- pthread_cond_init(&COND_sigwait,NULL);
+ pthread_mutex_init(&LOCK_sigwait, MY_MUTEX_INIT_FAST);
+ pthread_cond_init(&COND_sigwait, 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,8196);
- my_pthread_attr_setprio(&thr_attr,100); /* Very high priority */
- VOID(pthread_create(&sigwait_thread_id,&thr_attr,sigwait_thread,setp));
- VOID(pthread_attr_destroy(&thr_attr));
+ pthread_create(&sigwait_thread_id, &thr_attr, sigwait_thread, setp);
+ pthread_attr_destroy(&thr_attr);
}
pthread_mutex_lock(&LOCK_sigwait);
@@ -392,7 +290,7 @@ int sigwait(sigset_t *setp, int *sigp)
return 0;
}
}
- VOID(pthread_cond_wait(&COND_sigwait,&LOCK_sigwait));
+ pthread_cond_wait(&COND_sigwait, &LOCK_sigwait);
}
return 0;
}
@@ -422,39 +320,6 @@ int sigwait(sigset_t *setp, int *sigp)
#undef pthread_attr_getstacksize
/*****************************************************************************
-** Patches for AIX and DEC OSF/1 3.2
-*****************************************************************************/
-
-#if defined(HAVE_NONPOSIX_PTHREAD_MUTEX_INIT)
-
-#include <netdb.h>
-
-int my_pthread_mutex_noposix_init(pthread_mutex_t *mp,
- const pthread_mutexattr_t *attr)
-{
- int error;
- if (!attr)
- error=pthread_mutex_init(mp,pthread_mutexattr_default);
- else
- error=pthread_mutex_init(mp,*attr);
- return error;
-}
-
-int my_pthread_cond_noposix_init(pthread_cond_t *mp,
- const pthread_condattr_t *attr)
-{
- int error;
- if (!attr)
- error=pthread_cond_init(mp,pthread_condattr_default);
- else
- error=pthread_cond_init(mp,*attr);
- return error;
-}
-
-#endif
-
-
-/*****************************************************************************
Patches for HPUX
We need these because the pthread_mutex.. code returns -1 on error,
instead of the error code.
@@ -464,7 +329,7 @@ int my_pthread_cond_noposix_init(pthread_cond_t *mp,
this has to be added here.
****************************************************************************/
-#if defined(HPUX10) || defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT)
+#if defined(HPUX10)
int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
struct timespec *abstime)
@@ -535,13 +400,7 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex)
/* Some help functions */
-int pthread_no_free(void *not_used __attribute__((unused)))
-{
- return 0;
-}
-
int pthread_dummy(int ret)
{
return ret;
}
-#endif /* THREAD */
diff --git a/mysys/my_quick.c b/mysys/my_quick.c
index b93e7e17224..2d5e9fb95ca 100644
--- a/mysys/my_quick.c
+++ b/mysys/my_quick.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2006, 2007 MySQL AB, 2009 Sun Microsystems, Inc.
+ 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
@@ -11,7 +12,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* Quicker interface to read & write. Used with my_nosys.h */
diff --git a/mysys/my_rdtsc.c b/mysys/my_rdtsc.c
new file mode 100644
index 00000000000..028c7f810d4
--- /dev/null
+++ b/mysys/my_rdtsc.c
@@ -0,0 +1,962 @@
+/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+/*
+ rdtsc3 -- multi-platform timer code
+ pgulutzan@mysql.com, 2005-08-29
+ modified 2008-11-02
+
+ Functions:
+
+ my_timer_cycles ulonglong cycles
+ my_timer_nanoseconds ulonglong nanoseconds
+ my_timer_microseconds ulonglong "microseconds"
+ my_timer_milliseconds ulonglong milliseconds
+ my_timer_ticks ulonglong ticks
+ my_timer_init initialization / test
+
+ We'll call the first 5 functions (the ones that return
+ a ulonglong) "my_timer_xxx" functions.
+ Each my_timer_xxx function returns a 64-bit timing value
+ since an arbitrary 'epoch' start. Since the only purpose
+ is to determine elapsed times, wall-clock time-of-day
+ is not known and not relevant.
+
+ The my_timer_init function is necessary for initializing.
+ It returns information (underlying routine name,
+ frequency, resolution, overhead) about all my_timer_xxx
+ functions. A program should call my_timer_init once,
+ use the information to decide what my_timer_xxx function
+ to use, and subsequently call that function by function
+ pointer.
+
+ A typical use would be:
+ my_timer_init() ... once, at program start
+ ...
+ time1= my_timer_xxx() ... time before start
+ [code that's timed]
+ time2= my_timer_xxx() ... time after end
+ elapsed_time= (time2 - time1) - overhead
+*/
+
+#include "my_global.h"
+#include "my_rdtsc.h"
+
+#if defined(_WIN32)
+#include <stdio.h>
+#include "windows.h"
+#else
+#include <stdio.h>
+#endif
+
+#if !defined(_WIN32)
+#if TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h> /* for clock_gettime */
+#else
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#elif defined(HAVE_TIME_H)
+#include <time.h>
+#endif
+#endif
+#endif
+
+#if defined(HAVE_ASM_MSR_H) && defined(HAVE_RDTSCLL)
+#include <asm/msr.h> /* for rdtscll */
+#endif
+
+#if defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME)
+#include <sys/timeb.h> /* for ftime */
+#endif
+
+#if defined(HAVE_SYS_TIMES_H) && defined(HAVE_TIMES)
+#include <sys/times.h> /* for times */
+#endif
+
+#if defined(__INTEL_COMPILER) && defined(__ia64__) && defined(HAVE_IA64INTRIN_H)
+#include <ia64intrin.h> /* for __GetReg */
+#endif
+
+#if defined(__APPLE__) && defined(__MACH__)
+#include <mach/mach_time.h>
+#endif
+
+#if defined(__SUNPRO_CC) && defined(__sparcv9) && defined(_LP64) && !defined(__SunOS_5_7)
+extern "C" ulonglong my_timer_cycles_il_sparc64();
+#elif defined(__SUNPRO_CC) && defined(_ILP32) && !defined(__SunOS_5_7)
+extern "C" ulonglong my_timer_cycles_il_sparc32();
+#elif defined(__SUNPRO_CC) && defined(__i386) && defined(_ILP32)
+extern "C" ulonglong my_timer_cycles_il_i386();
+#elif defined(__SUNPRO_CC) && defined(__x86_64) && defined(_LP64)
+extern "C" ulonglong my_timer_cycles_il_x86_64();
+#elif defined(__SUNPRO_C) && defined(__sparcv9) && defined(_LP64) && !defined(__SunOS_5_7)
+ulonglong my_timer_cycles_il_sparc64();
+#elif defined(__SUNPRO_C) && defined(_ILP32) && !defined(__SunOS_5_7)
+ulonglong my_timer_cycles_il_sparc32();
+#elif defined(__SUNPRO_C) && defined(__i386) && defined(_ILP32)
+ulonglong my_timer_cycles_il_i386();
+#elif defined(__SUNPRO_C) && defined(__x86_64) && defined(_LP64)
+ulonglong my_timer_cycles_il_x86_64();
+#endif
+
+#if defined(__INTEL_COMPILER)
+/*
+ icc warning #1011 is:
+ missing return statement at end of non-void function
+*/
+#pragma warning (disable:1011)
+#endif
+
+/*
+ For cycles, we depend on RDTSC for x86 platforms,
+ or on time buffer (which is not really a cycle count
+ but a separate counter with less than nanosecond
+ resolution) for most PowerPC platforms, or on
+ gethrtime which is okay for hpux and solaris, or on
+ clock_gettime(CLOCK_SGI_CYCLE) for Irix platforms,
+ or on read_real_time for aix platforms. There is
+ nothing for Alpha platforms, they would be tricky.
+*/
+
+ulonglong my_timer_cycles(void)
+{
+#if defined(__GNUC__) && defined(__i386__)
+ /* This works much better if compiled with "gcc -O3". */
+ ulonglong result;
+ __asm__ __volatile__ ("rdtsc" : "=A" (result));
+ return result;
+#elif defined(__SUNPRO_C) && defined(__i386)
+ __asm("rdtsc");
+#elif defined(__GNUC__) && defined(__x86_64__)
+ ulonglong result;
+ __asm__ __volatile__ ("rdtsc\n\t" \
+ "shlq $32,%%rdx\n\t" \
+ "orq %%rdx,%%rax"
+ : "=a" (result) :: "%edx");
+ return result;
+#elif defined(HAVE_ASM_MSR_H) && defined(HAVE_RDTSCLL)
+ {
+ ulonglong result;
+ rdtscll(result);
+ return result;
+ }
+#elif defined(_WIN32) && defined(_M_IX86)
+ __asm {rdtsc};
+#elif defined(_WIN64) && defined(_M_X64)
+ /* For 64-bit Windows: unsigned __int64 __rdtsc(); */
+ return __rdtsc();
+#elif defined(__INTEL_COMPILER) && defined(__ia64__) && defined(HAVE_IA64INTRIN_H)
+ return (ulonglong) __getReg(_IA64_REG_AR_ITC); /* (3116) */
+#elif defined(__GNUC__) && defined(__ia64__)
+ {
+ ulonglong result;
+ __asm __volatile__ ("mov %0=ar.itc" : "=r" (result));
+ return result;
+ }
+#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__) || (defined(_POWER) && defined(_AIX52))) && (defined(__64BIT__) || defined(_ARCH_PPC64))
+ {
+ ulonglong result;
+ __asm __volatile__ ("mftb %0" : "=r" (result));
+ return result;
+ }
+#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__) || (defined(_POWER) && defined(_AIX52))) && (!defined(__64BIT__) && !defined(_ARCH_PPC64))
+ {
+ /*
+ mftbu means "move from time-buffer-upper to result".
+ The loop is saying: x1=upper, x2=lower, x3=upper,
+ if x1!=x3 there was an overflow so repeat.
+ */
+ unsigned int x1, x2, x3;
+ ulonglong result;
+ for (;;)
+ {
+ __asm __volatile__ ( "mftbu %0" : "=r"(x1) );
+ __asm __volatile__ ( "mftb %0" : "=r"(x2) );
+ __asm __volatile__ ( "mftbu %0" : "=r"(x3) );
+ if (x1 == x3) break;
+ }
+ result = x1;
+ return ( result << 32 ) | x2;
+ }
+#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__sparcv9) && defined(_LP64) && !defined(__SunOS_5_7)
+ return (my_timer_cycles_il_sparc64());
+#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(_ILP32) && !defined(__SunOS_5_7)
+ return (my_timer_cycles_il_sparc32());
+#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__i386) && defined(_ILP32)
+ /* This is probably redundant for __SUNPRO_C. */
+ return (my_timer_cycles_il_i386());
+#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__x86_64) && defined(_LP64)
+ return (my_timer_cycles_il_x86_64());
+#elif defined(__GNUC__) && defined(__sparcv9) && defined(_LP64) && (__GNUC__>2)
+ {
+ ulonglong result;
+ __asm __volatile__ ("rd %%tick,%0" : "=r" (result));
+ return result;
+ }
+#elif defined(__GNUC__) && defined(__sparc__) && !defined(_LP64) && (__GNUC__>2)
+ {
+ union {
+ ulonglong wholeresult;
+ struct {
+ ulong high;
+ ulong low;
+ } splitresult;
+ } result;
+ __asm __volatile__ ("rd %%tick,%1; srlx %1,32,%0" : "=r" (result.splitresult.high), "=r" (result.splitresult.low));
+ return result.wholeresult;
+ }
+#elif defined(__sgi) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_SGI_CYCLE)
+ {
+ struct timespec tp;
+ clock_gettime(CLOCK_SGI_CYCLE, &tp);
+ return (ulonglong) tp.tv_sec * 1000000000 + (ulonglong) tp.tv_nsec;
+ }
+#elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
+ /* gethrtime may appear as either cycle or nanosecond counter */
+ return (ulonglong) gethrtime();
+#else
+ return 0;
+#endif
+}
+
+#if defined(__INTEL_COMPILER)
+/* re-enable warning#1011 which was only for my_timer_cycles() */
+/* There may be an icc bug which means we must leave disabled. */
+#pragma warning (default:1011)
+#endif
+
+/*
+ For nanoseconds, most platforms have nothing available that
+ (a) doesn't require bringing in a 40-kb librt.so library
+ (b) really has nanosecond resolution.
+*/
+
+ulonglong my_timer_nanoseconds(void)
+{
+#if defined(HAVE_READ_REAL_TIME)
+ {
+ timebasestruct_t tr;
+ read_real_time(&tr, TIMEBASE_SZ);
+ return (ulonglong) tr.tb_high * 1000000000 + (ulonglong) tr.tb_low;
+ }
+#elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
+ /* SunOS 5.10+, Solaris, HP-UX: hrtime_t gethrtime(void) */
+ return (ulonglong) gethrtime();
+#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
+ {
+ struct timespec tp;
+ clock_gettime(CLOCK_REALTIME, &tp);
+ return (ulonglong) tp.tv_sec * 1000000000 + (ulonglong) tp.tv_nsec;
+ }
+#elif defined(__APPLE__) && defined(__MACH__)
+ {
+ ulonglong tm;
+ static mach_timebase_info_data_t timebase_info= {0,0};
+ if (timebase_info.denom == 0)
+ (void) mach_timebase_info(&timebase_info);
+ tm= mach_absolute_time();
+ return (tm * timebase_info.numer) / timebase_info.denom;
+ }
+#else
+ return 0;
+#endif
+}
+
+/*
+ For microseconds, gettimeofday() is available on
+ almost all platforms. On Windows we use
+ QueryPerformanceCounter which will usually tick over
+ 3.5 million times per second, and we don't throw
+ away the extra precision. (On Windows Server 2003
+ the frequency is same as the cycle frequency.)
+*/
+
+ulonglong my_timer_microseconds(void)
+{
+#if defined(HAVE_GETTIMEOFDAY)
+ {
+ static ulonglong last_value= 0;
+ struct timeval tv;
+ if (gettimeofday(&tv, NULL) == 0)
+ last_value= (ulonglong) tv.tv_sec * 1000000 + (ulonglong) tv.tv_usec;
+ else
+ {
+ /*
+ There are reports that gettimeofday(2) can have intermittent failures
+ on some platform, see for example Bug#36819.
+ We are not trying again or looping, just returning the best value possible
+ under the circumstances ...
+ */
+ last_value++;
+ }
+ return last_value;
+ }
+#elif defined(_WIN32)
+ {
+ /* QueryPerformanceCounter usually works with about 1/3 microsecond. */
+ LARGE_INTEGER t_cnt;
+
+ QueryPerformanceCounter(&t_cnt);
+ return (ulonglong) t_cnt.QuadPart;
+ }
+#else
+ return 0;
+#endif
+}
+
+/*
+ For milliseconds, we use ftime() if it's supported
+ or time()*1000 if it's not. With modern versions of
+ Windows and with HP Itanium, resolution is 10-15
+ milliseconds.
+*/
+
+ulonglong my_timer_milliseconds(void)
+{
+#if defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME)
+ /* ftime() is obsolete but maybe the platform is old */
+ struct timeb ft;
+ ftime(&ft);
+ return (ulonglong)ft.time * 1000 + (ulonglong)ft.millitm;
+#elif defined(HAVE_TIME)
+ return (ulonglong) time(NULL) * 1000;
+#elif defined(_WIN32)
+ FILETIME ft;
+ GetSystemTimeAsFileTime( &ft );
+ return ((ulonglong)ft.dwLowDateTime +
+ (((ulonglong)ft.dwHighDateTime) << 32))/10000;
+#else
+ return 0;
+#endif
+}
+
+/*
+ For ticks, which we handle with times(), the frequency
+ is usually 100/second and the overhead is surprisingly
+ bad, sometimes even worse than gettimeofday's overhead.
+*/
+
+ulonglong my_timer_ticks(void)
+{
+#if defined(HAVE_SYS_TIMES_H) && defined(HAVE_TIMES)
+ {
+ struct tms times_buf;
+ return (ulonglong) times(&times_buf);
+ }
+#elif defined(_WIN32)
+ return (ulonglong) GetTickCount();
+#else
+ return 0;
+#endif
+}
+
+/*
+ The my_timer_init() function and its sub-functions
+ have several loops which call timers. If there's
+ something wrong with a timer -- which has never
+ happened in tests -- we want the loop to end after
+ an arbitrary number of iterations, and my_timer_info
+ will show a discouraging result. The arbitrary
+ number is 1,000,000.
+*/
+#define MY_TIMER_ITERATIONS 1000000
+
+/*
+ Calculate overhead. Called from my_timer_init().
+ Usually best_timer_overhead = cycles.overhead or
+ nanoseconds.overhead, so returned amount is in
+ cycles or nanoseconds. We repeat the calculation
+ ten times, so that we can disregard effects of
+ caching or interrupts. Result is quite consistent
+ for cycles, at least. But remember it's a minimum.
+*/
+
+static void my_timer_init_overhead(ulonglong *overhead,
+ ulonglong (*cycle_timer)(void),
+ ulonglong (*this_timer)(void),
+ ulonglong best_timer_overhead)
+{
+ ulonglong time1, time2;
+ int i;
+
+ /* *overhead, least of 20 calculations - cycles.overhead */
+ for (i= 0, *overhead= 1000000000; i < 20; ++i)
+ {
+ time1= cycle_timer();
+ this_timer(); /* rather than 'time_tmp= timer();' */
+ time2= cycle_timer() - time1;
+ if (*overhead > time2)
+ *overhead= time2;
+ }
+ *overhead-= best_timer_overhead;
+}
+
+/*
+ Calculate Resolution. Called from my_timer_init().
+ If a timer goes up by jumps, e.g. 1050, 1075, 1100, ...
+ then the best resolution is the minimum jump, e.g. 25.
+ If it's always divisible by 1000 then it's just a
+ result of multiplication of a lower-precision timer
+ result, e.g. nanoseconds are often microseconds * 1000.
+ If the minimum jump is less than an arbitrary passed
+ figure (a guess based on maximum overhead * 2), ignore.
+ Usually we end up with nanoseconds = 1 because it's too
+ hard to detect anything <= 100 nanoseconds.
+ Often GetTickCount() has resolution = 15.
+ We don't check with ticks because they take too long.
+*/
+static ulonglong my_timer_init_resolution(ulonglong (*this_timer)(void),
+ ulonglong overhead_times_2)
+{
+ ulonglong time1, time2;
+ ulonglong best_jump;
+ int i, jumps, divisible_by_1000, divisible_by_1000000;
+
+ divisible_by_1000= divisible_by_1000000= 0;
+ best_jump= 1000000;
+ for (i= jumps= 0; jumps < 3 && i < MY_TIMER_ITERATIONS * 10; ++i)
+ {
+ time1= this_timer();
+ time2= this_timer();
+ time2-= time1;
+ if (time2)
+ {
+ ++jumps;
+ if (!(time2 % 1000))
+ {
+ ++divisible_by_1000;
+ if (!(time2 % 1000000))
+ ++divisible_by_1000000;
+ }
+ if (best_jump > time2)
+ best_jump= time2;
+ /* For milliseconds, one jump is enough. */
+ if (overhead_times_2 == 0)
+ break;
+ }
+ }
+ if (jumps == 3)
+ {
+ if (jumps == divisible_by_1000000)
+ return 1000000;
+ if (jumps == divisible_by_1000)
+ return 1000;
+ }
+ if (best_jump > overhead_times_2)
+ return best_jump;
+ return 1;
+}
+
+/*
+ Calculate cycle frequency by seeing how many cycles pass
+ in a 200-microsecond period. I tried with 10-microsecond
+ periods originally, and the result was often very wrong.
+*/
+
+static ulonglong my_timer_init_frequency(MY_TIMER_INFO *mti)
+{
+ int i;
+ ulonglong time1, time2, time3, time4;
+ time1= my_timer_cycles();
+ time2= my_timer_microseconds();
+ time3= time2; /* Avoids a Microsoft/IBM compiler warning */
+ for (i= 0; i < MY_TIMER_ITERATIONS; ++i)
+ {
+ time3= my_timer_microseconds();
+ if (time3 - time2 > 200) break;
+ }
+ time4= my_timer_cycles() - mti->cycles.overhead;
+ time4-= mti->microseconds.overhead;
+ return (mti->microseconds.frequency * (time4 - time1)) / (time3 - time2);
+}
+
+/*
+ Call my_timer_init before the first call to my_timer_xxx().
+ If something must be initialized, it happens here.
+ Set: what routine is being used e.g. "asm_x86"
+ Set: function, overhead, actual frequency, resolution.
+*/
+
+void my_timer_init(MY_TIMER_INFO *mti)
+{
+ ulonglong (*best_timer)(void);
+ ulonglong best_timer_overhead;
+ ulonglong time1, time2;
+ int i;
+
+ /* cycles */
+ mti->cycles.frequency= 1000000000;
+#if defined(__GNUC__) && defined(__i386__)
+ mti->cycles.routine= MY_TIMER_ROUTINE_ASM_X86;
+#elif defined(__SUNPRO_C) && defined(__i386)
+ mti->cycles.routine= MY_TIMER_ROUTINE_ASM_X86;
+#elif defined(__GNUC__) && defined(__x86_64__)
+ mti->cycles.routine= MY_TIMER_ROUTINE_ASM_X86_64;
+#elif defined(HAVE_ASM_MSR_H) && defined(HAVE_RDTSCLL)
+ mti->cycles.routine= MY_TIMER_ROUTINE_RDTSCLL;
+#elif defined(_WIN32) && defined(_M_IX86)
+ mti->cycles.routine= MY_TIMER_ROUTINE_ASM_X86_WIN;
+#elif defined(_WIN64) && defined(_M_X64)
+ mti->cycles.routine= MY_TIMER_ROUTINE_RDTSC;
+#elif defined(__INTEL_COMPILER) && defined(__ia64__) && defined(HAVE_IA64INTRIN_H)
+ mti->cycles.routine= MY_TIMER_ROUTINE_ASM_IA64;
+#elif defined(__GNUC__) && defined(__ia64__)
+ mti->cycles.routine= MY_TIMER_ROUTINE_ASM_IA64;
+#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__) || (defined(_POWER) && defined(_AIX52))) && (defined(__64BIT__) || defined(_ARCH_PPC64))
+ mti->cycles.routine= MY_TIMER_ROUTINE_ASM_PPC64;
+#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__) || (defined(_POWER) && defined(_AIX52))) && (!defined(__64BIT__) && !defined(_ARCH_PPC64))
+ mti->cycles.routine= MY_TIMER_ROUTINE_ASM_PPC;
+#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__sparcv9) && defined(_LP64) && !defined(__SunOS_5_7)
+ mti->cycles.routine= MY_TIMER_ROUTINE_ASM_SUNPRO_SPARC64;
+#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(_ILP32) && !defined(__SunOS_5_7)
+ mti->cycles.routine= MY_TIMER_ROUTINE_ASM_SUNPRO_SPARC32;
+#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__i386) && defined(_ILP32)
+ mti->cycles.routine= MY_TIMER_ROUTINE_ASM_SUNPRO_I386;
+#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__x86_64) && defined(_LP64)
+ mti->cycles.routine= MY_TIMER_ROUTINE_ASM_SUNPRO_X86_64;
+#elif defined(__GNUC__) && defined(__sparcv9) && defined(_LP64) && (__GNUC__>2)
+ mti->cycles.routine= MY_TIMER_ROUTINE_ASM_GCC_SPARC64;
+#elif defined(__GNUC__) && defined(__sparc__) && !defined(_LP64) && (__GNUC__>2)
+ mti->cycles.routine= MY_TIMER_ROUTINE_ASM_GCC_SPARC32;
+#elif defined(__sgi) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_SGI_CYCLE)
+ mti->cycles.routine= MY_TIMER_ROUTINE_SGI_CYCLE;
+#elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
+ mti->cycles.routine= MY_TIMER_ROUTINE_GETHRTIME;
+#else
+ mti->cycles.routine= 0;
+#endif
+
+ if (!mti->cycles.routine || !my_timer_cycles())
+ {
+ mti->cycles.routine= 0;
+ mti->cycles.resolution= 0;
+ mti->cycles.frequency= 0;
+ mti->cycles.overhead= 0;
+ }
+
+ /* nanoseconds */
+ mti->nanoseconds.frequency= 1000000000; /* initial assumption */
+#if defined(HAVE_READ_REAL_TIME)
+ mti->nanoseconds.routine= MY_TIMER_ROUTINE_READ_REAL_TIME;
+#elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
+ mti->nanoseconds.routine= MY_TIMER_ROUTINE_GETHRTIME;
+#elif defined(HAVE_CLOCK_GETTIME)
+ mti->nanoseconds.routine= MY_TIMER_ROUTINE_CLOCK_GETTIME;
+#elif defined(__APPLE__) && defined(__MACH__)
+ mti->nanoseconds.routine= MY_TIMER_ROUTINE_MACH_ABSOLUTE_TIME;
+#else
+ mti->nanoseconds.routine= 0;
+#endif
+ if (!mti->nanoseconds.routine || !my_timer_nanoseconds())
+ {
+ mti->nanoseconds.routine= 0;
+ mti->nanoseconds.resolution= 0;
+ mti->nanoseconds.frequency= 0;
+ mti->nanoseconds.overhead= 0;
+ }
+
+ /* microseconds */
+ mti->microseconds.frequency= 1000000; /* initial assumption */
+#if defined(HAVE_GETTIMEOFDAY)
+ mti->microseconds.routine= MY_TIMER_ROUTINE_GETTIMEOFDAY;
+#elif defined(_WIN32)
+ {
+ LARGE_INTEGER li;
+ /* Windows: typical frequency = 3579545, actually 1/3 microsecond. */
+ if (!QueryPerformanceFrequency(&li))
+ mti->microseconds.routine= 0;
+ else
+ {
+ mti->microseconds.frequency= li.QuadPart;
+ mti->microseconds.routine= MY_TIMER_ROUTINE_QUERYPERFORMANCECOUNTER;
+ }
+ }
+#else
+ mti->microseconds.routine= 0;
+#endif
+ if (!mti->microseconds.routine || !my_timer_microseconds())
+ {
+ mti->microseconds.routine= 0;
+ mti->microseconds.resolution= 0;
+ mti->microseconds.frequency= 0;
+ mti->microseconds.overhead= 0;
+ }
+
+ /* milliseconds */
+ mti->milliseconds.frequency= 1000; /* initial assumption */
+#if defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME)
+ mti->milliseconds.routine= MY_TIMER_ROUTINE_FTIME;
+#elif defined(_WIN32)
+ mti->milliseconds.routine= MY_TIMER_ROUTINE_GETSYSTEMTIMEASFILETIME;
+#elif defined(HAVE_TIME)
+ mti->milliseconds.routine= MY_TIMER_ROUTINE_TIME;
+#else
+ mti->milliseconds.routine= 0;
+#endif
+ if (!mti->milliseconds.routine || !my_timer_milliseconds())
+ {
+ mti->milliseconds.routine= 0;
+ mti->milliseconds.resolution= 0;
+ mti->milliseconds.frequency= 0;
+ mti->milliseconds.overhead= 0;
+ }
+
+ /* ticks */
+ mti->ticks.frequency= 100; /* permanent assumption */
+#if defined(HAVE_SYS_TIMES_H) && defined(HAVE_TIMES)
+ mti->ticks.routine= MY_TIMER_ROUTINE_TIMES;
+#elif defined(_WIN32)
+ mti->ticks.routine= MY_TIMER_ROUTINE_GETTICKCOUNT;
+#else
+ mti->ticks.routine= 0;
+#endif
+ if (!mti->ticks.routine || !my_timer_ticks())
+ {
+ mti->ticks.routine= 0;
+ mti->ticks.resolution= 0;
+ mti->ticks.frequency= 0;
+ mti->ticks.overhead= 0;
+ }
+
+ /*
+ Calculate overhead in terms of the timer that
+ gives the best resolution: cycles or nanoseconds.
+ I doubt it ever will be as bad as microseconds.
+ */
+ if (mti->cycles.routine)
+ best_timer= &my_timer_cycles;
+ else
+ {
+ if (mti->nanoseconds.routine)
+ {
+ best_timer= &my_timer_nanoseconds;
+ }
+ else
+ best_timer= &my_timer_microseconds;
+ }
+
+ /* best_timer_overhead = least of 20 calculations */
+ for (i= 0, best_timer_overhead= 1000000000; i < 20; ++i)
+ {
+ time1= best_timer();
+ time2= best_timer() - time1;
+ if (best_timer_overhead > time2)
+ best_timer_overhead= time2;
+ }
+ if (mti->cycles.routine)
+ my_timer_init_overhead(&mti->cycles.overhead,
+ best_timer,
+ &my_timer_cycles,
+ best_timer_overhead);
+ if (mti->nanoseconds.routine)
+ my_timer_init_overhead(&mti->nanoseconds.overhead,
+ best_timer,
+ &my_timer_nanoseconds,
+ best_timer_overhead);
+ if (mti->microseconds.routine)
+ my_timer_init_overhead(&mti->microseconds.overhead,
+ best_timer,
+ &my_timer_microseconds,
+ best_timer_overhead);
+ if (mti->milliseconds.routine)
+ my_timer_init_overhead(&mti->milliseconds.overhead,
+ best_timer,
+ &my_timer_milliseconds,
+ best_timer_overhead);
+ if (mti->ticks.routine)
+ my_timer_init_overhead(&mti->ticks.overhead,
+ best_timer,
+ &my_timer_ticks,
+ best_timer_overhead);
+
+/*
+ Calculate resolution for nanoseconds or microseconds
+ or milliseconds, by seeing if it's always divisible
+ by 1000, and by noticing how much jumping occurs.
+ For ticks, just assume the resolution is 1.
+*/
+ if (mti->cycles.routine)
+ mti->cycles.resolution= 1;
+ if (mti->nanoseconds.routine)
+ mti->nanoseconds.resolution=
+ my_timer_init_resolution(&my_timer_nanoseconds, 20000);
+ if (mti->microseconds.routine)
+ mti->microseconds.resolution=
+ my_timer_init_resolution(&my_timer_microseconds, 20);
+ if (mti->milliseconds.routine)
+ {
+ if (mti->milliseconds.routine == MY_TIMER_ROUTINE_TIME)
+ mti->milliseconds.resolution= 1000;
+ else
+ mti->milliseconds.resolution=
+ my_timer_init_resolution(&my_timer_milliseconds, 0);
+ }
+ if (mti->ticks.routine)
+ mti->ticks.resolution= 1;
+
+/*
+ Calculate cycles frequency,
+ if we have both a cycles routine and a microseconds routine.
+ In tests, this usually results in a figure within 2% of
+ what "cat /proc/cpuinfo" says.
+ If the microseconds routine is QueryPerformanceCounter
+ (i.e. it's Windows), and the microseconds frequency is >
+ 500,000,000 (i.e. it's Windows Server so it uses RDTSC)
+ and the microseconds resolution is > 100 (i.e. dreadful),
+ then calculate cycles frequency = microseconds frequency.
+*/
+ if (mti->cycles.routine
+ && mti->microseconds.routine)
+ {
+ if (mti->microseconds.routine ==
+ MY_TIMER_ROUTINE_QUERYPERFORMANCECOUNTER
+ && mti->microseconds.frequency > 500000000
+ && mti->microseconds.resolution > 100)
+ mti->cycles.frequency= mti->microseconds.frequency;
+ else
+ {
+ ulonglong time1, time2;
+ time1= my_timer_init_frequency(mti);
+ /* Repeat once in case there was an interruption. */
+ time2= my_timer_init_frequency(mti);
+ if (time1 < time2) mti->cycles.frequency= time1;
+ else mti->cycles.frequency= time2;
+ }
+ }
+
+/*
+ Calculate milliseconds frequency =
+ (cycles-frequency/#-of-cycles) * #-of-milliseconds,
+ if we have both a milliseconds routine and a cycles
+ routine.
+ This will be inaccurate if milliseconds resolution > 1.
+ This is probably only useful when testing new platforms.
+*/
+ if (mti->milliseconds.routine
+ && mti->milliseconds.resolution < 1000
+ && mti->microseconds.routine
+ && mti->cycles.routine)
+ {
+ int i;
+ ulonglong time1, time2, time3, time4;
+ time1= my_timer_cycles();
+ time2= my_timer_milliseconds();
+ time3= time2; /* Avoids a Microsoft/IBM compiler warning */
+ for (i= 0; i < MY_TIMER_ITERATIONS * 1000; ++i)
+ {
+ time3= my_timer_milliseconds();
+ if (time3 - time2 > 10) break;
+ }
+ time4= my_timer_cycles();
+ mti->milliseconds.frequency=
+ (mti->cycles.frequency * (time3 - time2)) / (time4 - time1);
+ }
+
+/*
+ Calculate ticks.frequency =
+ (cycles-frequency/#-of-cycles * #-of-ticks,
+ if we have both a ticks routine and a cycles
+ routine,
+ This is probably only useful when testing new platforms.
+*/
+ if (mti->ticks.routine
+ && mti->microseconds.routine
+ && mti->cycles.routine)
+ {
+ int i;
+ ulonglong time1, time2, time3, time4;
+ time1= my_timer_cycles();
+ time2= my_timer_ticks();
+ time3= time2; /* Avoids a Microsoft/IBM compiler warning */
+ for (i= 0; i < MY_TIMER_ITERATIONS * 1000; ++i)
+ {
+ time3= my_timer_ticks();
+ if (time3 - time2 > 10) break;
+ }
+ time4= my_timer_cycles();
+ mti->ticks.frequency=
+ (mti->cycles.frequency * (time3 - time2)) / (time4 - time1);
+ }
+}
+
+/*
+ Additional Comments
+ -------------------
+
+ This is for timing, i.e. finding out how long a piece of code
+ takes. If you want time of day matching a wall clock, the
+ my_timer_xxx functions won't help you.
+
+ The best timer is the one with highest frequency, lowest
+ overhead, and resolution=1. The my_timer_info() routine will tell
+ you at runtime which timer that is. Usually it will be
+ my_timer_cycles() but be aware that, although it's best,
+ it has possible flaws and dangers. Depending on platform:
+ - The frequency might change. We don't test for this. It
+ happens on laptops for power saving, and on blade servers
+ for avoiding overheating.
+ - The overhead that my_timer_init() returns is the minimum.
+ In fact it could be slightly greater because of caching or
+ because you call the routine by address, as recommended.
+ It could be hugely greater if there's an interrupt.
+ - The x86 cycle counter, RDTSC doesn't "serialize". That is,
+ if there is out-of-order execution, rdtsc might be processed
+ after an instruction that logically follows it.
+ (We could force serialization, but that would be slower.)
+ - It is possible to set a flag which renders RDTSC
+ inoperative. Somebody responsible for the kernel
+ of the operating system would have to make this
+ decision. For the platforms we've tested with, there's
+ no such problem.
+ - With a multi-processor arrangement, it's possible
+ to get the cycle count from one processor in
+ thread X, and the cycle count from another processor
+ in thread Y. They may not always be in synch.
+ - You can't depend on a cycle counter being available for
+ all platforms. On Alphas, the
+ cycle counter is only 32-bit, so it would overflow quickly,
+ so we don't bother with it. On platforms that we haven't
+ tested, there might be some if/endif combination that we
+ didn't expect, or some assembler routine that we didn't
+ supply.
+
+ The recommended way to use the timer routines is:
+ 1. Somewhere near the beginning of the program, call
+ my_timer_init(). This should only be necessary once,
+ although you can call it again if you think that the
+ frequency has changed.
+ 2. Determine the best timer based on frequency, resolution,
+ overhead -- all things that my_timer_init() returns.
+ Preserve the address of the timer and the my_timer_into
+ results in an easily-accessible place.
+ 3. Instrument the code section that you're monitoring, thus:
+ time1= my_timer_xxx();
+ Instrumented code;
+ time2= my_timer_xxx();
+ elapsed_time= (time2 - time1) - overhead;
+ If the timer is always on, then overhead is always there,
+ so don't subtract it.
+ 4. Save the elapsed time, or add it to a totaller.
+ 5. When all timing processes are complete, transfer the
+ saved / totalled elapsed time to permanent storage.
+ Optionally you can convert cycles to microseconds at
+ this point. (Don't do so every time you calculate
+ elapsed_time! That would waste time and lose precision!)
+ For converting cycles to microseconds, use the frequency
+ that my_timer_init() returns. You'll also need to convert
+ if the my_timer_microseconds() function is the Windows
+ function QueryPerformanceCounter(), since that's sometimes
+ a counter with precision slightly better than microseconds.
+
+ Since we recommend calls by function pointer, we supply
+ no inline functions.
+
+ Some comments on the many candidate routines for timing ...
+
+ clock() -- We don't use because it would overflow frequently.
+
+ clock_gettime() -- In tests, clock_gettime often had
+ resolution = 1000.
+
+ ftime() -- A "man ftime" says: "This function is obsolete.
+ Don't use it." On every platform that we tested, if ftime()
+ was available, then so was gettimeofday(), and gettimeofday()
+ overhead was always at least as good as ftime() overhead.
+
+ gettimeofday() -- available on most platforms, though not
+ on Windows. There is a hardware timer (sometimes a Programmable
+ Interrupt Timer or "PIT") (sometimes a "HPET") used for
+ interrupt generation. When it interrupts (a "tick" or "jiffy",
+ typically 1 centisecond) it sets xtime. For gettimeofday, a
+ Linux kernel routine usually gets xtime and then gets rdtsc
+ to get elapsed nanoseconds since the last tick. On Red Hat
+ Enterprise Linux 3, there was once a bug which caused the
+ resolution to be 1000, i.e. one centisecond. We never check
+ for time-zone change.
+
+ getnstimeofday() -- something to watch for in future Linux
+
+ do_gettimeofday() -- exists on Linux but not for "userland"
+
+ get_cycles() -- a multi-platform function, worth watching
+ in future Linux versions. But we found platform-specific
+ functions which were better documented in operating-system
+ manuals. And get_cycles() can fail or return a useless
+ 32-bit number. It might be available on some platforms,
+ such as arm, which we didn't test. Using
+ "include <linux/timex.h>" or "include <asm/timex.h>"
+ can lead to autoconf or compile errors, depending on system.
+
+ rdtsc, __rdtsc, rdtscll: available for x86 with Linux BSD,
+ Solaris, Windows. See "possible flaws and dangers" comments.
+
+ times(): what we use for ticks. Should just read the last
+ (xtime) tick count, therefore should be fast, but usually
+ isn't.
+
+ GetTickCount(): we use this for my_timer_ticks() on
+ Windows. Actually it really is a tick counter, so resolution
+ >= 10 milliseconds unless you have a very old Windows version.
+ With Windows 95 or 98 or ME, timeGetTime() has better resolution than
+ GetTickCount (1ms rather than 55ms). But with Windows NT or XP or 2000,
+ they're both getting from a variable in the Process Environment Block
+ (PEB), and the variable is set by the programmable interrupt timer, so
+ the resolution is the same (usually 10-15 milliseconds). Also timeGetTime
+ is slower on old machines:
+ http://www.doumo.jp/aon-java/jsp/postgretips/tips.jsp?tips=74.
+ Also timeGetTime requires linking winmm.lib,
+ Therefore we use GetTickCount.
+ It will overflow every 49 days because the return is 32-bit.
+ There is also a GetTickCount64 but it requires Vista or Windows Server 2008.
+ (As for GetSystemTimeAsFileTime, its precision is spurious, it
+ just reads the tick variable like the other functions do.
+ However, we don't expect it to overflow every 49 days, so we
+ will prefer it for my_timer_milliseconds().)
+
+ QueryPerformanceCounter() we use this for my_timer_microseconds()
+ on Windows. 1-PIT-tick (often 1/3-microsecond). Usually reads
+ the PIT so it's slow. On some Windows variants, uses RDTSC.
+
+ GetLocalTime() this is available on Windows but we don't use it.
+
+ getclock(): documented for Alpha, but not found during tests.
+
+ mach_absolute_time() and UpTime() are recommended for Apple.
+ Inititally they weren't tried, because asm_ppc seems to do the job.
+ But now we use mach_absolute_time for nanoseconds.
+
+ Any clock-based timer can be affected by NPT (ntpd program),
+ which means:
+ - full-second correction can occur for leap second
+ - tiny corrections can occcur approimately every 11 minutes
+ (but I think they only affect the RTC which isn't the PIT).
+
+ We define "precision" as "frequency" and "high precision" is
+ "frequency better than 1 microsecond". We define "resolution"
+ as a synonym for "granularity". We define "accuracy" as
+ "closeness to the truth" as established by some authoritative
+ clock, but we can't measure accuracy.
+
+ Do not expect any of our timers to be monotonic; we
+ won't guarantee that they return constantly-increasing
+ unique numbers.
+
+ We tested with AIX, Solaris (x86 + Sparc), Linux (x86 +
+ Itanium), Windows, 64-bit Windows, QNX, FreeBSD, HPUX,
+ Irix, Mac. We didn't test with SCO.
+
+*/
+
diff --git a/mysys/my_read.c b/mysys/my_read.c
index 8ababb31324..0afbf3773f3 100644
--- a/mysys/my_read.c
+++ b/mysys/my_read.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -37,8 +37,8 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags)
{
size_t readbytes, save_count;
DBUG_ENTER("my_read");
- DBUG_PRINT("my",("fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d",
- Filedes, (long) Buffer, (ulong) Count, MyFlags));
+ DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d",
+ Filedes, Buffer, (ulong) Count, MyFlags));
save_count= Count;
if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP)))
MyFlags|= my_global_flags;
@@ -51,6 +51,7 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags)
#else
readbytes= read(Filedes, Buffer, Count);
#endif
+
if (readbytes != Count)
{
my_errno= errno;
@@ -60,14 +61,14 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags)
DBUG_PRINT("warning",("Read only %d bytes off %lu from %d, errno: %d",
(int) readbytes, (ulong) Count, Filedes,
my_errno));
-#ifdef THREAD
+
if ((readbytes == 0 || (int) readbytes == -1) && errno == EINTR)
{
DBUG_PRINT("debug", ("my_read() was interrupted and returned %ld",
(long) readbytes));
continue; /* Interrupted */
}
-#endif
+
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
{
if (readbytes == (size_t) -1)
diff --git a/mysys/my_realloc.c b/mysys/my_realloc.c
deleted file mode 100644
index 7e49a482884..00000000000
--- a/mysys/my_realloc.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Copyright (C) 2000 MySQL 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* my_global.h may define SAFEMALLOC (through my_config.h). */
-#include <my_global.h>
-
-#ifdef SAFEMALLOC /* We don't need SAFEMALLOC here */
-#undef SAFEMALLOC
-#endif
-
-#include "mysys_priv.h"
-#include "mysys_err.h"
-
- /* My memory re allocator */
-
-/**
- @brief wrapper around realloc()
-
- @param oldpoint pointer to currently allocated area
- @param size new size requested, must be >0
- @param my_flags flags
-
- @note if size==0 realloc() may return NULL; my_realloc() treats this as an
- error which is not the intention of realloc()
-*/
-
-void* my_realloc(void* oldpoint, size_t size, myf my_flags)
-{
- void *point;
- DBUG_ENTER("my_realloc");
- DBUG_PRINT("my",("ptr: 0x%lx size: %lu my_flags: %d", (long) oldpoint,
- (ulong) size, my_flags));
-
- DBUG_ASSERT(size > 0);
- if (!oldpoint && (my_flags & MY_ALLOW_ZERO_PTR))
- DBUG_RETURN(my_malloc(size,my_flags));
-#ifdef USE_HALLOC
- if (!(point = malloc(size)))
- {
- if (my_flags & MY_FREE_ON_ERROR)
- my_free(oldpoint,my_flags);
- if (my_flags & MY_HOLD_ON_ERROR)
- DBUG_RETURN(oldpoint);
- my_errno=errno;
- if (my_flags & MY_FAE+MY_WME)
- my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG),size);
- }
- else
- {
- memcpy(point,oldpoint,size);
- free(oldpoint);
- }
-#else
- if ((point= (uchar*) realloc(oldpoint,size)) == NULL)
- {
- if (my_flags & MY_FREE_ON_ERROR)
- my_free(oldpoint, my_flags);
- if (my_flags & MY_HOLD_ON_ERROR)
- DBUG_RETURN(oldpoint);
- my_errno=errno;
- if (my_flags & (MY_FAE+MY_WME))
- my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG), size);
- }
-#endif
- DBUG_PRINT("exit",("ptr: 0x%lx", (long) point));
- DBUG_RETURN(point);
-} /* my_realloc */
diff --git a/mysys/my_redel.c b/mysys/my_redel.c
index b048c24d942..d096a5c071c 100644
--- a/mysys/my_redel.c
+++ b/mysys/my_redel.c
@@ -12,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -106,7 +105,7 @@ int my_copystat(const char *from, const char *to, int MyFlags)
return -1;
}
-#if !defined(__WIN__) && !defined(__NETWARE__)
+#if !defined(__WIN__)
if (statbuf.st_nlink > 1 && MyFlags & MY_LINK_WARNING)
{
if (MyFlags & MY_LINK_WARNING)
@@ -121,27 +120,16 @@ int my_copystat(const char *from, const char *to, int MyFlags)
if (MyFlags & MY_FAE)
return -1;
}
-#endif /* !__WIN__ && !__NETWARE__ */
+#endif /* !__WIN__ */
-#ifndef VMS
-#ifndef __ZTC__
if (MyFlags & MY_COPYTIME)
{
struct utimbuf timep;
timep.actime = statbuf.st_atime;
timep.modtime = statbuf.st_mtime;
- VOID(utime((char*) to, &timep));/* Update last accessed and modified times */
- }
-#else
- if (MyFlags & MY_COPYTIME)
- {
- time_t time[2];
- time[0]= statbuf.st_atime;
- time[1]= statbuf.st_mtime;
- VOID(utime((char*) to, time));/* Update last accessed and modified times */
+ (void) utime((char*) to, &timep);/* Update last accessed and modified times */
}
-#endif
-#endif
+
return 0;
} /* my_copystat */
diff --git a/mysys/my_rename.c b/mysys/my_rename.c
index 39e6056a9e4..b89bc4c8fbd 100644
--- a/mysys/my_rename.c
+++ b/mysys/my_rename.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include <my_dir.h>
@@ -27,24 +27,8 @@ int my_rename(const char *from, const char *to, myf MyFlags)
DBUG_ENTER("my_rename");
DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));
-#if defined(HAVE_FILE_VERSIONS)
- { /* Check that there isn't a old file */
- int save_errno;
- MY_STAT my_stat_result;
- save_errno=my_errno;
- if (my_stat(to,&my_stat_result,MYF(0)))
- {
- my_errno=EEXIST;
- error= -1;
- if (MyFlags & MY_FAE+MY_WME)
- my_error(EE_LINK, MYF(ME_BELL+ME_WAITTANG),from,to,my_errno);
- DBUG_RETURN(error);
- }
- my_errno=save_errno;
- }
-#endif
#if defined(HAVE_RENAME)
-#if defined(__WIN__) || defined(__NETWARE__)
+#if defined(__WIN__)
/*
On windows we can't rename over an existing file:
Remove any conflicting files:
diff --git a/mysys/my_safehash.c b/mysys/my_safehash.c
index b3d6439793c..1417b8ea94e 100644
--- a/mysys/my_safehash.c
+++ b/mysys/my_safehash.c
@@ -53,7 +53,7 @@
static void safe_hash_entry_free(SAFE_HASH_ENTRY *entry)
{
DBUG_ENTER("safe_hash_entry_free");
- my_free((uchar*) entry, MYF(0));
+ my_free(entry);
DBUG_VOID_RETURN;
}
@@ -100,14 +100,14 @@ my_bool safe_hash_init(SAFE_HASH *hash, uint elements,
uchar *default_value)
{
DBUG_ENTER("safe_hash_init");
- if (hash_init(&hash->hash, &my_charset_bin, elements,
- 0, 0, (hash_get_key) safe_hash_entry_get,
- (void (*)(void*)) safe_hash_entry_free, 0))
+ if (my_hash_init(&hash->hash, &my_charset_bin, elements,
+ 0, 0, (my_hash_get_key) safe_hash_entry_get,
+ (void (*)(void*)) safe_hash_entry_free, 0))
{
hash->default_value= 0;
DBUG_RETURN(1);
}
- my_rwlock_init(&hash->mutex, 0);
+ mysql_rwlock_init(key_SAFEHASH_mutex, &hash->mutex);
hash->default_value= default_value;
hash->root= 0;
DBUG_RETURN(0);
@@ -133,8 +133,8 @@ void safe_hash_free(SAFE_HASH *hash)
*/
if (hash->default_value)
{
- hash_free(&hash->hash);
- rwlock_destroy(&hash->mutex);
+ my_hash_free(&hash->hash);
+ mysql_rwlock_destroy(&hash->mutex);
hash->default_value=0;
}
}
@@ -159,9 +159,9 @@ uchar *safe_hash_search(SAFE_HASH *hash, const uchar *key, uint length,
{
uchar *result;
DBUG_ENTER("safe_hash_search");
- rw_rdlock(&hash->mutex);
- result= hash_search(&hash->hash, key, length);
- rw_unlock(&hash->mutex);
+ mysql_rwlock_rdlock(&hash->mutex);
+ result= my_hash_search(&hash->hash, key, length);
+ mysql_rwlock_unlock(&hash->mutex);
if (!result)
result= def;
else
@@ -199,8 +199,8 @@ my_bool safe_hash_set(SAFE_HASH *hash, const uchar *key, uint length,
DBUG_ENTER("safe_hash_set");
DBUG_PRINT("enter",("key: %.*s data: 0x%lx", length, key, (long) data));
- rw_wrlock(&hash->mutex);
- entry= (SAFE_HASH_ENTRY*) hash_search(&hash->hash, key, length);
+ mysql_rwlock_wrlock(&hash->mutex);
+ entry= (SAFE_HASH_ENTRY*) my_hash_search(&hash->hash, key, length);
if (data == hash->default_value)
{
@@ -214,7 +214,7 @@ my_bool safe_hash_set(SAFE_HASH *hash, const uchar *key, uint length,
/* unlink entry from list */
if ((*entry->prev= entry->next))
entry->next->prev= entry->prev;
- hash_delete(&hash->hash, (uchar*) entry);
+ my_hash_delete(&hash->hash, (uchar*) entry);
goto end;
}
if (entry)
@@ -242,14 +242,14 @@ my_bool safe_hash_set(SAFE_HASH *hash, const uchar *key, uint length,
if (my_hash_insert(&hash->hash, (uchar*) entry))
{
/* This can only happen if hash got out of memory */
- my_free((char*) entry, MYF(0));
+ my_free(entry);
error= 1;
goto end;
}
}
end:
- rw_unlock(&hash->mutex);
+ mysql_rwlock_unlock(&hash->mutex);
DBUG_RETURN(error);
}
@@ -274,7 +274,7 @@ void safe_hash_change(SAFE_HASH *hash, uchar *old_data, uchar *new_data)
SAFE_HASH_ENTRY *entry, *next;
DBUG_ENTER("safe_hash_change");
- rw_wrlock(&hash->mutex);
+ mysql_rwlock_wrlock(&hash->mutex);
for (entry= hash->root ; entry ; entry= next)
{
@@ -285,13 +285,13 @@ void safe_hash_change(SAFE_HASH *hash, uchar *old_data, uchar *new_data)
{
if ((*entry->prev= entry->next))
entry->next->prev= entry->prev;
- hash_delete(&hash->hash, (uchar*) entry);
+ my_hash_delete(&hash->hash, (uchar*) entry);
}
else
entry->data= new_data;
}
}
- rw_unlock(&hash->mutex);
+ mysql_rwlock_unlock(&hash->mutex);
DBUG_VOID_RETURN;
}
diff --git a/mysys/my_safehash.h b/mysys/my_safehash.h
index 8a5856b6763..e52fee68b57 100644
--- a/mysys/my_safehash.h
+++ b/mysys/my_safehash.h
@@ -39,9 +39,7 @@ typedef struct st_safe_hash_entry
typedef struct st_safe_hash_with_default
{
-#ifdef THREAD
- rw_lock_t mutex;
-#endif
+ mysql_rwlock_t mutex;
HASH hash;
uchar *default_value;
SAFE_HASH_ENTRY *root;
diff --git a/mysys/my_seek.c b/mysys/my_seek.c
index bdaf91ccc5a..1033d7ac806 100644
--- a/mysys/my_seek.c
+++ b/mysys/my_seek.c
@@ -12,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -47,11 +46,10 @@
my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags)
{
- reg1 os_off_t newpos= -1;
+ os_off_t newpos= -1;
DBUG_ENTER("my_seek");
- DBUG_PRINT("my",("fd: %d Hpos: %lu Pos: %lu Whence: %d MyFlags: %d",
- fd, (ulong) (((ulonglong) pos) >> 32), (ulong) pos,
- whence, MyFlags));
+ DBUG_PRINT("my",("fd: %d Pos: %llu Whence: %d MyFlags: %d",
+ fd, (ulonglong) pos, whence, MyFlags));
DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */
/*
@@ -68,12 +66,12 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags)
my_errno= errno;
if (MyFlags & MY_WME)
my_error(EE_CANT_SEEK, MYF(0), my_filename(fd), my_errno);
- DBUG_PRINT("error",("lseek: %lu errno: %d", (ulong) newpos,errno));
+ DBUG_PRINT("error", ("lseek: %llu errno: %d", (ulonglong) newpos, errno));
DBUG_RETURN(MY_FILEPOS_ERROR);
}
if ((my_off_t) newpos != pos)
{
- DBUG_PRINT("exit",("pos: %lu", (ulong) newpos));
+ DBUG_PRINT("exit",("pos: %llu", (ulonglong) newpos));
}
DBUG_RETURN((my_off_t) newpos);
} /* my_seek */
@@ -88,20 +86,18 @@ my_off_t my_tell(File fd, myf MyFlags)
DBUG_ENTER("my_tell");
DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags));
DBUG_ASSERT(fd >= 0);
-#ifdef _WIN32
- pos= my_seek(fd, 0, MY_SEEK_CUR,0);
-#elif defined(HAVE_TELL)
- pos=tell(fd);
+#if defined (HAVE_TELL) && !defined (_WIN32)
+ pos= tell(fd);
#else
- pos=lseek(fd, 0L, MY_SEEK_CUR);
+ pos= my_seek(fd, 0L, MY_SEEK_CUR,0);
#endif
if (pos == (os_off_t) -1)
{
my_errno= errno;
if (MyFlags & MY_WME)
my_error(EE_CANT_SEEK, MYF(0), my_filename(fd), my_errno);
- DBUG_PRINT("error", ("tell: %lu errno: %d", (ulong) pos, my_errno));
+ DBUG_PRINT("error", ("tell: %llu errno: %d", (ulonglong) pos, my_errno));
}
- DBUG_PRINT("exit",("pos: %lu", (ulong) pos));
+ DBUG_PRINT("exit",("pos: %llu", (ulonglong) pos));
DBUG_RETURN((my_off_t) pos);
} /* my_tell */
diff --git a/mysys/my_sleep.c b/mysys/my_sleep.c
index cb21c15a925..77eb466aee8 100644
--- a/mysys/my_sleep.c
+++ b/mysys/my_sleep.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* Wait a given number of microseconds */
@@ -20,9 +20,7 @@
void my_sleep(ulong m_seconds)
{
-#ifdef __NETWARE__
- delay(m_seconds/1000+1);
-#elif defined(__WIN__)
+#if defined(__WIN__)
Sleep(m_seconds/1000+1); /* Sleep() has millisecond arg */
#elif defined(HAVE_SELECT)
struct timeval t;
diff --git a/mysys/my_static.c b/mysys/my_static.c
index dd4e4f225c3..bc2d8beac83 100644
--- a/mysys/my_static.c
+++ b/mysys/my_static.c
@@ -13,8 +13,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
Static variables for mysys library. All definied here for easy making of
@@ -30,27 +29,22 @@ my_bool timed_mutexes= 0;
/* from my_init */
char * home_dir=0;
const char *my_progname= NULL, *my_progname_short= NULL;
-char NEAR curr_dir[FN_REFLEN]= {0},
- NEAR home_dir_buff[FN_REFLEN]= {0};
+char curr_dir[FN_REFLEN]= {0},
+ home_dir_buff[FN_REFLEN]= {0};
ulong my_stream_opened=0,my_file_opened=0, my_tmp_file_created=0;
ulong my_file_total_opened= 0;
-int NEAR my_umask=0664, NEAR my_umask_dir=0777;
+int my_umask=0664, my_umask_dir=0777;
+
myf my_global_flags= 0;
my_bool my_assert_on_error= 0;
-#ifndef THREAD
-int NEAR my_errno=0;
-#endif
struct st_my_file_info my_file_info_default[MY_NFILE];
uint my_file_limit= MY_NFILE;
struct st_my_file_info *my_file_info= my_file_info_default;
/* From mf_brkhant */
-int NEAR my_dont_interrupt=0;
+int my_dont_interrupt=0;
volatile int _my_signals=0;
struct st_remember _my_sig_remember[MAX_SIGNALS]={{0,0}};
-#ifdef THREAD
-sigset_t my_signals; /* signals blocked by mf_brkhant */
-#endif
/* from mf_reccache.c */
ulong my_default_record_cache_size=RECORD_CACHE_SIZE;
@@ -70,32 +64,19 @@ my_bool my_use_large_pages= 0;
uint my_large_page_size= 0;
#endif
- /* from safe_malloc */
-uint sf_malloc_prehunc=0, /* If you have problem with core- */
- sf_malloc_endhunc=0, /* dump when malloc-message.... */
- /* set theese to 64 or 128 */
- sf_malloc_quick=0; /* set if no calls to sanity */
-size_t sf_malloc_cur_memory= 0L; /* Current memory usage */
-size_t sf_malloc_max_memory= 0L; /* Maximum memory usage */
-uint sf_malloc_count= 0; /* Number of times NEW() was called */
-uchar *sf_min_adress= (uchar*) ~(unsigned long) 0L,
- *sf_max_adress= (uchar*) 0L;
-/* Root of the linked list of struct st_irem */
-struct st_irem *sf_malloc_root = NULL;
-
/* 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
-char * NEAR globerrs[GLOBERRS]; /* my_error_messages is here */
+const char *globerrs[GLOBERRS]; /* my_error_messages is here */
#endif
void (*my_abort_hook)(int) = (void(*)(int)) exit;
-int (*error_handler_hook)(uint error,const char *str,myf MyFlags)=
- my_message_no_curses;
-int (*fatal_error_handler_hook)(uint error,const char *str,myf MyFlags)=
- my_message_no_curses;
+void (*error_handler_hook)(uint error, const char *str, myf MyFlags)=
+ my_message_stderr;
+void (*fatal_error_handler_hook)(uint error, const char *str, myf MyFlags)=
+ my_message_stderr;
static const char *proc_info_dummy(void *a __attribute__((unused)),
const char *b __attribute__((unused)),
@@ -109,18 +90,39 @@ static const char *proc_info_dummy(void *a __attribute__((unused)),
/* this is to be able to call set_thd_proc_info from the C code */
const char *(*proc_info_hook)(void *, const char *, const char *, const char *,
const unsigned int)= proc_info_dummy;
-#if defined(ENABLED_DEBUG_SYNC)
+void (*debug_sync_C_callback_ptr)(MYSQL_THD, const char *, size_t)= 0;
+
+ /* How to disable options */
+my_bool my_disable_locking=0;
+my_bool my_disable_sync=0;
+my_bool my_disable_async_io=0;
+my_bool my_disable_flush_key_blocks=0;
+my_bool my_disable_symlinks=0;
+
+/*
+ Note that PSI_hook and PSI_server are unconditionally
+ (no ifdef HAVE_PSI_INTERFACE) defined.
+ This is to ensure binary compatibility between the server and plugins,
+ in the case when:
+ - the server is not compiled with HAVE_PSI_INTERFACE
+ - a plugin is compiled with HAVE_PSI_INTERFACE
+ See the doxygen documentation for the performance schema.
+*/
+
/**
- Global pointer to be set if callback function is defined
- (e.g. in mysqld). See sql/debug_sync.cc.
+ Hook for the instrumentation interface.
+ Code implementing the instrumentation interface should register here.
*/
-void (*debug_sync_C_callback_ptr)(const char *, size_t);
-#endif /* defined(ENABLED_DEBUG_SYNC) */
+struct PSI_bootstrap *PSI_hook= NULL;
+
+/**
+ Instance of the instrumentation interface for the MySQL server.
+ @todo This is currently a global variable, which is handy when
+ compiling instrumented code that is bundled with the server.
+ When dynamic plugin are truly supported, this variable will need
+ to be replaced by a macro, so that each XYZ plugin can have it's own
+ xyz_psi_server variable, obtained from PSI_bootstrap::get_interface()
+ with the version used at compile time for plugin XYZ.
+*/
+PSI *PSI_server= NULL;
- /* How to disable options */
-my_bool NEAR my_disable_locking=0;
-my_bool NEAR my_disable_sync=0;
-my_bool NEAR my_disable_async_io=0;
-my_bool NEAR my_disable_flush_key_blocks=0;
-my_bool NEAR my_disable_symlinks=0;
-my_bool NEAR mysys_uses_curses=0;
diff --git a/mysys/my_static.h b/mysys/my_static.h
index 5e853c2a559..a44a4b26c3d 100644
--- a/mysys/my_static.h
+++ b/mysys/my_static.h
@@ -1,4 +1,7 @@
-/* Copyright (C) 2000 MySQL AB
+#ifndef MYSYS_MY_STATIC_INCLUDED
+#define MYSYS_MY_STATIC_INCLUDED
+
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +14,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
Static variables for mysys library. All definied here for easy making of
@@ -22,35 +25,13 @@ C_MODE_START
#include <signal.h>
#define MAX_SIGNALS 10 /* Max signals under a dont-allow */
-#define MIN_KEYBLOCK (min(IO_SIZE,1024))
-#define MAX_KEYBLOCK 8192 /* Max keyblocklength == 8*IO_SIZE */
-#define MAX_BLOCK_TYPES MAX_KEYBLOCK/MIN_KEYBLOCK
struct st_remember {
int number;
sig_handler (*func)(int number);
};
-/*
- Structure that stores information of a allocated memory block
- The data is at &struct_adr+sizeof(ALIGN_SIZE(sizeof(struct irem)))
- The lspecialvalue is at the previous 4 bytes from this, which may not
- necessarily be in the struct if the struct size isn't aligned at a 8 byte
- boundary.
-*/
-
-struct st_irem
-{
- struct st_irem *next; /* Linked list of structures */
- struct st_irem *prev; /* Other link */
- char *filename; /* File in which memory was new'ed */
- size_t datasize; /* Size requested */
- uint32 linenum; /* Line number in above file */
- uint32 SpecialValue; /* Underrun marker value */
-};
-
-
-extern char NEAR curr_dir[FN_REFLEN],NEAR home_dir_buff[FN_REFLEN];
+extern char curr_dir[FN_REFLEN], home_dir_buff[FN_REFLEN];
extern volatile int _my_signals;
extern struct st_remember _my_sig_remember[MAX_SIGNALS];
@@ -60,13 +41,8 @@ extern const char *soundex_map;
extern USED_MEM* my_once_root_block;
extern uint my_once_extra;
-extern uchar *sf_min_adress,*sf_max_adress;
-extern uint sf_malloc_count;
-extern struct st_irem *sf_malloc_root;
-
extern struct st_my_file_info my_file_info_default[MY_NFILE];
-#if defined(THREAD) && !defined(__WIN__)
-extern sigset_t my_signals; /* signals blocked by mf_brkhant */
-#endif
C_MODE_END
+
+#endif /* MYSYS_MY_STATIC_INCLUDED */
diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c
index a788424446a..b0e910f7ba0 100644
--- a/mysys/my_symlink.c
+++ b/mysys/my_symlink.c
@@ -12,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
diff --git a/mysys/my_sync.c b/mysys/my_sync.c
index 33033ff1045..88bcb685271 100644
--- a/mysys/my_sync.c
+++ b/mysys/my_sync.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2003, 2010, Oracle and/or its affiliates
+ Copyright (c) 2003, 2011, Oracle and/or its affiliates
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
@@ -12,15 +12,25 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
#include <errno.h>
+
ulong my_sync_count; /* Count number of sync calls */
+static void (*before_sync_wait)(void)= 0;
+static void (*after_sync_wait)(void)= 0;
+
+void thr_set_sync_wait_callback(void (*before_wait)(void),
+ void (*after_wait)(void))
+{
+ before_sync_wait= before_wait;
+ after_sync_wait= after_wait;
+}
+
/*
Sync data in file to disk
@@ -55,12 +65,19 @@ int my_sync(File fd, myf my_flags)
{
int res;
DBUG_ENTER("my_sync");
+
DBUG_PRINT("my",("fd: %d my_flags: %d", fd, my_flags));
if (my_disable_sync)
DBUG_RETURN(0);
statistic_increment(my_sync_count,&THR_LOCK_open);
+
+ DBUG_PRINT("my",("Fd: %d my_flags: %d", fd, my_flags));
+
+ if (before_sync_wait)
+ (*before_sync_wait)();
+
do
{
#if defined(F_FULLFSYNC)
@@ -83,7 +100,7 @@ int my_sync(File fd, myf my_flags)
res= fsync(fd);
if (res == -1 && errno == ENOLCK)
res= 0; /* Result Bug in Old FreeBSD */
-#elif defined(__WIN__)
+#elif defined(_WIN32)
res= my_win_fsync(fd);
#else
#error Cannot find a way to sync a file, durability in danger
@@ -99,6 +116,8 @@ int my_sync(File fd, myf my_flags)
int er= errno;
if (!(my_errno= er))
my_errno= -1; /* Unknown error */
+ if (after_sync_wait)
+ (*after_sync_wait)();
if ((my_flags & MY_IGNORE_BADFD) &&
(er == EBADF || er == EINVAL || er == EROFS))
{
@@ -108,6 +127,11 @@ int my_sync(File fd, myf my_flags)
else if (my_flags & MY_WME)
my_error(EE_SYNC, MYF(ME_BELL+ME_WAITTANG), my_filename(fd), my_errno);
}
+ else
+ {
+ if (after_sync_wait)
+ (*after_sync_wait)();
+ }
DBUG_RETURN(res);
} /* my_sync */
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 307413faadc..ac16189f3a7 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -1,6 +1,5 @@
-/*
- Copyright (c) 2000-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* Copyright (c) 2000, 2011 Oracle and/or its affiliates.
+ Copyright 2008-2011 Monty Program 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
@@ -13,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
Functions to handle initializating and allocationg of all mysys & debug
@@ -25,27 +23,21 @@
#include <m_string.h>
#include <signal.h>
-#ifdef THREAD
-#ifdef USE_TLS
pthread_key(struct st_my_thread_var*, THR_KEY_mysys);
-#else
-pthread_key(struct st_my_thread_var, THR_KEY_mysys);
-#endif /* USE_TLS */
-pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,
- THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap,
- THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time,
- THR_LOCK_myisam_mmap;
-
-pthread_cond_t THR_COND_threads;
+mysql_mutex_t THR_LOCK_malloc, THR_LOCK_open,
+ THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_myisam, THR_LOCK_heap,
+ THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads,
+ THR_LOCK_myisam_mmap;
+
+mysql_cond_t THR_COND_threads;
uint THR_thread_count= 0;
uint my_thread_end_wait_time= 5;
#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
-pthread_mutex_t LOCK_localtime_r;
+mysql_mutex_t LOCK_localtime_r;
#endif
-#ifndef HAVE_GETHOSTBYNAME_R
-pthread_mutex_t LOCK_gethostbyname_r;
+#ifdef _MSC_VER
+static void install_sigabrt_handler();
#endif
-
#ifdef TARGET_OS_LINUX
/*
@@ -64,39 +56,113 @@ nptl_pthread_exit_hack_handler(void *arg __attribute((unused)))
#endif /* TARGET_OS_LINUX */
+static uint get_thread_lib(void);
-/**
- Initialize thread attributes.
+/** True if @c my_thread_global_init() has been called. */
+static my_bool my_thread_global_init_done= 0;
+
+
+/*
+ These are mutexes not used by safe_mutex or my_thr_init.c
+
+ We want to free these earlier than other mutex so that safe_mutex
+ can detect if all mutex and memory is freed properly.
*/
-void my_threadattr_global_init(void)
+static void my_thread_init_common_mutex(void)
{
-#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
- /*
- Set mutex type to "fast" a.k.a "adaptive"
-
- In this case the thread may steal the mutex from some other thread
- that is waiting for the same mutex. This will save us some
- context switches but may cause a thread to 'starve forever' while
- waiting for the mutex (not likely if the code within the mutex is
- short).
- */
- pthread_mutexattr_init(&my_fast_mutexattr); /* ?= MY_MUTEX_INIT_FAST */
- pthread_mutexattr_settype(&my_fast_mutexattr,
- PTHREAD_MUTEX_ADAPTIVE_NP);
+ mysql_mutex_init(key_THR_LOCK_open, &THR_LOCK_open, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_THR_LOCK_lock, &THR_LOCK_lock, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_THR_LOCK_isam, &THR_LOCK_isam, MY_MUTEX_INIT_SLOW);
+ mysql_mutex_init(key_THR_LOCK_myisam, &THR_LOCK_myisam, MY_MUTEX_INIT_SLOW);
+ mysql_mutex_init(key_THR_LOCK_myisam_mmap, &THR_LOCK_myisam_mmap, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_THR_LOCK_heap, &THR_LOCK_heap, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_THR_LOCK_net, &THR_LOCK_net, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_THR_LOCK_charset, &THR_LOCK_charset, MY_MUTEX_INIT_FAST);
+#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
+ mysql_mutex_init(key_LOCK_localtime_r, &LOCK_localtime_r, MY_MUTEX_INIT_SLOW);
#endif
-#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
- /*
- Set mutex type to "errorcheck"
- */
- pthread_mutexattr_init(&my_errorcheck_mutexattr);
- pthread_mutexattr_settype(&my_errorcheck_mutexattr,
- PTHREAD_MUTEX_ERRORCHECK);
+}
+
+void my_thread_destroy_common_mutex(void)
+{
+ mysql_mutex_destroy(&THR_LOCK_open);
+ mysql_mutex_destroy(&THR_LOCK_lock);
+ mysql_mutex_destroy(&THR_LOCK_isam);
+ mysql_mutex_destroy(&THR_LOCK_myisam);
+ mysql_mutex_destroy(&THR_LOCK_myisam_mmap);
+ mysql_mutex_destroy(&THR_LOCK_heap);
+ mysql_mutex_destroy(&THR_LOCK_net);
+ mysql_mutex_destroy(&THR_LOCK_charset);
+#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
+ mysql_mutex_destroy(&LOCK_localtime_r);
#endif
}
-static uint get_thread_lib(void);
+/*
+ These mutexes are used by my_thread_init() and after
+ my_thread_destroy_mutex()
+*/
+
+static void my_thread_init_internal_mutex(void)
+{
+ mysql_mutex_init(key_THR_LOCK_threads, &THR_LOCK_threads, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_THR_LOCK_malloc, &THR_LOCK_malloc, MY_MUTEX_INIT_FAST);
+ mysql_cond_init(key_THR_COND_threads, &THR_COND_threads, NULL);
+}
+
+
+void my_thread_destroy_internal_mutex(void)
+{
+ mysql_mutex_destroy(&THR_LOCK_threads);
+ mysql_mutex_destroy(&THR_LOCK_malloc);
+ mysql_cond_destroy(&THR_COND_threads);
+}
+
+static void my_thread_init_thr_mutex(struct st_my_thread_var *var)
+{
+ mysql_mutex_init(key_my_thread_var_mutex, &var->mutex, MY_MUTEX_INIT_FAST);
+ mysql_cond_init(key_my_thread_var_suspend, &var->suspend, NULL);
+}
+
+static void my_thread_destory_thr_mutex(struct st_my_thread_var *var)
+{
+ mysql_mutex_destroy(&var->mutex);
+ mysql_cond_destroy(&var->suspend);
+}
+
+
+/**
+ Re-initialize components initialized early with @c my_thread_global_init.
+ Some mutexes were initialized before the instrumentation.
+ Destroy + create them again, now that the instrumentation
+ is in place.
+ This is safe, since this function() is called before creating new threads,
+ so the mutexes are not in use.
+*/
+void my_thread_global_reinit(void)
+{
+ struct st_my_thread_var *tmp;
+
+ DBUG_ASSERT(my_thread_global_init_done);
+
+#ifdef HAVE_PSI_INTERFACE
+ my_init_mysys_psi_keys();
+#endif
+
+ my_thread_destroy_common_mutex();
+ my_thread_init_common_mutex();
+
+ my_thread_destroy_internal_mutex();
+ my_thread_init_internal_mutex();
+
+ tmp= my_pthread_getspecific(struct st_my_thread_var*, THR_KEY_mysys);
+ DBUG_ASSERT(tmp);
+
+ my_thread_destory_thr_mutex(tmp);
+ my_thread_init_thr_mutex(tmp);
+}
/*
initialize thread environment
@@ -112,14 +178,27 @@ static uint get_thread_lib(void);
my_bool my_thread_global_init(void)
{
int pth_ret;
- thd_lib_detected= get_thread_lib();
+
+ /* Normally this should never be called twice */
+ DBUG_ASSERT(my_thread_global_init_done == 0);
+ if (my_thread_global_init_done)
+ return 0;
+ my_thread_global_init_done= 1;
if ((pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0)
{
- fprintf(stderr,"Can't initialize threads: error %d\n", pth_ret);
+ fprintf(stderr, "Can't initialize threads: error %d\n", pth_ret);
return 1;
}
+ /* Mutex used by my_thread_init() and after my_thread_destroy_mutex() */
+ my_thread_init_internal_mutex();
+
+ if (my_thread_init())
+ return 1;
+
+ thd_lib_detected= get_thread_lib();
+
#ifdef TARGET_OS_LINUX
/*
BUG#24507: Race conditions inside current NPTL pthread_exit()
@@ -147,129 +226,57 @@ my_bool my_thread_global_init(void)
}
#endif /* TARGET_OS_LINUX */
- /* Mutex used by my_thread_init() and after my_thread_destroy_mutex() */
- my_pthread_mutex_init(&THR_LOCK_threads, MY_MUTEX_INIT_FAST,
- "THR_LOCK_threads", MYF_NO_DEADLOCK_DETECTION);
- my_pthread_mutex_init(&THR_LOCK_malloc, MY_MUTEX_INIT_FAST,
- "THR_LOCK_malloc", MYF_NO_DEADLOCK_DETECTION);
+ my_thread_init_common_mutex();
- if (my_thread_init())
- return 1;
-
- /* Mutex uses by mysys */
- pthread_mutex_init(&THR_LOCK_open,MY_MUTEX_INIT_FAST);
- pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST);
- pthread_mutex_init(&THR_LOCK_isam,MY_MUTEX_INIT_SLOW);
- pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_SLOW);
- pthread_mutex_init(&THR_LOCK_myisam_mmap,MY_MUTEX_INIT_FAST);
- pthread_mutex_init(&THR_LOCK_heap,MY_MUTEX_INIT_FAST);
- pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST);
- pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST);
- pthread_mutex_init(&THR_LOCK_time,MY_MUTEX_INIT_FAST);
- pthread_cond_init(&THR_COND_threads, NULL);
-#if defined( __WIN__) || defined(OS2)
- win_pthread_init();
-#endif
-#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
- pthread_mutex_init(&LOCK_localtime_r,MY_MUTEX_INIT_SLOW);
-#endif
-#ifndef HAVE_GETHOSTBYNAME_R
- pthread_mutex_init(&LOCK_gethostbyname_r,MY_MUTEX_INIT_SLOW);
-#endif
return 0;
}
/**
- Wait for all threads in system to die
- @fn my_wait_for_other_threads_to_die()
- @param number_of_threads Wait until this number of threads
-
- @retval 0 Less or equal to number_of_threads left
- @retval 1 Wait failed
+ End the mysys thread system. Called when ending the last thread
*/
-my_bool my_wait_for_other_threads_to_die(uint number_of_threads)
+void my_thread_global_end(void)
{
struct timespec abstime;
my_bool all_threads_killed= 1;
set_timespec(abstime, my_thread_end_wait_time);
- pthread_mutex_lock(&THR_LOCK_threads);
- while (THR_thread_count > number_of_threads)
+ mysql_mutex_lock(&THR_LOCK_threads);
+ while (THR_thread_count > 0)
{
- int error= pthread_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads,
- &abstime);
+ int error= mysql_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads,
+ &abstime);
if (error == ETIMEDOUT || error == ETIME)
{
+#ifdef HAVE_PTHREAD_KILL
+ /*
+ We shouldn't give an error here, because if we don't have
+ pthread_kill(), programs like mysqld can't ensure that all threads
+ are killed when we enter here.
+ */
+ if (THR_thread_count)
+ fprintf(stderr,
+ "Error in my_thread_global_end(): %d threads didn't exit\n",
+ THR_thread_count);
+#endif
all_threads_killed= 0;
break;
}
}
- pthread_mutex_unlock(&THR_LOCK_threads);
- return all_threads_killed;
-}
-
+ mysql_mutex_unlock(&THR_LOCK_threads);
-/**
- End the mysys thread system. Called when ending the last thread
-*/
-
-
-void my_thread_global_end(void)
-{
- my_bool all_threads_killed;
-
- if (!(all_threads_killed= my_wait_for_other_threads_to_die(0)))
- {
-#ifdef HAVE_PTHREAD_KILL
- /*
- We shouldn't give an error here, because if we don't have
- pthread_kill(), programs like mysqld can't ensure that all threads
- are killed when we enter here.
- */
- if (THR_thread_count)
- fprintf(stderr,
- "Error in my_thread_global_end(): %d threads didn't exit\n",
- THR_thread_count);
-#endif
- }
+ my_thread_destroy_common_mutex();
- pthread_key_delete(THR_KEY_mysys);
+ /*
+ Only destroy the mutex & conditions if we don't have other threads around
+ that could use them.
+ */
if (all_threads_killed)
{
- pthread_mutex_destroy(&THR_LOCK_threads);
- pthread_cond_destroy(&THR_COND_threads);
- pthread_mutex_destroy(&THR_LOCK_malloc);
+ my_thread_destroy_internal_mutex();
}
-}
-
-/* Free all mutex used by mysys */
-
-void my_thread_destroy_mutex(void)
-{
- struct st_my_thread_var *tmp;
- tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
- if (tmp)
- {
- safe_mutex_free_deadlock_data(&tmp->mutex);
- }
-
- pthread_mutex_destroy(&THR_LOCK_open);
- pthread_mutex_destroy(&THR_LOCK_lock);
- pthread_mutex_destroy(&THR_LOCK_isam);
- pthread_mutex_destroy(&THR_LOCK_myisam);
- pthread_mutex_destroy(&THR_LOCK_myisam_mmap);
- pthread_mutex_destroy(&THR_LOCK_heap);
- pthread_mutex_destroy(&THR_LOCK_net);
- pthread_mutex_destroy(&THR_LOCK_time);
- pthread_mutex_destroy(&THR_LOCK_charset);
-#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
- pthread_mutex_destroy(&LOCK_localtime_r);
-#endif
-#ifndef HAVE_GETHOSTBYNAME_R
- pthread_mutex_destroy(&LOCK_gethostbyname_r);
-#endif
+ my_thread_global_init_done= 0;
}
static my_thread_id thread_id= 0;
@@ -300,50 +307,38 @@ my_bool my_thread_init(void)
my_bool error=0;
#ifdef EXTRA_DEBUG_THREADS
- fprintf(stderr,"my_thread_init(): thread_id: 0x%lx\n",
- (ulong) pthread_self());
-#endif
+ fprintf(stderr,"my_thread_init(): pthread_self: %p\n", pthread_self());
+#endif
-#if !defined(__WIN__) || defined(USE_TLS)
if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys))
{
#ifdef EXTRA_DEBUG_THREADS
fprintf(stderr,"my_thread_init() called more than once in thread 0x%lx\n",
(long) pthread_self());
-#endif
+#endif
goto end;
}
+
+#ifdef _MSC_VER
+ install_sigabrt_handler();
+#endif
+
if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp))))
{
error= 1;
goto end;
}
pthread_setspecific(THR_KEY_mysys,tmp);
-
-#else /* defined(__WIN__) && !(defined(USE_TLS) */
- /*
- Skip initialization if the thread specific variable is already initialized
- */
- if (THR_KEY_mysys.init)
- goto end;
- tmp= &THR_KEY_mysys;
-#endif
-#if defined(__WIN__) && defined(EMBEDDED_LIBRARY)
- tmp->pthread_self= (pthread_t) getpid();
-#else
tmp->pthread_self= pthread_self();
-#endif
- my_pthread_mutex_init(&tmp->mutex, MY_MUTEX_INIT_FAST, "mysys_var->mutex",
- 0);
- pthread_cond_init(&tmp->suspend, NULL);
+ my_thread_init_thr_mutex(tmp);
tmp->stack_ends_here= (char*)&tmp +
STACK_DIRECTION * (long)my_thread_stack_size;
- pthread_mutex_lock(&THR_LOCK_threads);
+ mysql_mutex_lock(&THR_LOCK_threads);
tmp->id= ++thread_id;
++THR_thread_count;
- pthread_mutex_unlock(&THR_LOCK_threads);
+ mysql_mutex_unlock(&THR_LOCK_threads);
tmp->init= 1;
#ifndef DBUG_OFF
/* Generate unique name for thread */
@@ -373,57 +368,50 @@ void my_thread_end(void)
tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
#ifdef EXTRA_DEBUG_THREADS
- fprintf(stderr,"my_thread_end(): tmp: 0x%lx pthread_self: 0x%lx thread_id: %ld\n",
- (long) tmp, (long) pthread_self(), tmp ? (long) tmp->id : 0L);
-#endif
- if (tmp && tmp->init)
- {
+ fprintf(stderr,"my_thread_end(): tmp: %p pthread_self: %p thread_id: %ld\n",
+ tmp, pthread_self(), tmp ? (long) tmp->id : 0L);
+#endif
-#if !defined(__bsdi__) && !defined(__OpenBSD__)
- /* bsdi and openbsd 3.5 dumps core here */
- pthread_cond_destroy(&tmp->suspend);
+#ifdef HAVE_PSI_INTERFACE
+ /*
+ Remove the instrumentation for this thread.
+ This must be done before trashing st_my_thread_var,
+ because the LF_HASH depends on it.
+ */
+ if (PSI_server)
+ PSI_server->delete_current_thread();
#endif
- pthread_mutex_destroy(&tmp->mutex);
+ DBUG_POP();
+
+ pthread_setspecific(THR_KEY_mysys,0);
+
+ if (tmp && tmp->init)
+ {
#if !defined(DBUG_OFF)
/* tmp->dbug is allocated inside DBUG library */
if (tmp->dbug)
{
- DBUG_POP();
free(tmp->dbug);
tmp->dbug=0;
}
#endif
-#if !defined(__WIN__) || defined(USE_TLS)
-#ifndef DBUG_OFF
- /* To find bugs when accessing unallocated data */
- bfill(tmp, sizeof(tmp), 0x8F);
-#endif
- free(tmp);
-#else
- tmp->init= 0;
-#endif
+ my_thread_destory_thr_mutex(tmp);
-#if !defined(__WIN__) || defined(USE_TLS)
- pthread_setspecific(THR_KEY_mysys,0);
-#endif
/*
Decrement counter for number of running threads. We are using this
in my_thread_global_end() to wait until all threads have called
my_thread_end and thus freed all memory they have allocated in
my_thread_init() and DBUG_xxxx
*/
- pthread_mutex_lock(&THR_LOCK_threads);
+ mysql_mutex_lock(&THR_LOCK_threads);
DBUG_ASSERT(THR_thread_count != 0);
if (--THR_thread_count == 0)
- pthread_cond_signal(&THR_COND_threads);
- pthread_mutex_unlock(&THR_LOCK_threads);
- }
- else
- {
-#if !defined(__WIN__) || defined(USE_TLS)
- pthread_setspecific(THR_KEY_mysys,0);
-#endif
+ mysql_cond_signal(&THR_COND_threads);
+ mysql_mutex_unlock(&THR_LOCK_threads);
+
+ TRASH(tmp, sizeof(*tmp));
+ free(tmp);
}
}
@@ -432,25 +420,6 @@ struct st_my_thread_var *_my_thread_var(void)
return my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
}
-#ifndef DBUG_OFF
-/* Return pointer to DBUG for holding current state */
-
-extern void **my_thread_var_dbug()
-{
- struct st_my_thread_var *tmp=
- my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
- return tmp && tmp->init ? &tmp->dbug : 0;
-}
-#endif
-
-/* Return pointer to mutex_in_use */
-
-safe_mutex_t **my_thread_var_mutex_in_use()
-{
- struct st_my_thread_var *tmp=
- my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
- return tmp ? &tmp->mutex_in_use : 0;
-}
/****************************************************************************
Get name of current thread.
@@ -481,8 +450,29 @@ const char *my_thread_name(void)
}
return tmp->name;
}
+
+/* Return pointer to DBUG for holding current state */
+
+extern void **my_thread_var_dbug()
+{
+ struct st_my_thread_var *tmp;
+ if (!my_thread_global_init_done)
+ return NULL;
+ tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
+ return tmp && tmp->init ? &tmp->dbug : 0;
+}
#endif /* DBUG_OFF */
+/* Return pointer to mutex_in_use */
+
+safe_mutex_t **my_thread_var_mutex_in_use()
+{
+ struct st_my_thread_var *tmp;
+ if (!my_thread_global_init_done)
+ return NULL;
+ tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
+ return tmp ? &tmp->mutex_in_use : 0;
+}
static uint get_thread_lib(void)
{
@@ -499,4 +489,29 @@ static uint get_thread_lib(void)
return THD_LIB_OTHER;
}
-#endif /* THREAD */
+#ifdef _WIN32
+/*
+ In Visual Studio 2005 and later, default SIGABRT handler will overwrite
+ any unhandled exception filter set by the application and will try to
+ call JIT debugger. This is not what we want, this we calling __debugbreak
+ to stop in debugger, if process is being debugged or to generate
+ EXCEPTION_BREAKPOINT and then handle_segfault will do its magic.
+*/
+
+#if (_MSC_VER >= 1400)
+static void my_sigabrt_handler(int sig)
+{
+ __debugbreak();
+}
+#endif /*_MSC_VER >=1400 */
+
+static void install_sigabrt_handler(void)
+{
+#if (_MSC_VER >=1400)
+ /*abort() should not override our exception filter*/
+ _set_abort_behavior(0,_CALL_REPORTFAULT);
+ signal(SIGABRT,my_sigabrt_handler);
+#endif /* _MSC_VER >=1400 */
+}
+#endif
+
diff --git a/mysys/my_timer_cycles.il b/mysys/my_timer_cycles.il
new file mode 100644
index 00000000000..e655cad2a2e
--- /dev/null
+++ b/mysys/my_timer_cycles.il
@@ -0,0 +1,39 @@
+/* Copyright (c) 2008 MySQL AB, 2009 Sun Microsystems, Inc.
+ 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 St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+/* Sun Studio SPARC inline templates for cycle timer */
+/* Sun Studio i386 and x86_64 inline templates for cycle timer */
+/* I didn't say ".volatile" or ".nonvolatile". */
+
+.inline my_timer_cycles_il_sparc64,0
+rd %tick,%o0
+.end
+
+.inline my_timer_cycles_il_sparc32,0
+rd %tick,%o2
+srlx %o2,32,%o0
+sra %o2,0,%o1
+.end
+
+.inline my_timer_cycles_il_i386,0
+rdtsc
+.end
+
+.inline my_timer_cycles_il_x86_64,0
+rdtsc
+shlq $32,%rdx
+orq %rdx,%rax
+.end
diff --git a/mysys/my_uuid.c b/mysys/my_uuid.c
index 3df2dda2af5..ab1b259ae0f 100644
--- a/mysys/my_uuid.c
+++ b/mysys/my_uuid.c
@@ -50,9 +50,7 @@ static ulonglong uuid_time= 0;
static longlong interval_timer_offset;
static uchar uuid_suffix[2+6]; /* clock_seq and node */
-#ifdef THREAD
-static pthread_mutex_t LOCK_uuid_generator;
-#endif
+static mysql_mutex_t LOCK_uuid_generator;
/*
Number of 100-nanosecond intervals between
@@ -117,7 +115,7 @@ void my_uuid_init(ulong seed1, ulong seed2)
}
my_rnd_init(&uuid_rand, (ulong) (seed1 + now), (ulong) (now/2+ getpid()));
set_clock_seq();
- pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_LOCK_uuid_generator, &LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
}
@@ -136,7 +134,7 @@ void my_uuid(uchar *to)
DBUG_ASSERT(my_uuid_inited);
- pthread_mutex_lock(&LOCK_uuid_generator);
+ mysql_mutex_lock(&LOCK_uuid_generator);
tv= my_interval_timer()/100 + interval_timer_offset + nanoseq;
if (likely(tv > uuid_time))
@@ -197,7 +195,7 @@ void my_uuid(uchar *to)
}
uuid_time=tv;
- pthread_mutex_unlock(&LOCK_uuid_generator);
+ mysql_mutex_unlock(&LOCK_uuid_generator);
time_low= (uint32) (tv & 0xFFFFFFFF);
time_mid= (uint16) ((tv >> 32) & 0xFFFF);
@@ -242,6 +240,6 @@ void my_uuid_end()
if (my_uuid_inited)
{
my_uuid_inited= 0;
- pthread_mutex_destroy(&LOCK_uuid_generator);
+ mysql_mutex_destroy(&LOCK_uuid_generator);
}
}
diff --git a/mysys/my_vle.c b/mysys/my_vle.c
deleted file mode 100644
index 09f297eb553..00000000000
--- a/mysys/my_vle.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Copyright (C) 2005 MySQL 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*
- Variable length encoding.
-
- A method to store an arbitrary-size non-negative integer. We let the
- most significant bit of the number indicate that the next byte
- should be contatenated to form the real number.
-*/
-
-#include "my_vle.h"
-
-/*
- Function to encode an unsigned long as VLE. The bytes for the VLE
- will be written to the location pointed to by 'out'. The maximum
- number of bytes written will be 'max'.
-
- PARAMETERS
-
- out Pointer to beginning of where to store VLE bytes.
- max Maximum number of bytes to write.
- n Number to encode.
-
- RETURN VALUE
- On success, one past the end of the array containing the VLE
- bytes. On failure, the 'out' pointer is returned.
-*/
-
-uchar*
-my_vle_encode(uchar* out, size_t max, ulong n)
-{
- uchar buf[my_vle_sizeof(n)];
- uchar *ptr= buf;
- size_t len;
-
- do
- {
- *ptr++= (uchar) (n & 0x7F);
- n>>= 7;
- }
- while (n > 0);
-
- len= ptr - buf;
-
- if (len <= max)
- {
- /*
- The bytes are stored in reverse order in 'buf'. Let's write them
- in correct order to the output buffer and set the MSB at the
- same time.
- */
- while (ptr-- > buf)
- {
- uchar v= *ptr;
- if (ptr > buf)
- v|= 0x80;
- *out++= v;
- }
- }
-
- return out;
-}
-
-/*
- Function to decode a VLE representation of an integral value.
-
-
- PARAMETERS
-
- result_ptr Pointer to an unsigned long where the value will be written.
- vle Pointer to the VLE bytes.
-
- RETURN VALUE
-
- One-past the end of the VLE bytes. The routine will never read
- more than sizeof(*result_ptr) + 1 bytes.
-*/
-
-uchar const*
-my_vle_decode(ulong *result_ptr, uchar const *vle)
-{
- ulong result= 0;
- size_t cnt= 1;
-
- do
- {
- result<<= 7;
- result|= (*vle & 0x7F);
- }
- while ((*vle++ & 0x80) && ++cnt <= sizeof(*result_ptr) + 1);
-
- if (cnt <= sizeof(*result_ptr) + 1)
- *result_ptr= result;
-
- return vle;
-}
diff --git a/mysys/my_wincond.c b/mysys/my_wincond.c
index 64cd67bf8d9..f88e33e17f3 100644
--- a/mysys/my_wincond.c
+++ b/mysys/my_wincond.c
@@ -1,6 +1,4 @@
-/*
- Copyright (c) 2000, 2006, 2007 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* Copyright (c) 2000, 2010, 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
@@ -13,19 +11,16 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*****************************************************************************
** The following is a simple implementation of posix conditions
*****************************************************************************/
+#if defined(_WIN32)
-#include <my_global.h>
#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */
#include "mysys_priv.h"
-#if defined(THREAD) && defined(__WIN__)
#include <m_string.h>
-#undef getpid
#include <process.h>
#include <sys/timeb.h>
@@ -160,29 +155,9 @@ static int legacy_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
struct timespec *abstime)
{
int result;
- DWORD timeout;
- long long timeout_us;
- my_hrtime_t now;
- my_hrtime_t then;
- if( abstime != NULL )
- {
- now= my_hrtime();
- then.val= 1000000ULL*abstime->tv_sec + abstime->tv_nsec/1000;
- timeout_us= then.val - now.val;
-
- if (timeout_us < 0)
- timeout= 0;
- else if (timeout_us > 1000ULL*INFINITE)
- timeout= INFINITE;
- else
- timeout= (DWORD)(timeout_us/1000);
- }
- else
- {
- /* No time specified; don't expire */
- timeout= INFINITE;
- }
+ DWORD timeout;
+ timeout= get_milliseconds(abstime);
/*
Block access if previous broadcast hasn't finished.
This is just for safety and should normally not
@@ -338,7 +313,6 @@ int pthread_attr_init(pthread_attr_t *connect_att)
{
connect_att->dwStackSize = 0;
connect_att->dwCreatingFlag = 0;
- connect_att->priority = 0;
return 0;
}
@@ -348,12 +322,6 @@ int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack)
return 0;
}
-int pthread_attr_setprio(pthread_attr_t *connect_att,int priority)
-{
- connect_att->priority=priority;
- return 0;
-}
-
int pthread_attr_destroy(pthread_attr_t *connect_att)
{
bzero((uchar*) connect_att,sizeof(*connect_att));
diff --git a/mysys/my_windac.c b/mysys/my_windac.c
index f846853f7be..51fe22e8f59 100644
--- a/mysys/my_windac.c
+++ b/mysys/my_windac.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2005 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "m_string.h"
@@ -194,8 +194,8 @@ error:
FreeSid(everyone_sid);
if (htoken)
CloseHandle(htoken);
- my_free((uchar*) sa, MYF(MY_ALLOW_ZERO_PTR));
- my_free((uchar*) dacl, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sa);
+ my_free(dacl);
*psa= 0;
return 1;
}
@@ -215,8 +215,8 @@ void my_security_attr_free(SECURITY_ATTRIBUTES *sa)
My_security_attr *attr= (My_security_attr*)
(((char*)sa) + ALIGN_SIZE(sizeof(*sa)));
FreeSid(attr->everyone_sid);
- my_free((uchar*) attr->dacl, MYF(0));
- my_free((uchar*) sa, MYF(0));
+ my_free(attr->dacl);
+ my_free(sa);
}
}
diff --git a/mysys/my_winerr.c b/mysys/my_winerr.c
index 534078b6737..15f52dd7f37 100644
--- a/mysys/my_winerr.c
+++ b/mysys/my_winerr.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2008 MySQL AB
+/* Copyright (c) 2008 MySQL AB, 2009 Sun Microsystems, Inc.
+ 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
@@ -11,7 +12,7 @@ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
Convert Windows API error (GetLastError() to Posix equivalent (errno)
diff --git a/mysys/my_winfile.c b/mysys/my_winfile.c
index f63c35ba47b..ad87bf718d2 100644
--- a/mysys/my_winfile.c
+++ b/mysys/my_winfile.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2008, 2010, 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
@@ -11,7 +11,7 @@ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
The purpose of this file is to provide implementation of file IO routines on
@@ -57,7 +57,7 @@ File my_open_osfhandle(HANDLE handle, int oflag)
uint i;
DBUG_ENTER("my_open_osfhandle");
- pthread_mutex_lock(&THR_LOCK_open);
+ mysql_mutex_lock(&THR_LOCK_open);
for(i= MY_FILE_MIN; i < my_file_limit;i++)
{
if(my_file_info[i].fhandle == 0)
@@ -70,7 +70,7 @@ File my_open_osfhandle(HANDLE handle, int oflag)
break;
}
}
- pthread_mutex_unlock(&THR_LOCK_open);
+ mysql_mutex_unlock(&THR_LOCK_open);
if(offset == -1)
errno= EMFILE; /* to many file handles open */
DBUG_RETURN(offset);
diff --git a/mysys/my_winthread.c b/mysys/my_winthread.c
index 7a22027d6a5..b77581fae78 100644
--- a/mysys/my_winthread.c
+++ b/mysys/my_winthread.c
@@ -1,6 +1,4 @@
-/*
- Copyright (c) 2000, 2001, 2005-2007 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* Copyright (c) 2000, 2010, 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
@@ -13,38 +11,25 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*****************************************************************************
-** Simulation of posix threads calls for WIN95 and NT
+** Simulation of posix threads calls for Windows
*****************************************************************************/
-
+#if defined (_WIN32)
/* SAFE_MUTEX will not work until the thread structure is up to date */
-#include <my_global.h>
-#undef SAFE_MUTEX
+#undef SAFE_MUTEX
#include "mysys_priv.h"
-#if defined(THREAD) && defined(__WIN__)
-#include <m_string.h>
-#undef getpid
#include <process.h>
+#include <signal.h>
-static pthread_mutex_t THR_LOCK_thread;
-
-struct pthread_map
+struct thread_start_parameter
{
- HANDLE pthreadself;
pthread_handler func;
- void *param;
+ void *arg;
};
-void win_pthread_init(void)
-{
- pthread_mutex_init(&THR_LOCK_thread,MY_MUTEX_INIT_FAST);
-}
-
-
/**
Adapter to @c pthread_mutex_trylock()
@@ -66,91 +51,101 @@ win_pthread_mutex_trylock(pthread_mutex_t *mutex)
return EBUSY;
}
-
-/*
-** We have tried to use '_beginthreadex' instead of '_beginthread' here
-** but in this case the program leaks about 512 characters for each
-** created thread !
-** As we want to save the created thread handler for other threads to
-** use and to be returned by pthread_self() (instead of the Win32 pseudo
-** handler), we have to go trough pthread_start() to catch the returned handler
-** in the new thread.
-*/
-
-pthread_handler_t pthread_start(void *param)
+static unsigned int __stdcall pthread_start(void *p)
{
- pthread_handler func=((struct pthread_map *) param)->func;
- void *func_param=((struct pthread_map *) param)->param;
- void *result;
- my_thread_init(); /* Will always succeed in windows */
- pthread_mutex_lock(&THR_LOCK_thread); /* Wait for beginthread to return */
- win_pthread_self=((struct pthread_map *) param)->pthreadself;
- pthread_mutex_unlock(&THR_LOCK_thread);
- free((char*) param); /* Free param from create */
- result= (void*) (*func)(func_param);
- my_thread_end();
- pthread_exit(result);
- return 0; /* Safety */
+ struct thread_start_parameter *par= (struct thread_start_parameter *)p;
+ pthread_handler func= par->func;
+ void *arg= par->arg;
+ free(p);
+ (*func)(arg);
+ return 0;
}
-int pthread_create(pthread_t *thread_id, pthread_attr_t *attr,
- pthread_handler func, void *param)
+int pthread_create(pthread_t *thread_id, const pthread_attr_t *attr,
+ pthread_handler func, void *param)
{
- HANDLE hThread;
- struct pthread_map *map;
- DWORD StackSize= 0;
- int priority= 0;
+ uintptr_t handle;
+ struct thread_start_parameter *par;
+ unsigned int stack_size;
DBUG_ENTER("pthread_create");
- if (!(map=malloc(sizeof(*map))))
- DBUG_RETURN(-1);
- map->func=func;
- map->param=param;
- if (attr != NULL)
- {
- StackSize= attr->dwStackSize;
- priority= attr->priority;
- }
- if (StackSize == 0)
- StackSize= PTHREAD_STACK_MIN;
- pthread_mutex_lock(&THR_LOCK_thread);
-#ifdef __BORLANDC__
- hThread=(HANDLE)_beginthread((void(_USERENTRY *)(void *)) pthread_start,
- StackSize, (void*) map);
-#else
- hThread=(HANDLE)_beginthread((void( __cdecl *)(void *)) pthread_start,
- StackSize, (void*) map);
-#endif
- DBUG_PRINT("info", ("hThread=%lu",(long) hThread));
- *thread_id=map->pthreadself=hThread;
- pthread_mutex_unlock(&THR_LOCK_thread);
+ par= (struct thread_start_parameter *)malloc(sizeof(*par));
+ if (!par)
+ goto error_return;
- if (hThread == (HANDLE) -1)
- {
- int error=errno;
- DBUG_PRINT("error",
- ("Can't create thread to handle request (error %d)",error));
- DBUG_RETURN(error ? error : -1);
- }
- VOID(SetThreadPriority(hThread, priority)) ;
+ par->func= func;
+ par->arg= param;
+ stack_size= attr?attr->dwStackSize:0;
+
+ handle= _beginthreadex(NULL, stack_size , pthread_start, par, 0, thread_id);
+ if (!handle)
+ goto error_return;
+ DBUG_PRINT("info", ("thread id=%u",*thread_id));
+
+ /* Do not need thread handle, close it */
+ CloseHandle((HANDLE)handle);
DBUG_RETURN(0);
+
+error_return:
+ DBUG_PRINT("error",
+ ("Can't create thread to handle request (error %d)",errno));
+ DBUG_RETURN(-1);
}
void pthread_exit(void *a)
{
- _endthread();
+ _endthreadex(0);
}
-/* This is neaded to get the macro pthread_setspecific to work */
-
-int win_pthread_setspecific(void *a,void *b,uint length)
+int pthread_join(pthread_t thread, void **value_ptr)
{
- memcpy(a,b,length);
+ DWORD ret;
+ HANDLE handle;
+
+ handle= OpenThread(SYNCHRONIZE, FALSE, thread);
+ if (!handle)
+ {
+ errno= EINVAL;
+ goto error_return;
+ }
+
+ ret= WaitForSingleObject(handle, INFINITE);
+
+ if(ret != WAIT_OBJECT_0)
+ {
+ errno= EINVAL;
+ goto error_return;
+ }
+
+ CloseHandle(handle);
return 0;
+
+error_return:
+ if(handle)
+ CloseHandle(handle);
+ return -1;
}
+int pthread_cancel(pthread_t thread)
+{
+
+ HANDLE handle= 0;
+ BOOL ok= FALSE;
+
+ handle= OpenThread(THREAD_TERMINATE, FALSE, thread);
+ if (handle)
+ {
+ ok= TerminateThread(handle,0);
+ CloseHandle(handle);
+ }
+ if (ok)
+ return 0;
+
+ errno= EINVAL;
+ return -1;
+}
/*
One time initialization. For simplicity, we assume initializer thread
@@ -193,5 +188,4 @@ int my_pthread_once(my_pthread_once_t *once_control,
}
return 0;
}
-
#endif
diff --git a/mysys/my_write.c b/mysys/my_write.c
index 67fe04a69d7..4997a4a804a 100644
--- a/mysys/my_write.c
+++ b/mysys/my_write.c
@@ -1,6 +1,4 @@
-/*
- Copyright (c) 2000, 2001, 2004-2007 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* 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
@@ -13,8 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -23,14 +20,14 @@
/* Write a chunk of bytes to a file */
-size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
+size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
{
size_t writtenbytes, written;
uint errors;
DBUG_ENTER("my_write");
- DBUG_PRINT("my",("fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d",
- Filedes, (long) Buffer, (ulong) Count, MyFlags));
- errors=0; written=0;
+ DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d",
+ Filedes, Buffer, (ulong) Count, MyFlags));
+ errors= 0; written= 0;
if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP)))
MyFlags|= my_global_flags;
@@ -73,10 +70,9 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
DBUG_PRINT("error",("Write only %ld bytes, error: %d",
(long) writtenbytes, my_errno));
#ifndef NO_BACKGROUND
-#ifdef THREAD
if (my_thread_var->abort)
MyFlags&= ~ MY_WAIT_IF_FULL; /* End if aborted by user */
-#endif
+
if ((my_errno == ENOSPC || my_errno == EDQUOT) &&
(MyFlags & MY_WAIT_IF_FULL))
{
diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h
index 6d39999aa86..f5d2f301837 100644
--- a/mysys/mysys_priv.h
+++ b/mysys/mysys_priv.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <my_global.h>
#include <my_sys.h>
@@ -24,16 +24,61 @@
#include <sys/resource.h>
#endif
-#ifdef THREAD
#include <my_pthread.h>
-extern pthread_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache;
-extern pthread_mutex_t THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_net;
-extern pthread_mutex_t THR_LOCK_charset, THR_LOCK_time;
+
+#ifdef HAVE_PSI_INTERFACE
+
+#if !defined(HAVE_PREAD) && !defined(_WIN32)
+extern PSI_mutex_key key_my_file_info_mutex;
+#endif /* !defined(HAVE_PREAD) && !defined(_WIN32) */
+
+#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
+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_my_thread_var_mutex, key_THR_LOCK_charset, key_THR_LOCK_heap,
+ key_THR_LOCK_isam, 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;
+
+extern PSI_cond_key key_COND_alarm, 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_rwlock_key key_SAFEHASH_mutex;
+
+#endif /* HAVE_PSI_INTERFACE */
+
+extern mysql_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache;
+extern mysql_mutex_t THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_net;
+extern mysql_mutex_t THR_LOCK_charset;
+
+#include <mysql/psi/mysql_file.h>
+
+#ifdef HAVE_PSI_INTERFACE
+#ifdef HUGETLB_USE_PROC_MEMINFO
+extern PSI_file_key key_file_proc_meminfo;
+#endif /* HUGETLB_USE_PROC_MEMINFO */
+extern PSI_file_key key_file_charset, key_file_cnf;
+#endif /* HAVE_PSI_INTERFACE */
+
+#ifdef SAFEMALLOC
+void *sf_malloc(size_t size);
+void *sf_realloc(void *ptr, size_t size);
+void sf_free(void *ptr);
#else
-#include <my_no_pthread.h>
+#define sf_malloc(X) malloc(X)
+#define sf_realloc(X,Y) realloc(X,Y)
+#define sf_free(X) free(X)
#endif
-
/*
EDQUOT is used only in 3 C files only in mysys/. If it does not exist on
system, we set it to some value which can never happen.
@@ -43,29 +88,28 @@ extern pthread_mutex_t THR_LOCK_charset, THR_LOCK_time;
#endif
void my_error_unregister_all(void);
-void my_thread_destroy_mutex(void);
-my_bool my_wait_for_other_threads_to_die(uint number_of_threads);
-
-#ifdef _WIN32
-/* my_winfile.c exports, should not be used outside mysys */
-extern File my_win_open(const char *path, int oflag);
-extern int my_win_close(File fd);
-extern size_t my_win_read(File fd, uchar *buffer, size_t count);
-extern size_t my_win_write(File fd, const uchar *buffer, size_t count);
-extern size_t my_win_pread(File fd, uchar *buffer, size_t count,
- my_off_t offset);
-extern size_t my_win_pwrite(File fd, const uchar *buffer, size_t count,
- my_off_t offset);
-extern my_off_t my_win_lseek(File fd, my_off_t pos, int whence);
-extern int my_win_chsize(File fd, my_off_t newlength);
-extern FILE* my_win_fopen(const char *filename, const char *type);
-extern File my_win_fclose(FILE *file);
-extern File my_win_fileno(FILE *file);
-extern FILE* my_win_fdopen(File Filedes, const char *type);
-extern int my_win_stat(const char *path, struct _stat64 *buf);
-extern int my_win_fstat(File fd, struct _stat64 *buf);
-extern int my_win_fsync(File fd);
-extern File my_win_dup(File fd);
-extern File my_win_sopen(const char *path, int oflag, int shflag, int perm);
-extern File my_open_osfhandle(HANDLE handle, int oflag);
+
+#ifdef _WIN32
+#include <sys/stat.h>
+/* my_winfile.c exports, should not be used outside mysys */
+extern File my_win_open(const char *path, int oflag);
+extern int my_win_close(File fd);
+extern size_t my_win_read(File fd, uchar *buffer, size_t count);
+extern size_t my_win_write(File fd, const uchar *buffer, size_t count);
+extern size_t my_win_pread(File fd, uchar *buffer, size_t count,
+ my_off_t offset);
+extern size_t my_win_pwrite(File fd, const uchar *buffer, size_t count,
+ my_off_t offset);
+extern my_off_t my_win_lseek(File fd, my_off_t pos, int whence);
+extern int my_win_chsize(File fd, my_off_t newlength);
+extern FILE* my_win_fopen(const char *filename, const char *type);
+extern File my_win_fclose(FILE *file);
+extern File my_win_fileno(FILE *file);
+extern FILE* my_win_fdopen(File Filedes, const char *type);
+extern int my_win_stat(const char *path, struct _stati64 *buf);
+extern int my_win_fstat(File fd, struct _stati64 *buf);
+extern int my_win_fsync(File fd);
+extern File my_win_dup(File fd);
+extern File my_win_sopen(const char *path, int oflag, int shflag, int perm);
+extern File my_open_osfhandle(HANDLE handle, int oflag);
#endif
diff --git a/mysys/ptr_cmp.c b/mysys/ptr_cmp.c
index 24ab6a1ea9c..a481b4d961c 100644
--- a/mysys/ptr_cmp.c
+++ b/mysys/ptr_cmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
get_ptr_compare(len) returns a pointer to a optimal byte-compare function
@@ -21,15 +21,47 @@
#include "mysys_priv.h"
#include <myisampack.h>
+/*
+ * On some platforms, memcmp() is faster than the unrolled ptr_compare_N
+ * functions, as memcmp() is usually a platform-specific implementation
+ * written in assembler. for example one in /usr/lib/libc/libc_hwcap*.so.1.
+ * on Solaris, or on Windows inside C runtime linrary.
+ *
+ * On Solaris, native implementation is also usually faster than the
+ * built-in memcmp supplied by GCC, so it is recommended to build
+ * with "-fno-builtin-memcmp"in CFLAGS if building with GCC on Solaris.
+ */
+
+#if defined (__sun) || defined (_WIN32)
+#define USE_NATIVE_MEMCMP 1
+#endif
+
+#ifdef USE_NATIVE_MEMCMP
+
+#include <string.h>
+
+static int native_compare(size_t *length, unsigned char **a, unsigned char **b)
+{
+ return memcmp(*a, *b, *length);
+}
+
+#else /* USE_NATIVE_MEMCMP */
static int ptr_compare(size_t *compare_length, uchar **a, uchar **b);
static int ptr_compare_0(size_t *compare_length, uchar **a, uchar **b);
static int ptr_compare_1(size_t *compare_length, uchar **a, uchar **b);
static int ptr_compare_2(size_t *compare_length, uchar **a, uchar **b);
static int ptr_compare_3(size_t *compare_length, uchar **a, uchar **b);
+#endif /* __sun */
/* Get a pointer to a optimal byte-compare function for a given size */
+#ifdef USE_NATIVE_MEMCMP
+qsort2_cmp get_ptr_compare (size_t size __attribute__((unused)))
+{
+ return (qsort2_cmp) native_compare;
+}
+#else
qsort2_cmp get_ptr_compare (size_t size)
{
if (size < 4)
@@ -42,6 +74,7 @@ qsort2_cmp get_ptr_compare (size_t size)
}
return 0; /* Impossible */
}
+#endif /* USE_NATIVE_MEMCMP */
/*
@@ -51,6 +84,8 @@ qsort2_cmp get_ptr_compare (size_t size)
#define cmp(N) if (first[N] != last[N]) return (int) first[N] - (int) last[N]
+#ifndef USE_NATIVE_MEMCMP
+
static int ptr_compare(size_t *compare_length, uchar **a, uchar **b)
{
reg3 int length= *compare_length;
@@ -153,6 +188,8 @@ static int ptr_compare_3(size_t *compare_length,uchar **a, uchar **b)
return (0);
}
+#endif /* !__sun */
+
void my_store_ptr(uchar *buff, size_t pack_length, my_off_t pos)
{
switch (pack_length) {
diff --git a/mysys/queues.c b/mysys/queues.c
index d1f2dab18bc..418163d7c58 100644
--- a/mysys/queues.c
+++ b/mysys/queues.c
@@ -176,11 +176,8 @@ int resize_queue(QUEUE *queue, uint max_elements)
void delete_queue(QUEUE *queue)
{
DBUG_ENTER("delete_queue");
- if (queue->root)
- {
- my_free((uchar*) queue->root,MYF(0));
- queue->root=0; /* Allow multiple calls */
- }
+ my_free(queue->root);
+ queue->root=0; /* Allow multiple calls */
DBUG_VOID_RETURN;
}
diff --git a/mysys/rijndael.c b/mysys/rijndael.c
index 2b12753c4e5..e893a886726 100644
--- a/mysys/rijndael.c
+++ b/mysys/rijndael.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2004 MySQL AB
+/* Copyright (c) 2002, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
@@ -32,22 +32,6 @@
#define FULL_UNROLL
*/
-
-#ifdef NOT_USED
-Te0[x] = S [x].[02, 01, 01, 03];
-Te1[x] = S [x].[03, 02, 01, 01];
-Te2[x] = S [x].[01, 03, 02, 01];
-Te3[x] = S [x].[01, 01, 03, 02];
-Te4[x] = S [x].[01, 01, 01, 01];
-
-Td0[x] = Si[x].[0e, 09, 0d, 0b];
-Td1[x] = Si[x].[0b, 0e, 09, 0d];
-Td2[x] = Si[x].[0d, 0b, 0e, 09];
-Td3[x] = Si[x].[09, 0d, 0b, 0e];
-Td4[x] = Si[x].[01, 01, 01, 01];
-#endif
-
-
static const uint32 Te0[256]=
{
0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c
index 89cf0093969..31f0333725f 100644
--- a/mysys/safemalloc.c
+++ b/mysys/safemalloc.c
@@ -1,5 +1,4 @@
-/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates
+/* Copyright (C) 2000 MySQL AB, 2011 Monty Program 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
@@ -12,306 +11,183 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-/*
- * Memory sub-system, written by Bjorn Benson
- Fixed to use my_sys scheme by Michael Widenius
-
- [This posting refers to an article entitled "oops, corrupted memory
- again!" in net.lang.c. I am posting it here because it is source.]
-
- My tool for approaching this problem is to build another level of data
- abstraction on top of malloc() and free() that implements some checking.
- This does a number of things for you:
- - Checks for overruns and underruns on allocated data
- - Keeps track of where in the program the memory was malloc'ed
- - Reports on pieces of memory that were not free'ed
- - Records some statistics such as maximum memory used
- - Marks newly malloc'ed and newly free'ed memory with special values
- You can use this scheme to:
- - Find bugs such as overrun, underrun, etc because you know where
- a piece of data was malloc'ed and where it was free'ed
- - Find bugs where memory was not free'ed
- - Find bugs where newly malloc'ed memory is used without initializing
- - Find bugs where newly free'ed memory is still used
- - Determine how much memory your program really uses
- - and other things
-
- To implement my scheme you must have a C compiler that has __LINE__ and
- __FILE__ macros. If your compiler doesn't have these then (a) buy another:
- compilers that do are available on UNIX 4.2bsd based systems and the PC,
- and probably on other machines; or (b) change my scheme somehow. I have
- recomendations on both these points if you would like them (e-mail please).
-
- There are 4 functions in my package:
- char *NEW( uSize ) Allocate memory of uSize bytes
- (equivalent to malloc())
- char *REA( pPtr, uSize) Allocate memory of uSize bytes, move data and
- free pPtr.
- (equivalent to realloc())
- FREE( pPtr ) Free memory allocated by NEW
- (equivalent to free())
- TERMINATE(file,flag) End system, report errors and stats on file
- I personally use two more functions, but have not included them here:
- char *STRSAVE( sPtr ) Save a copy of the string in dynamic memory
- char *RENEW( pPtr, uSize )
- (equivalent to realloc())
+/********************************************************************
+ memory debugger
+ based on safemalloc, memory sub-system, written by Bjorn Benson
+********************************************************************/
-*/
-
-#ifndef SAFEMALLOC
-#define SAFEMALLOC 1 /* Get protos from my_sys */
-#endif
#include "mysys_priv.h"
-#include <m_string.h>
-#include "my_static.h"
-#include "mysys_err.h"
+#include <my_stacktrace.h> /* my_addr_resolve */
-ulonglong sf_malloc_mem_limit= ~(ulonglong)0;
+#if HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
-#ifndef PEDANTIC_SAFEMALLOC
/*
- Set to 1 after TERMINATE() if we had to fiddle with sf_malloc_count and
- the linked list of blocks so that _sanity() will not fuss when it
- is not supposed to
+ this can be set to 1 if we leak memory and know it
+ (to disable memory leak tests on exit)
*/
-static int sf_malloc_tampered= 0;
-#endif
-
+int sf_leaking_memory= 0;
- /* Static functions prototypes */
+#ifdef SAFEMALLOC
-static int check_ptr(const char *where, uchar *ptr, const char *sFile,
- uint uLine);
-static int _checkchunk(struct st_irem *pRec, const char *sFile, uint uLine);
+/* this mutex protects all sf_* variables, and nothing else*/
+static pthread_mutex_t sf_mutex;
+static int init_done= 0;
-/*
- Note: We only fill up the allocated block. This do not include
- malloc() roundoff or the extra space required by the irem
- structures.
-*/
+#ifndef SF_REMEMBER_FRAMES
+#define SF_REMEMBER_FRAMES 8
+#endif
-/*
- NEW'ed memory is filled with this value so that references to it will
- end up being very strange.
-*/
-#define ALLOC_VAL (uchar) 0xA5
-/*
- FEEE'ed memory is filled with this value so that references to it will
- end up being very strange.
-*/
-#define FREE_VAL (uchar) 0x8F
-#define MAGICKEY 0x14235296 /* A magic value for underrun key */
+/* ignore the first two frames (sf_malloc itself, and my_malloc) */
+#define SF_FRAMES_SKIP 2
/*
- Warning: do not change the MAGICEND? values to something with the
- high bit set. Various C compilers (like the 4.2bsd one) do not do
- the sign extension right later on in this code and you will get
- erroneous errors.
+ Structure that stores information of an allocated memory block
+ The data is at &struct_adr+sizeof(struct irem)
+ Note that sizeof(struct st_irem) % sizeof(double) == 0
*/
+struct st_irem
+{
+ struct st_irem *next; /* Linked list of structures */
+ struct st_irem *prev; /* Other link */
+ size_t datasize; /* Size requested */
+#ifdef HAVE_BACKTRACE
+ void *frame[SF_REMEMBER_FRAMES]; /* call stack */
+#endif
+ uint32 marker; /* Underrun marker value */
+};
+
+static int sf_malloc_count= 0; /* Number of allocated chunks */
-#define MAGICEND0 0x68 /* Magic values for overrun keys */
-#define MAGICEND1 0x34 /* " */
-#define MAGICEND2 0x7A /* " */
-#define MAGICEND3 0x15 /* " */
+static void *sf_min_adress= (void*) (intptr)~0ULL,
+ *sf_max_adress= 0;
+static struct st_irem *sf_malloc_root = 0;
-/* Allocate some memory. */
+#define MAGICSTART 0x14235296 /* A magic value for underrun key */
-void *_mymalloc(size_t size, const char *filename, uint lineno, myf MyFlags)
+#define MAGICEND0 0x68 /* Magic values for overrun keys */
+#define MAGICEND1 0x34 /* " */
+#define MAGICEND2 0x7A /* " */
+#define MAGICEND3 0x15 /* " */
+
+static int bad_ptr(const char *where, void *ptr);
+static void free_memory(void *ptr);
+static void sf_terminate();
+
+/**
+ allocates memory
+*/
+
+void *sf_malloc(size_t size)
{
struct st_irem *irem;
uchar *data;
- DBUG_ENTER("_mymalloc");
- DBUG_PRINT("enter",("Size: %lu Total alloc: %lu", (ulong) size,
- (ulong) sf_malloc_cur_memory));
-
- if (!sf_malloc_quick)
- (void) _sanity (filename, lineno);
- if (size + sf_malloc_cur_memory > sf_malloc_mem_limit)
- irem= 0;
- else
+ /*
+ this style of initialization looks like race conditon prone,
+ but it is safe under the assumption that a program does
+ at least one malloc() while still being single threaded.
+ */
+ if (!init_done)
{
- /* Allocate the physical memory */
- irem= (struct st_irem *) malloc (ALIGN_SIZE(sizeof(struct st_irem)) +
- sf_malloc_prehunc +
- size + /* size requested */
- 4 + /* overrun mark */
- sf_malloc_endhunc);
- DBUG_EXECUTE_IF("simulate_out_of_memory",
- {
- free(irem);
- irem= NULL;
- });
+ pthread_mutex_init(&sf_mutex, NULL);
+ /* disable deadlock detector, because it calls my_malloc() */
+ safe_mutex_setflags(&sf_mutex, MYF_NO_DEADLOCK_DETECTION);
+ atexit(sf_terminate);
+ init_done= 1;
}
- /* Check if there isn't anymore memory avaiable */
+
+ irem= (struct st_irem *) malloc (sizeof(struct st_irem) + size + 4);
+
if (!irem)
- {
- if (MyFlags & MY_FAE)
- error_handler_hook=fatal_error_handler_hook;
- if (MyFlags & (MY_FAE+MY_WME))
- {
- char buff[256];
- my_errno=errno;
- sprintf(buff,"Out of memory at line %d, '%s'", lineno, filename);
- my_message(EE_OUTOFMEMORY, buff, MYF(ME_BELL+ME_WAITTANG+ME_NOREFRESH));
- sprintf(buff,"needed %lu byte (%luk), memory in use: %lu bytes (%luk)",
- (ulong) size, (ulong) (size + 1023L) / 1024L,
- (ulong) sf_malloc_max_memory,
- (ulong) (sf_malloc_max_memory + 1023L) / 1024L);
- my_message(EE_OUTOFMEMORY, buff, MYF(ME_BELL+ME_WAITTANG+ME_NOREFRESH));
- }
- DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'",
- (ulong) sf_malloc_max_memory,lineno, filename));
- DBUG_EXECUTE_IF("simulate_out_of_memory",
- DBUG_SET("-d,simulate_out_of_memory"););
- if (MyFlags & MY_FAE)
- exit(1);
- DBUG_RETURN ((void*) 0);
- }
+ return 0;
+
+ /* we guarantee the alignment */
+ compile_time_assert(sizeof(struct st_irem) % sizeof(double) == 0);
/* Fill up the structure */
- data= (((uchar*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) +
- sf_malloc_prehunc);
- *((uint32*) (data-sizeof(uint32)))= MAGICKEY;
+ data= (uchar*) (irem + 1);
+ irem->datasize= size;
+ irem->prev= 0;
+ irem->marker= MAGICSTART;
data[size + 0]= MAGICEND0;
data[size + 1]= MAGICEND1;
data[size + 2]= MAGICEND2;
data[size + 3]= MAGICEND3;
- irem->filename= (char *) filename;
- irem->linenum= lineno;
- irem->datasize= size;
- irem->prev= NULL;
- /* Add this remember structure to the linked list */
- pthread_mutex_lock(&THR_LOCK_malloc);
+#ifdef HAVE_BACKTRACE
+ {
+ void *frame[SF_REMEMBER_FRAMES + SF_FRAMES_SKIP];
+ int frames= backtrace(frame, array_elements(frame));
+ if (frames < SF_FRAMES_SKIP)
+ frames= 0;
+ else
+ {
+ frames-= SF_FRAMES_SKIP;
+ memcpy(irem->frame, frame + SF_FRAMES_SKIP, sizeof(void*)*frames);
+ }
+ if (frames < SF_REMEMBER_FRAMES)
+ irem->frame[frames]= 0;
+ }
+#endif
+
+ pthread_mutex_lock(&sf_mutex);
+
+ /* Add this structure to the linked list */
if ((irem->next= sf_malloc_root))
sf_malloc_root->prev= irem;
sf_malloc_root= irem;
/* Keep the statistics */
- sf_malloc_cur_memory+= size;
- if (sf_malloc_cur_memory > sf_malloc_max_memory)
- sf_malloc_max_memory= sf_malloc_cur_memory;
sf_malloc_count++;
- pthread_mutex_unlock(&THR_LOCK_malloc);
-
- MEM_CHECK_ADDRESSABLE(data, size);
- /* Set the memory to the aribtrary wierd value */
- if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick)
- bfill(data, size, (char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL));
- if (!(MyFlags & MY_ZEROFILL))
- MEM_UNDEFINED(data, size);
- /* Return a pointer to the real data */
- DBUG_PRINT("exit",("ptr: %p", data));
- if (sf_min_adress > data)
- sf_min_adress= data;
- if (sf_max_adress < data)
- sf_max_adress= data;
- DBUG_RETURN((void*) data);
-}
+ set_if_smaller(sf_min_adress, (void*)data);
+ set_if_bigger(sf_max_adress, (void*)data);
+ pthread_mutex_unlock(&sf_mutex);
-/*
- Allocate some new memory and move old memoryblock there.
- Free then old memoryblock
-*/
+ TRASH_ALLOC(data, size);
+ return data;
+}
-void *_myrealloc(register void *ptr, register size_t size,
- const char *filename, uint lineno, myf MyFlags)
+void *sf_realloc(void *ptr, size_t size)
{
- struct st_irem *irem;
char *data;
- DBUG_ENTER("_myrealloc");
- DBUG_PRINT("my",("ptr: 0x%lx size: %lu my_flags: %d", (long) ptr,
- (ulong) size, MyFlags));
-
- if (!ptr && (MyFlags & MY_ALLOW_ZERO_PTR))
- DBUG_RETURN(_mymalloc(size, filename, lineno, MyFlags));
- if (!sf_malloc_quick)
- (void) _sanity (filename, lineno);
+ if (!ptr)
+ return sf_malloc(size);
- if (check_ptr("Reallocating", (uchar*) ptr, filename, lineno))
- DBUG_RETURN((uchar*) NULL);
+ if (bad_ptr("Reallocating", ptr))
+ return 0;
- irem= (struct st_irem *) (((char*) ptr) - ALIGN_SIZE(sizeof(struct st_irem))-
- sf_malloc_prehunc);
- if (*((uint32*) (((char*) ptr)- sizeof(uint32))) != MAGICKEY)
+ if ((data= sf_malloc(size)))
{
- fprintf(stderr, "Error: Reallocating unallocated data at line %d, '%s'\n",
- lineno, filename);
- DBUG_PRINT("safe",("Reallocating unallocated data at line %d, '%s'",
- lineno, filename));
- (void) fflush(stderr);
- DBUG_RETURN((uchar*) NULL);
+ struct st_irem *irem= (struct st_irem *)ptr - 1;
+ set_if_smaller(size, irem->datasize);
+ memcpy(data, ptr, size);
+ free_memory(ptr);
}
- DBUG_PRINT("my", ("old_size: %lu -> new_size: %lu",
- (ulong) irem->datasize, (ulong) size));
-
- if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */
- {
- size=min(size, irem->datasize); /* Move as much as possibly */
- memcpy((uchar*) data, ptr, (size_t) size); /* Copy old data */
- _myfree(ptr, filename, lineno, 0); /* Free not needed area */
- }
- else
- {
- if (MyFlags & MY_HOLD_ON_ERROR)
- DBUG_RETURN(ptr);
- if (MyFlags & MY_FREE_ON_ERROR)
- _myfree(ptr, filename, lineno, 0);
- }
- DBUG_RETURN(data);
-} /* _myrealloc */
-
-
-/* Deallocate some memory. */
+ return data;
+}
-void _myfree(void *ptr, const char *filename, uint lineno, myf myflags)
+void sf_free(void *ptr)
{
- struct st_irem *irem;
- DBUG_ENTER("_myfree");
- DBUG_PRINT("enter",("ptr: %p", ptr));
-
- if (!sf_malloc_quick)
- (void) _sanity (filename, lineno);
-
- if ((!ptr && (myflags & MY_ALLOW_ZERO_PTR)) ||
- check_ptr("Freeing",(uchar*) ptr,filename,lineno))
- DBUG_VOID_RETURN;
+ if (!ptr || bad_ptr("Freeing", ptr))
+ return;
- /* Calculate the address of the remember structure */
- irem= (struct st_irem *) ((char*) ptr- ALIGN_SIZE(sizeof(struct st_irem))-
- sf_malloc_prehunc);
-
- if (sf_malloc_quick)
- (void) _checkchunk(irem, filename, lineno);
-
- /*
- Check to make sure that we have a real remember structure.
- Note: this test could fail for four reasons:
- (1) The memory was already free'ed
- (2) The memory was never new'ed
- (3) There was an underrun
- (4) A stray pointer hit this location
- */
+ free_memory(ptr);
+}
- if (*((uint32*) ((char*) ptr- sizeof(uint32))) != MAGICKEY)
- {
- fprintf(stderr, "Error: Freeing unallocated data at line %d, '%s'\n",
- lineno, filename);
- DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",lineno,filename));
- (void) fflush(stderr);
- DBUG_VOID_RETURN;
- }
+static void free_memory(void *ptr)
+{
+ struct st_irem *irem= (struct st_irem *)ptr - 1;
+ pthread_mutex_lock(&sf_mutex);
/* Remove this structure from the linked list */
- pthread_mutex_lock(&THR_LOCK_malloc);
if (irem->prev)
irem->prev->next= irem->next;
else
@@ -319,268 +195,148 @@ void _myfree(void *ptr, const char *filename, uint lineno, myf myflags)
if (irem->next)
irem->next->prev= irem->prev;
+
/* Handle the statistics */
- sf_malloc_cur_memory-= irem->datasize;
sf_malloc_count--;
- pthread_mutex_unlock(&THR_LOCK_malloc);
- DBUG_PRINT("info", ("bytes freed: %ld", (ulong) irem->datasize));
+ pthread_mutex_unlock(&sf_mutex);
-#ifndef HAVE_valgrind
- /* Mark this data as free'ed */
- if (!sf_malloc_quick)
- bfill(ptr, irem->datasize, (pchar) FREE_VAL);
-#endif
- MEM_NOACCESS(ptr, irem->datasize);
- *((uint32*) ((char*) ptr- sizeof(uint32)))= ~MAGICKEY;
- MEM_NOACCESS((char*) ptr - sizeof(uint32), sizeof(uint32));
- /* Actually free the memory */
- free((char*) irem);
- DBUG_VOID_RETURN;
+ /* only trash the data and magic values, but keep the stack trace */
+ TRASH_FREE((uchar*)(irem + 1) - 4, irem->datasize + 8);
+ free(irem);
+ return;
}
- /* Check if we have a wrong pointer */
-
-static int check_ptr(const char *where, uchar *ptr, const char *filename,
- uint lineno)
+#ifdef HAVE_BACKTRACE
+static void print_stack(void **frame)
{
- if (!ptr)
- {
- fprintf(stderr, "Error: %s NULL pointer at line %d, '%s'\n",
- where,lineno, filename);
- DBUG_PRINT("safe",("Null pointer at line %d '%s'", lineno, filename));
- (void) fflush(stderr);
- return 1;
- }
-#ifndef _MSC_VER
- if ((long) ptr & (ALIGN_SIZE(1)-1))
+ const char *err;
+ int i;
+
+ if ((err= my_addr_resolve_init()))
{
- fprintf(stderr, "Error: %s wrong aligned pointer at line %d, '%s'\n",
- where,lineno, filename);
- DBUG_PRINT("safe",("Wrong aligned pointer at line %d, '%s'",
- lineno,filename));
- (void) fflush(stderr);
- return 1;
+ fprintf(stderr, "(my_addr_resolve failure: %s)\n", err);
+ return;
}
-#endif
- if (ptr < sf_min_adress || ptr > sf_max_adress)
+
+ for (i=0; i < SF_REMEMBER_FRAMES && frame[i]; i++)
{
- fprintf(stderr, "Error: %s pointer out of range at line %d, '%s'\n",
- where,lineno, filename);
- DBUG_PRINT("safe",("Pointer out of range at line %d '%s'",
- lineno,filename));
- (void) fflush(stderr);
- return 1;
+ my_addr_loc loc;
+ if (i)
+ fprintf(stderr, ", ");
+
+ if (my_addr_resolve(frame[i], &loc))
+ fprintf(stderr, "%p", frame[i]);
+ else
+ fprintf(stderr, "%s:%u", loc.file, loc.line);
}
- return 0;
+ fprintf(stderr, "\n");
}
+#else
+#define print_stack(X) fprintf(stderr, "???\n")
+#endif
-
-/*
- Report on all the memory pieces that have not been free'ed
-
- SYNOPSIS
- TERMINATE()
- file Write output to this file
- flag If <> 0, also write statistics
- */
-
-void TERMINATE(FILE *file, uint flag)
+static void warn(const char *format,...)
{
- struct st_irem *irem;
- DBUG_ENTER("TERMINATE");
- pthread_mutex_lock(&THR_LOCK_malloc);
+ va_list args;
+ va_start(args,format);
+ vfprintf(stderr, format, args);
+ va_end(args);
- /*
- Report the difference between number of calls to
- NEW and the number of calls to FREE. >0 means more
- NEWs than FREEs. <0, etc.
- */
-
- if (sf_malloc_count)
+#ifdef HAVE_BACKTRACE
{
- if (file)
- {
- fprintf(file, "Warning: Not freed memory segments: %u\n", sf_malloc_count);
- (void) fflush(file);
- }
- DBUG_PRINT("safe",("sf_malloc_count: %u", sf_malloc_count));
+ void *frame[SF_REMEMBER_FRAMES + SF_FRAMES_SKIP];
+ int frames= backtrace(frame, array_elements(frame));
+ fprintf(stderr, " ");
+ if (frames < SF_REMEMBER_FRAMES + SF_FRAMES_SKIP)
+ frame[frames]= 0;
+ print_stack(frame + SF_FRAMES_SKIP);
}
+#endif
+}
- /*
- Report on all the memory that was allocated with NEW
- but not free'ed with FREE.
- */
+static int bad_ptr(const char *where, void *ptr)
+{
+ struct st_irem *irem= (struct st_irem *)ptr - 1;
+ const uchar *magicend;
- if ((irem= sf_malloc_root))
+ if (((intptr) ptr) % sizeof(double))
{
- if (file)
- {
- fprintf(file, "Warning: Memory that was not free'ed (%lu bytes):\n",
- (ulong) sf_malloc_cur_memory);
- (void) fflush(file);
- }
- DBUG_PRINT("safe",("Memory that was not free'ed (%lu bytes):",
- (ulong) sf_malloc_cur_memory));
- while (irem)
- {
- char *data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) +
- sf_malloc_prehunc);
- if (file)
- {
- fprintf(file,
- "\t%6lu bytes at %p, allocated at line %4u in '%s'",
- (ulong) irem->datasize, data, irem->linenum, irem->filename);
- fprintf(file, "\n");
- (void) fflush(file);
- }
- DBUG_PRINT("safe",
- ("%6lu bytes at %p, allocated at line %4d in '%s'",
- (ulong) irem->datasize,
- data, irem->linenum, irem->filename));
- irem= irem->next;
- }
+ warn("Error: %s wrong aligned pointer", where);
+ return 1;
}
- /* Report the memory usage statistics */
- if (file && flag)
+ if (ptr < sf_min_adress || ptr > sf_max_adress)
{
- fprintf(file, "Maximum memory usage: %lu bytes (%luk)\n",
- (ulong) sf_malloc_max_memory,
- (ulong) (sf_malloc_max_memory + 1023L) / 1024L);
- (void) fflush(file);
+ warn("Error: %s pointer out of range", where);
+ return 1;
}
- DBUG_PRINT("safe",("Maximum memory usage: %lu bytes (%luk)",
- (ulong) sf_malloc_max_memory,
- (ulong) (sf_malloc_max_memory + 1023L) /1024L));
- pthread_mutex_unlock(&THR_LOCK_malloc);
- DBUG_VOID_RETURN;
-}
-
-
-/*
- Report where a piece of memory was allocated
-
- This is useful to call from withing a debugger
-*/
-
-void sf_malloc_report_allocated(void *memory)
-{
- struct st_irem *irem;
- for (irem= sf_malloc_root ; irem ; irem=irem->next)
+ if (irem->marker != MAGICSTART)
{
- char *data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) +
- sf_malloc_prehunc);
- if (data <= (char*) memory && (char*) memory <= data + irem->datasize)
- {
- printf("%lu bytes at %p, allocated at line %u in '%s'\n",
- (ulong) irem->datasize, data, irem->linenum, irem->filename);
- break;
- }
+ warn("Error: %s unallocated data or underrun buffer", where);
+ return 1;
}
-}
-
- /* Returns 0 if chunk is ok */
-static int _checkchunk(register struct st_irem *irem, const char *filename,
- uint lineno)
-{
- int flag=0;
- char *magicp, *data;
-
- data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) +
- sf_malloc_prehunc);
- /* Check for a possible underrun */
- if (*((uint32*) (data- sizeof(uint32))) != MAGICKEY)
+ magicend= (uchar*)ptr + irem->datasize;
+ if (magicend[0] != MAGICEND0 ||
+ magicend[1] != MAGICEND1 ||
+ magicend[2] != MAGICEND2 ||
+ magicend[3] != MAGICEND3)
{
- fprintf(stderr, "Error: Memory allocated at %s:%d was underrun,",
- irem->filename, irem->linenum);
- fprintf(stderr, " discovered at %s:%d\n", filename, lineno);
- (void) fflush(stderr);
- DBUG_PRINT("safe",("Underrun at %p, allocated at %s:%d",
- data, irem->filename, irem->linenum));
- flag=1;
+ warn("Error: %s overrun buffer ", where);
+ fprintf(stderr, "Allocated at ");
+ print_stack(irem->frame);
+ return 1;
}
- /* Check for a possible overrun */
- magicp= data + irem->datasize;
- if (*magicp++ != MAGICEND0 ||
- *magicp++ != MAGICEND1 ||
- *magicp++ != MAGICEND2 ||
- *magicp++ != MAGICEND3)
- {
- fprintf(stderr, "Error: Memory allocated at %s:%d was overrun,",
- irem->filename, irem->linenum);
- fprintf(stderr, " discovered at '%s:%d'\n", filename, lineno);
- (void) fflush(stderr);
- DBUG_PRINT("safe",("Overrun at %p, allocated at %s:%d",
- data, irem->filename, irem->linenum));
- flag=1;
- }
- return(flag);
+ return 0;
}
-
- /* Returns how many wrong chunks */
-
-int _sanity(const char *filename, uint lineno)
+/* check all allocated memory list for consistency */
+static int sf_sanity()
{
- reg1 struct st_irem *irem;
- reg2 int flag=0;
- uint count=0;
-
- pthread_mutex_lock(&THR_LOCK_malloc);
-#ifndef PEDANTIC_SAFEMALLOC
- if (sf_malloc_tampered && (int) sf_malloc_count < 0)
- sf_malloc_count=0;
-#endif
- count=sf_malloc_count;
- for (irem= sf_malloc_root; irem != NULL && count-- ; irem= irem->next)
- flag+= _checkchunk (irem, filename, lineno);
- pthread_mutex_unlock(&THR_LOCK_malloc);
+ struct st_irem *irem;
+ int flag= 0;
+ int count= 0;
+
+ pthread_mutex_lock(&sf_mutex);
+ count= sf_malloc_count;
+ for (irem= sf_malloc_root; irem && count > 0; count--, irem= irem->next)
+ flag+= bad_ptr("Safemalloc", irem + 1);
+ pthread_mutex_unlock(&sf_mutex);
if (count || irem)
{
- const char *format="Error: Safemalloc link list destroyed, discovered at '%s:%d'";
- fprintf(stderr, format, filename, lineno); fputc('\n',stderr);
- fprintf(stderr, "root=%p,count=%d,irem=%p\n", sf_malloc_root,count,irem);
- (void) fflush(stderr);
- DBUG_PRINT("safe",(format, filename, lineno));
- flag=1;
+ warn("Error: Safemalloc link list destroyed");
+ return 1;
}
- return flag;
-} /* _sanity */
-
-
- /* malloc and copy */
-
-void *_my_memdup(const void *from, size_t length, const char *filename,
- uint lineno, myf MyFlags)
-{
- void *ptr;
- if ((ptr= _mymalloc(length,filename,lineno,MyFlags)) != 0)
- memcpy(ptr, from, length);
- return(ptr);
-} /*_my_memdup */
+ return 0;
+}
+/**
+ report on all the memory pieces that have not been free'd
+*/
-char *_my_strdup(const char *from, const char *filename, uint lineno,
- myf MyFlags)
+static void sf_terminate()
{
- char *ptr;
- size_t length= strlen(from)+1;
- if ((ptr= (char*) _mymalloc(length,filename,lineno,MyFlags)) != 0)
- memcpy((uchar*) ptr, (uchar*) from, (size_t) length);
- return(ptr);
-} /* _my_strdup */
+ size_t total= 0;
+ struct st_irem *irem;
+ sf_sanity();
-char *_my_strndup(const char *from, size_t length,
- const char *filename, uint lineno,
- myf MyFlags)
-{
- char *ptr;
- if ((ptr= (char*) _mymalloc(length+1,filename,lineno,MyFlags)) != 0)
+ /* Report on all the memory that was allocated but not free'd */
+ if (!sf_leaking_memory && sf_malloc_root)
{
- memcpy((uchar*) ptr, (uchar*) from, (size_t) length);
- ptr[length]=0;
+ for (irem= sf_malloc_root; irem; irem= irem->next)
+ {
+ fprintf(stderr, "Warning: %4lu bytes lost, allocated at ",
+ (ulong) irem->datasize);
+ print_stack(irem->frame);
+ total+= irem->datasize;
+ }
+ fprintf(stderr, "Memory lost: %lu bytes in %d chunks\n",
+ (ulong) total, sf_malloc_count);
}
- return(ptr);
+
+ pthread_mutex_destroy(&sf_mutex);
+ return;
}
+
+#endif
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index 2ec526f2535..402520990b6 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2001, 2011, Oracle and/or its affiliates.
+/*
+ Copyright (c) 2001, 2011, Oracle and/or its affiliates
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
@@ -13,13 +14,6 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-/*
- Workaround for Bug#32082: VOID redefinition on Win results in
- compile errors
-*/
-#define DONT_DEFINE_VOID 1
-
#include <my_global.h>
#include <my_stacktrace.h>
@@ -125,12 +119,8 @@ static int safe_print_str(const char *addr, int max_len)
break;
}
- /* Output a new line if something was printed. */
- if (total != (size_t) max_len)
- my_safe_printf_stderr("%s", "\n");
-
if (nbytes == -1)
- my_safe_printf_stderr("Can't read from address %p\n", addr);
+ my_safe_printf_stderr("Can't read from address %p", addr);
close(fd);
@@ -152,7 +142,7 @@ void my_safe_print_str(const char* val, int max_len)
if (!PTR_SANE(val))
{
- my_safe_printf_stderr("%s", "is an invalid pointer\n");
+ my_safe_printf_stderr("%s", "is an invalid pointer");
return;
}
@@ -224,25 +214,52 @@ static void my_demangle_symbols(char **addrs, int n)
#endif /* BACKTRACE_DEMANGLE */
+#if HAVE_MY_ADDR_RESOLVE
+static int print_with_addr_resolve(void **addrs, int n)
+{
+ int i;
+ const char *err;
+
+ if ((err= my_addr_resolve_init()))
+ {
+ my_safe_printf_stderr("(my_addr_resolve failure: %s)\n", err);
+ return 0;
+ }
+
+ for (i= 0; i < n; i++)
+ {
+ my_addr_loc loc;
+ if (my_addr_resolve(addrs[i], &loc))
+ backtrace_symbols_fd(addrs+i, 1, fileno(stderr));
+ else
+ my_safe_printf_stderr("%s:%u(%s)[%p]\n",
+ loc.file, loc.line, loc.func, addrs[i]);
+ }
+ return 1;
+}
+#endif
+
void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
{
void *addrs[128];
- char **strings= NULL;
+ char **strings __attribute__((unused)) = NULL;
int n = backtrace(addrs, array_elements(addrs));
my_safe_printf_stderr("stack_bottom = %p thread_stack 0x%lx\n",
stack_bottom, thread_stack);
+#if HAVE_MY_ADDR_RESOLVE
+ if (print_with_addr_resolve(addrs, n))
+ return;
+#endif
#if BACKTRACE_DEMANGLE
if ((strings= backtrace_symbols(addrs, n)))
{
my_demangle_symbols(strings, n);
free(strings);
+ return;
}
#endif
#if HAVE_BACKTRACE_SYMBOLS_FD
- if (!strings)
- {
- backtrace_symbols_fd(addrs, n, fileno(stderr));
- }
+ backtrace_symbols_fd(addrs, n, fileno(stderr));
#endif
}
@@ -448,46 +465,10 @@ void my_write_core(int sig)
#include <dbghelp.h>
#include <tlhelp32.h>
-
-/*
- Stack tracing on Windows is implemented using Debug Helper
- library(dbghelp.dll) We do not redistribute dbghelp and the one
- comes with older OS (up to Windows 2001) is missing some important
- functions like functions StackWalk64 or MinidumpWriteDump. Hence,
- we have to load functions at runtime using
- LoadLibrary/GetProcAddress.
-*/
-
-typedef DWORD (WINAPI *SymSetOptions_FctType)(DWORD dwOptions);
-typedef BOOL (WINAPI *SymGetModuleInfo64_FctType)
- (HANDLE,DWORD64,PIMAGEHLP_MODULE64) ;
-typedef BOOL (WINAPI *SymGetSymFromAddr64_FctType)
- (HANDLE,DWORD64,PDWORD64,PIMAGEHLP_SYMBOL64) ;
-typedef BOOL (WINAPI *SymGetLineFromAddr64_FctType)
- (HANDLE,DWORD64,PDWORD,PIMAGEHLP_LINE64);
-typedef BOOL (WINAPI *SymInitialize_FctType)
- (HANDLE,PSTR,BOOL);
-typedef BOOL (WINAPI *StackWalk64_FctType)
- (DWORD,HANDLE,HANDLE,LPSTACKFRAME64,PVOID,PREAD_PROCESS_MEMORY_ROUTINE64,
- PFUNCTION_TABLE_ACCESS_ROUTINE64,PGET_MODULE_BASE_ROUTINE64 ,
- PTRANSLATE_ADDRESS_ROUTINE64);
-typedef BOOL (WINAPI *MiniDumpWriteDump_FctType)(
- IN HANDLE hProcess,
- IN DWORD ProcessId,
- IN HANDLE hFile,
- IN MINIDUMP_TYPE DumpType,
- IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
- IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
- IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
- );
-
-static SymSetOptions_FctType pSymSetOptions;
-static SymGetModuleInfo64_FctType pSymGetModuleInfo64;
-static SymGetSymFromAddr64_FctType pSymGetSymFromAddr64;
-static SymInitialize_FctType pSymInitialize;
-static StackWalk64_FctType pStackWalk64;
-static SymGetLineFromAddr64_FctType pSymGetLineFromAddr64;
-static MiniDumpWriteDump_FctType pMiniDumpWriteDump;
+#include <my_sys.h>
+#if _MSC_VER
+#pragma comment(lib, "dbghelp")
+#endif
static EXCEPTION_POINTERS *exception_ptrs;
@@ -498,50 +479,24 @@ void my_init_stacktrace()
{
}
-/*
- Dynamically load dbghelp functions
-*/
-BOOL init_dbghelp_functions()
-{
- static BOOL first_time= TRUE;
- static BOOL rc;
- HMODULE hDbghlp;
-
- if(first_time)
- {
- first_time= FALSE;
- hDbghlp= LoadLibrary("dbghelp");
- if(!hDbghlp)
- {
- rc= FALSE;
- return rc;
- }
- pSymSetOptions= (SymSetOptions_FctType)
- GetProcAddress(hDbghlp,"SymSetOptions");
- pSymInitialize= (SymInitialize_FctType)
- GetProcAddress(hDbghlp,"SymInitialize");
- pSymGetModuleInfo64= (SymGetModuleInfo64_FctType)
- GetProcAddress(hDbghlp,"SymGetModuleInfo64");
- pSymGetLineFromAddr64= (SymGetLineFromAddr64_FctType)
- GetProcAddress(hDbghlp,"SymGetLineFromAddr64");
- pSymGetSymFromAddr64=(SymGetSymFromAddr64_FctType)
- GetProcAddress(hDbghlp,"SymGetSymFromAddr64");
- pStackWalk64= (StackWalk64_FctType)
- GetProcAddress(hDbghlp,"StackWalk64");
- pMiniDumpWriteDump = (MiniDumpWriteDump_FctType)
- GetProcAddress(hDbghlp,"MiniDumpWriteDump");
-
- rc = (BOOL)(pSymSetOptions && pSymInitialize && pSymGetModuleInfo64
- && pSymGetLineFromAddr64 && pSymGetSymFromAddr64 && pStackWalk64);
- }
- return rc;
-}
void my_set_exception_pointers(EXCEPTION_POINTERS *ep)
{
exception_ptrs = ep;
}
+/*
+ Appends directory to symbol path.
+*/
+static void add_to_symbol_path(char *path, size_t path_buffer_size,
+ char *dir, size_t dir_buffer_size)
+{
+ strcat_s(dir, dir_buffer_size, ";");
+ if (!strstr(path, dir))
+ {
+ strcat_s(path, path_buffer_size, dir);
+ }
+}
/*
Get symbol path - semicolon-separated list of directories to search
@@ -554,8 +509,28 @@ static void get_symbol_path(char *path, size_t size)
{
HANDLE hSnap;
char *envvar;
+ char *p;
+#ifndef DBUG_OFF
+ static char pdb_debug_dir[MAX_PATH + 7];
+#endif
path[0]= '\0';
+
+#ifndef DBUG_OFF
+ /*
+ Add "debug" subdirectory of the application directory, sometimes PDB will
+ placed here by installation.
+ */
+ GetModuleFileName(NULL, pdb_debug_dir, MAX_PATH);
+ p= strrchr(pdb_debug_dir, '\\');
+ if(p)
+ {
+ *p= 0;
+ strcat_s(pdb_debug_dir, sizeof(pdb_debug_dir), "\\debug;");
+ add_to_symbol_path(path, size, pdb_debug_dir, sizeof(pdb_debug_dir));
+ }
+#endif
+
/*
Enumerate all modules, and add their directories to the path.
Avoid duplicate entries.
@@ -569,7 +544,7 @@ static void get_symbol_path(char *path, size_t size)
for (ret= Module32First(hSnap, &mod); ret; ret= Module32Next(hSnap, &mod))
{
char *module_dir= mod.szExePath;
- char *p= strrchr(module_dir,'\\');
+ p= strrchr(module_dir,'\\');
if (!p)
{
/*
@@ -577,29 +552,23 @@ static void get_symbol_path(char *path, size_t size)
will indicate current directory.
*/
module_dir[0]= '.';
- p= module_dir + 1;
+ module_dir[1]= '\0';
}
- *p++= ';';
- *p= '\0';
-
- if (!strstr(path, module_dir))
+ else
{
- size_t dir_len = strlen(module_dir);
- if (size > dir_len)
- {
- strncat(path, module_dir, size-1);
- size -= dir_len;
- }
+ *p= '\0';
}
+ add_to_symbol_path(path, size, module_dir,sizeof(mod.szExePath));
}
CloseHandle(hSnap);
}
+
/* Add _NT_SYMBOL_PATH, if present. */
envvar= getenv("_NT_SYMBOL_PATH");
- if(envvar && size)
+ if(envvar)
{
- strncat(path, envvar, size-1);
+ strcat_s(path, size, envvar);
}
}
@@ -623,15 +592,15 @@ void my_print_stacktrace(uchar* unused1, ulong unused2)
STACKFRAME64 frame={0};
static char symbol_path[MAX_SYMBOL_PATH];
- if(!exception_ptrs || !init_dbghelp_functions())
+ if(!exception_ptrs)
return;
/* Copy context, as stackwalking on original will unwind the stack */
context = *(exception_ptrs->ContextRecord);
/*Initialize symbols.*/
- pSymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_NO_PROMPTS|SYMOPT_DEFERRED_LOADS|SYMOPT_DEBUG);
+ SymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_NO_PROMPTS|SYMOPT_DEFERRED_LOADS|SYMOPT_DEBUG);
get_symbol_path(symbol_path, sizeof(symbol_path));
- pSymInitialize(hProcess, symbol_path, TRUE);
+ SymInitialize(hProcess, symbol_path, TRUE);
/*Prepare stackframe for the first StackWalk64 call*/
frame.AddrFrame.Mode= frame.AddrPC.Mode= frame.AddrStack.Mode= AddrModeFlat;
@@ -663,11 +632,11 @@ void my_print_stacktrace(uchar* unused1, ulong unused2)
BOOL have_symbol= FALSE;
BOOL have_source= FALSE;
- if(!pStackWalk64(machine, hProcess, hThread, &frame, &context, 0, 0, 0 ,0))
+ if(!StackWalk64(machine, hProcess, hThread, &frame, &context, 0, 0, 0 ,0))
break;
addr= frame.AddrPC.Offset;
- have_module= pSymGetModuleInfo64(hProcess,addr,&module);
+ have_module= SymGetModuleInfo64(hProcess,addr,&module);
#ifdef _M_IX86
if(!have_module)
{
@@ -677,22 +646,17 @@ void my_print_stacktrace(uchar* unused1, ulong unused2)
dbghelp.dll function happy, pretend passing the old structure.
*/
module.SizeOfStruct= MODULE64_SIZE_WINXP;
- have_module= pSymGetModuleInfo64(hProcess, addr, &module);
+ have_module= SymGetModuleInfo64(hProcess, addr, &module);
}
#endif
- have_symbol= pSymGetSymFromAddr64(hProcess, addr, &function_offset,
+ have_symbol= SymGetSymFromAddr64(hProcess, addr, &function_offset,
&(package.sym));
- have_source= pSymGetLineFromAddr64(hProcess, addr, &line_offset, &line);
+ have_source= SymGetLineFromAddr64(hProcess, addr, &line_offset, &line);
- my_safe_printf_stderr("%p ", addr);
if(have_module)
{
- char *base_image_name= strrchr(module.ImageName, '\\');
- if(base_image_name)
- base_image_name++;
- else
- base_image_name= module.ImageName;
+ const char *base_image_name= my_basename(module.ImageName);
my_safe_printf_stderr("%s!", base_image_name);
}
if(have_symbol)
@@ -703,11 +667,7 @@ void my_print_stacktrace(uchar* unused1, ulong unused2)
if(have_source)
{
- char *base_file_name= strrchr(line.FileName, '\\');
- if(base_file_name)
- base_file_name++;
- else
- base_file_name= line.FileName;
+ const char *base_file_name= my_basename(line.FileName);
my_safe_printf_stderr("[%s:%u]",
base_file_name, line.LineNumber);
}
@@ -728,7 +688,7 @@ void my_write_core(int unused)
MINIDUMP_EXCEPTION_INFORMATION info;
HANDLE hFile;
- if(!exception_ptrs || !init_dbghelp_functions() || !pMiniDumpWriteDump)
+ if(!exception_ptrs)
return;
info.ExceptionPointers= exception_ptrs;
@@ -746,7 +706,7 @@ void my_write_core(int unused)
if(hFile)
{
/* Create minidump */
- if(pMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
+ if(MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
hFile, MiniDumpNormal, &info, 0, 0))
{
my_safe_printf_stderr("Minidump written to %s\n",
@@ -776,7 +736,7 @@ void my_safe_print_str(const char *val, int len)
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
- my_safe_printf_stderr("%s", "is an invalid string pointer\n");
+ my_safe_printf_stderr("%s", "is an invalid string pointer");
}
}
#endif /*__WIN__*/
@@ -794,7 +754,7 @@ size_t my_safe_printf_stderr(const char* fmt, ...)
size_t result;
va_list args;
va_start(args,fmt);
- result= vsnprintf(to, sizeof(to), fmt, args);
+ result= my_vsnprintf(to, sizeof(to), fmt, args);
va_end(args);
my_write_stderr(to, result);
return result;
diff --git a/mysys/string.c b/mysys/string.c
index 1cbce7ca4e1..d9791341c60 100644
--- a/mysys/string.c
+++ b/mysys/string.c
@@ -1,6 +1,4 @@
-/*
- Copyright (c) 2000, 2001, 2005-2007 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* Copyright (c) 2000, 2010, 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
@@ -13,8 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
Code for handling strings with can grow dynamicly.
@@ -101,20 +98,21 @@ my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
size_t length)
{
char *new_ptr;
+ DBUG_ENTER("dynstr_append_mem");
if (str->length+length >= str->max_length)
{
size_t new_length=(str->length+length+str->alloc_increment)/
str->alloc_increment;
new_length*=str->alloc_increment;
if (!(new_ptr=(char*) my_realloc(str->str,new_length,MYF(MY_WME))))
- return TRUE;
+ DBUG_RETURN(TRUE);
str->str=new_ptr;
str->max_length=new_length;
}
memcpy(str->str + str->length,append,length);
str->length+=length;
str->str[str->length]=0; /* Safety for C programs */
- return FALSE;
+ DBUG_RETURN(FALSE);
}
@@ -180,11 +178,8 @@ my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append, ...)
void dynstr_free(DYNAMIC_STRING *str)
{
- if (str->str)
- {
- my_free(str->str,MYF(MY_WME));
- str->str=0;
- }
+ my_free(str->str);
+ str->str= NULL;
}
diff --git a/mysys/test_charset.c b/mysys/test_charset.c
index d867b49304e..49e25b8d5cd 100644
--- a/mysys/test_charset.c
+++ b/mysys/test_charset.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <my_global.h>
#include <m_ctype.h>
@@ -77,15 +77,5 @@ int main(int argc, char **argv) {
_print_csinfo(cs);
fflush(stdout);
-#ifdef NOT_USED_ANYMORE
- cs_list = list_charsets(MYF(MY_CS_COMPILED | MY_CS_CONFIG));
- printf("LIST OF CHARSETS (compiled + *.conf):\n%s\n", cs_list);
- my_free(cs_list,MYF(0));
-
- cs_list = list_charsets(MYF(MY_CS_INDEX | MY_CS_LOADED));
- printf("LIST OF CHARSETS (index + loaded):\n%s\n", cs_list);
- my_free(cs_list,MYF(0));
-#endif
-
return 0;
}
diff --git a/mysys/test_fn.c b/mysys/test_fn.c
deleted file mode 100644
index 249cc878390..00000000000
--- a/mysys/test_fn.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Copyright (C) 2000 MySQL 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "mysys_priv.h"
-
-const char *test_names[]=
-{
- "/usr/my/include/srclib/myfunc/dbug/test",
- "test",
- "dbug/test",
- "/usr/my/srclib/myfunc/dbug/test",
- "/usr/monty/oldcopy/jazz/setupp.frm",
- "~/monty.tst",
- "~/dbug/monty.tst",
- "./hejsan",
- "./dbug/test",
- "../dbug/test",
- "../myfunc/test",
- "../../monty/rutedit",
- "/usr/monty//usr/monty/rutedit",
- "/usr/./monty/rutedit",
- "/usr/my/../monty/rutedit",
- "/usr/my/~/rutedit",
- "~/../my",
- "~/../my/srclib/myfunc/test",
- "~/../my/srclib/myfunc/./dbug/test",
- "/../usr/my/srclib/dbug",
- "c/../my",
- "/c/../my",
- NullS,
-};
-
-int main(int argc __attribute__((unused)), char **argv)
-{
- const char **pos;
- char buff[FN_REFLEN],buff2[FN_REFLEN];
- DBUG_ENTER ("main");
- DBUG_PROCESS (argv[0]);
- MY_INIT(argv[0]);
-
- if (argv[1] && argv[1][1] == '#')
- DBUG_PUSH(argv[1]+2);
-
- for (pos=test_names; *pos ; pos++)
- {
- printf("org : '%s'\n",*pos);
- printf("pack: '%s'\n",fn_format(buff,*pos,"","",8));
- printf("unpack: '%s'\n",fn_format(buff2,*pos,"","",4));
- unpack_filename(buff,buff);
- if (strcmp(buff,buff2) != 0)
- {
- printf("error on cmp: '%s' != '%s'\n",buff,buff2);
- }
- puts("");
- }
- DBUG_RETURN(0);
-}
diff --git a/mysys/testhash.c b/mysys/testhash.c
index 2add2ebd2d7..ffdaaece770 100644
--- a/mysys/testhash.c
+++ b/mysys/testhash.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* Test of hash library: big test */
@@ -286,5 +286,5 @@ static int rnd(int max_value)
void free_record(void *record)
{
- my_free(record,MYF(0));
+ my_free(record);
}
diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c
index b6d2ce46ccc..9c21033eca4 100644
--- a/mysys/thr_alarm.c
+++ b/mysys/thr_alarm.c
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
+ Copyright (c) 2012, Monty Program 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
@@ -12,14 +13,14 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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(THREAD) && !defined(DONT_USE_THR_ALARM)
+#if !defined(DONT_USE_THR_ALARM)
#include <errno.h>
#include <my_pthread.h>
#include <signal.h>
@@ -58,8 +59,8 @@ static sig_handler process_alarm_part2(int sig);
#if !defined(__WIN__)
-static pthread_mutex_t LOCK_alarm;
-static pthread_cond_t COND_alarm;
+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;
@@ -67,7 +68,7 @@ pthread_t alarm_thread;
#ifdef USE_ALARM_THREAD
static void *alarm_handler(void *arg);
-#define reschedule_alarms() pthread_cond_signal(&COND_alarm)
+#define reschedule_alarms() mysql_cond_signal(&COND_alarm)
#else
#define reschedule_alarms() pthread_kill(alarm_thread,THR_SERVER_ALARM)
#endif
@@ -90,8 +91,8 @@ void init_thr_alarm(uint max_alarms)
init_queue(&alarm_queue, max_alarms+1, offsetof(ALARM,expire_time), 0,
compare_ulong, NullS, offsetof(ALARM, index_in_queue)+1, 0);
sigfillset(&full_signal_set); /* Neaded to block signals */
- pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST);
- pthread_cond_init(&COND_alarm,NULL);
+ mysql_mutex_init(key_LOCK_alarm, &LOCK_alarm, MY_MUTEX_INIT_FAST);
+ mysql_cond_init(key_COND_alarm, &COND_alarm, NULL);
if (thd_lib_detected == THD_LIB_LT)
thr_client_alarm= SIGALRM;
else
@@ -112,10 +113,9 @@ void init_thr_alarm(uint max_alarms)
pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
pthread_attr_setstacksize(&thr_attr,8196);
-
- my_pthread_attr_setprio(&thr_attr,100); /* Very high priority */
- VOID(pthread_create(&alarm_thread,&thr_attr,alarm_handler,NULL));
- VOID(pthread_attr_destroy(&thr_attr));
+ 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() */
@@ -134,14 +134,14 @@ void init_thr_alarm(uint max_alarms)
void resize_thr_alarm(uint max_alarms)
{
- pthread_mutex_lock(&LOCK_alarm);
+ 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);
- pthread_mutex_unlock(&LOCK_alarm);
+ mysql_mutex_unlock(&LOCK_alarm);
}
@@ -206,7 +206,7 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
alarm_data->thread_id= current_my_thread_var->id;
one_signal_hand_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
- pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */
+ mysql_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */
if (alarm_queue.elements >= max_used_alarms)
{
if (alarm_queue.elements == alarm_queue.max_elements)
@@ -233,15 +233,15 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
else
reschedule_alarms(); /* Reschedule alarms */
}
- pthread_mutex_unlock(&LOCK_alarm);
+ mysql_mutex_unlock(&LOCK_alarm);
one_signal_hand_sigmask(SIG_SETMASK,&old_mask,NULL);
(*alrm)= &alarm_data->alarmed;
DBUG_RETURN(0);
abort:
if (alarm_data->malloced)
- my_free(alarm_data, MYF(0));
- pthread_mutex_unlock(&LOCK_alarm);
+ my_free(alarm_data);
+ mysql_mutex_unlock(&LOCK_alarm);
one_signal_hand_sigmask(SIG_SETMASK,&old_mask,NULL);
abort_no_unlock:
*alrm= 0; /* No alarm */
@@ -265,12 +265,12 @@ void thr_end_alarm(thr_alarm_t *alarmed)
DBUG_VOID_RETURN;
one_signal_hand_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
alarm_data= (ALARM*) ((uchar*) *alarmed - offsetof(ALARM,alarmed));
- pthread_mutex_lock(&LOCK_alarm);
+ mysql_mutex_lock(&LOCK_alarm);
DBUG_ASSERT(alarm_data->index_in_queue != 0);
DBUG_ASSERT(queue_element(&alarm_queue, alarm_data->index_in_queue) ==
alarm_data);
queue_remove(&alarm_queue, alarm_data->index_in_queue);
- pthread_mutex_unlock(&LOCK_alarm);
+ mysql_mutex_unlock(&LOCK_alarm);
one_signal_hand_sigmask(SIG_SETMASK,&old_mask,NULL);
reset_index_in_queue(alarm_data);
DBUG_VOID_RETURN;
@@ -312,14 +312,14 @@ sig_handler process_alarm(int sig __attribute__((unused)))
#ifndef USE_ALARM_THREAD
pthread_sigmask(SIG_SETMASK,&full_signal_set,&old_mask);
- pthread_mutex_lock(&LOCK_alarm);
+ 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
- pthread_mutex_unlock(&LOCK_alarm);
+ mysql_mutex_unlock(&LOCK_alarm);
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
#endif
return;
@@ -430,7 +430,7 @@ void end_thr_alarm(my_bool free_structures)
DBUG_ENTER("end_thr_alarm");
if (alarm_aborted != 1) /* If memory not freed */
{
- pthread_mutex_lock(&LOCK_alarm);
+ mysql_mutex_lock(&LOCK_alarm);
DBUG_PRINT("info",("Resheduling %d waiting alarms",alarm_queue.elements));
alarm_aborted= -1; /* mark aborted */
if (alarm_queue.elements || (alarm_thread_running && free_structures))
@@ -450,21 +450,21 @@ void end_thr_alarm(my_bool free_structures)
set_timespec(abstime, 10); /* Wait up to 10 seconds */
while (alarm_thread_running)
{
- int error= pthread_cond_timedwait(&COND_alarm, &LOCK_alarm, &abstime);
+ 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;
- pthread_mutex_unlock(&LOCK_alarm);
+ mysql_mutex_unlock(&LOCK_alarm);
if (!alarm_thread_running) /* Safety */
{
- pthread_mutex_destroy(&LOCK_alarm);
- pthread_cond_destroy(&COND_alarm);
+ mysql_mutex_destroy(&LOCK_alarm);
+ mysql_cond_destroy(&COND_alarm);
}
}
else
- pthread_mutex_unlock(&LOCK_alarm);
+ mysql_mutex_unlock(&LOCK_alarm);
}
DBUG_VOID_RETURN;
}
@@ -481,7 +481,7 @@ void thr_alarm_kill(my_thread_id thread_id)
if (alarm_aborted)
return;
- pthread_mutex_lock(&LOCK_alarm);
+ mysql_mutex_lock(&LOCK_alarm);
for (i= queue_first_element(&alarm_queue) ;
i <= queue_last_element(&alarm_queue);
i++)
@@ -496,14 +496,14 @@ void thr_alarm_kill(my_thread_id thread_id)
break;
}
}
- pthread_mutex_unlock(&LOCK_alarm);
+ mysql_mutex_unlock(&LOCK_alarm);
DBUG_VOID_RETURN;
}
void thr_alarm_info(ALARM_INFO *info)
{
- pthread_mutex_lock(&LOCK_alarm);
+ mysql_mutex_lock(&LOCK_alarm);
info->next_alarm_time= 0;
info->max_used_alarms= max_used_alarms;
if ((info->active_alarms= alarm_queue.elements))
@@ -514,7 +514,7 @@ void thr_alarm_info(ALARM_INFO *info)
time_diff= (long) (alarm_data->expire_time - now);
info->next_alarm_time= (ulong) (time_diff < 0 ? 0 : time_diff);
}
- pthread_mutex_unlock(&LOCK_alarm);
+ mysql_mutex_unlock(&LOCK_alarm);
}
/*
@@ -551,7 +551,7 @@ static void *alarm_handler(void *arg __attribute__((unused)))
#endif
my_thread_init();
alarm_thread_running= 1;
- pthread_mutex_lock(&LOCK_alarm);
+ mysql_mutex_lock(&LOCK_alarm);
for (;;)
{
if (alarm_queue.elements)
@@ -566,7 +566,7 @@ static void *alarm_handler(void *arg __attribute__((unused)))
abstime.tv_sec=sleep_time;
abstime.tv_nsec=0;
next_alarm_expire_time= sleep_time;
- if ((error=pthread_cond_timedwait(&COND_alarm,&LOCK_alarm,&abstime)) &&
+ if ((error= mysql_cond_timedwait(&COND_alarm, &LOCK_alarm, &abstime)) &&
error != ETIME && error != ETIMEDOUT)
{
#ifdef MAIN
@@ -581,7 +581,7 @@ static void *alarm_handler(void *arg __attribute__((unused)))
else
{
next_alarm_expire_time= ~ (time_t) 0;
- if ((error=pthread_cond_wait(&COND_alarm,&LOCK_alarm)))
+ if ((error= mysql_cond_wait(&COND_alarm, &LOCK_alarm)))
{
#ifdef MAIN
printf("Got error: %d from ptread_cond_wait (errno: %d)\n",
@@ -593,111 +593,23 @@ static void *alarm_handler(void *arg __attribute__((unused)))
}
bzero((char*) &alarm_thread,sizeof(alarm_thread)); /* For easy debugging */
alarm_thread_running= 0;
- pthread_cond_signal(&COND_alarm);
- pthread_mutex_unlock(&LOCK_alarm);
+ mysql_cond_signal(&COND_alarm);
+ mysql_mutex_unlock(&LOCK_alarm);
pthread_exit(0);
return 0; /* Impossible */
}
#endif /* USE_ALARM_THREAD */
-
-/*****************************************************************************
- thr_alarm for win95
-*****************************************************************************/
-
-#else /* __WIN__ */
-
-void thr_alarm_kill(my_thread_id thread_id)
-{
- /* Can't do this yet */
-}
-
-sig_handler process_alarm(int sig __attribute__((unused)))
-{
- /* Can't do this yet */
-}
-
-
-my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm)
-{
- (*alrm)= &alarm->alarmed;
- if (alarm_aborted)
- {
- alarm->alarmed.crono=0;
- return 1;
- }
- if (!(alarm->alarmed.crono=SetTimer((HWND) NULL,0, sec*1000,
- (TIMERPROC) NULL)))
- return 1;
- return 0;
-}
-
-
-my_bool thr_got_alarm(thr_alarm_t *alrm_ptr)
-{
- thr_alarm_t alrm= *alrm_ptr;
- MSG msg;
- if (alrm->crono)
- {
- PeekMessage(&msg,NULL,WM_TIMER,WM_TIMER,PM_REMOVE) ;
- if (msg.message == WM_TIMER || alarm_aborted)
- {
- KillTimer(NULL, alrm->crono);
- alrm->crono = 0;
- }
- }
- return !alrm->crono || alarm_aborted;
-}
-
-
-void thr_end_alarm(thr_alarm_t *alrm_ptr)
-{
- thr_alarm_t alrm= *alrm_ptr;
- /* alrm may be zero if thr_alarm aborted with an error */
- if (alrm && alrm->crono)
-
- {
- KillTimer(NULL, alrm->crono);
- alrm->crono = 0;
- }
-}
-
-void end_thr_alarm(my_bool free_structures)
-{
- DBUG_ENTER("end_thr_alarm");
- alarm_aborted=1; /* No more alarms */
- DBUG_VOID_RETURN;
-}
-
-void init_thr_alarm(uint max_alarm)
-{
- DBUG_ENTER("init_thr_alarm");
- alarm_aborted=0; /* Yes, Gimmie alarms */
- DBUG_VOID_RETURN;
-}
-
-void thr_alarm_info(ALARM_INFO *info)
-{
- bzero((char*) info, sizeof(*info));
-}
-
-void resize_thr_alarm(uint max_alarms)
-{
-}
-
-#endif /* __WIN__ */
-
-#endif /* THREAD */
-
+#endif
/****************************************************************************
Handling of test case (when compiled with -DMAIN)
***************************************************************************/
#ifdef MAIN
-#if defined(THREAD) && !defined(DONT_USE_THR_ALARM)
+#if !defined(DONT_USE_THR_ALARM)
-static pthread_cond_t COND_thread_count;
-static pthread_mutex_t LOCK_thread_count;
+static mysql_cond_t COND_thread_count;
+static mysql_mutex_t LOCK_thread_count;
static uint thread_count;
#ifdef HPUX10
@@ -774,7 +686,7 @@ static void *test_thread(void *arg)
break;
continue;
}
- VOID(getchar()); /* Somebody was playing */
+ (void) getchar(); /* Somebody was playing */
}
}
}
@@ -784,10 +696,10 @@ static void *test_thread(void *arg)
thr_end_alarm(&got_alarm);
fflush(stdout);
}
- pthread_mutex_lock(&LOCK_thread_count);
+ mysql_mutex_lock(&LOCK_thread_count);
thread_count--;
- VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
- pthread_mutex_unlock(&LOCK_thread_count);
+ mysql_cond_signal(&COND_thread_count); /* Tell main we are ready */
+ mysql_mutex_unlock(&LOCK_thread_count);
free((uchar*) arg);
return 0;
}
@@ -801,9 +713,9 @@ static void *signal_hand(void *arg __attribute__((unused)))
my_thread_init();
pthread_detach_this_thread();
init_thr_alarm(10); /* Setup alarm handler */
- pthread_mutex_lock(&LOCK_thread_count); /* Required by bsdi */
- VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
- pthread_mutex_unlock(&LOCK_thread_count);
+ 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);
@@ -874,8 +786,8 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
{
DBUG_PUSH(argv[1]+2);
}
- pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
- pthread_cond_init(&COND_thread_count,NULL);
+ 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);
@@ -890,11 +802,6 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
sigaddset(&set,THR_SERVER_ALARM);
sigdelset(&set, thr_client_alarm);
(void) pthread_sigmask(SIG_SETMASK,&set,NULL);
-#ifdef NOT_USED
- sigemptyset(&set);
- sigaddset(&set, thr_client_alarm);
- VOID(pthread_sigmask(SIG_UNBLOCK, &set, (sigset_t*) 0));
-#endif
pthread_attr_init(&thr_attr);
pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
@@ -902,10 +809,11 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
pthread_attr_setstacksize(&thr_attr,65536L);
/* Start signal thread and wait for it to start */
- VOID(pthread_mutex_lock(&LOCK_thread_count));
- pthread_create(&tid,&thr_attr,signal_hand,NULL);
- VOID(pthread_cond_wait(&COND_thread_count,&LOCK_thread_count));
- VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ 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);
@@ -915,32 +823,34 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
{
param=(int*) malloc(sizeof(int));
*param= i;
- pthread_mutex_lock(&LOCK_thread_count);
- if ((error=pthread_create(&tid,&thr_attr,test_thread,(void*) param)))
+ mysql_mutex_lock(&LOCK_thread_count);
+ if ((error= mysql_thread_create(0,
+ &tid, &thr_attr, test_thread,
+ (void*) param)))
{
printf("Can't create thread %d, error: %d\n",i,error);
exit(1);
}
thread_count++;
- pthread_mutex_unlock(&LOCK_thread_count);
+ mysql_mutex_unlock(&LOCK_thread_count);
}
pthread_attr_destroy(&thr_attr);
- pthread_mutex_lock(&LOCK_thread_count);
+ 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)
{
- VOID(pthread_cond_wait(&COND_thread_count,&LOCK_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);
}
}
- pthread_mutex_unlock(&LOCK_thread_count);
+ 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",
@@ -950,17 +860,14 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
return 0;
}
-#else /* THREAD */
+#else /* !defined(DONT_USE_ALARM_THREAD) */
int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
{
-#ifndef THREAD
- printf("thr_alarm disabled because we are not using threads\n");
-#else
printf("thr_alarm disabled with DONT_USE_THR_ALARM\n");
-#endif
exit(1);
}
-#endif /* THREAD */
+#endif /* !defined(DONT_USE_ALARM_THREAD) */
+#endif /* WIN */
#endif /* MAIN */
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index b1722e0bfdf..a7cbfa07db2 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
+ Copyright (c) 2012, Monty Program 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
@@ -12,8 +13,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
Read and write locks for Posix threads. All tread must acquire
@@ -31,7 +31,6 @@ TL_READ_WITH_SHARED_LOCKS
TL_READ_HIGH_PRIORITY # High priority read
TL_READ_NO_INSERT # Read without concurrent inserts
TL_WRITE_ALLOW_WRITE # Write lock that allows other writers
-TL_WRITE_ALLOW_READ # Write lock, but allow reading
TL_WRITE_CONCURRENT_INSERT
# Insert that can be mixed when selects
TL_WRITE_DELAYED # Used by delayed insert
@@ -43,7 +42,7 @@ TL_WRITE_ONLY # High priority write
Locks are prioritized according to:
-WRITE_ALLOW_WRITE, WRITE_ALLOW_READ, WRITE_CONCURRENT_INSERT, WRITE_DELAYED,
+WRITE_ALLOW_WRITE, WRITE_CONCURRENT_INSERT, WRITE_DELAYED,
WRITE_LOW_PRIORITY, READ, WRITE, READ_HIGH_PRIORITY and WRITE_ONLY
Locks in the same privilege level are scheduled in first-in-first-out order.
@@ -75,9 +74,8 @@ get_status:
In MyISAM this stores the number of rows and size of the datafile
for concurrent reads.
-The lock algorithm allows one to have one TL_WRITE_ALLOW_READ,
-TL_WRITE_CONCURRENT_INSERT or one TL_WRITE_DELAYED lock at the same
-time as multiple read locks.
+The lock algorithm allows one to have one TL_WRITE_CONCURRENT_INSERT or
+one TL_WRITE_DELAYED lock at the same time as multiple read locks.
In addition, if lock->allow_multiple_concurrent_insert is set then there can
be any number of TL_WRITE_CONCURRENT_INSERT locks aktive at the same time.
@@ -89,14 +87,12 @@ be any number of TL_WRITE_CONCURRENT_INSERT locks aktive at the same time.
#include "mysys_priv.h"
-#ifdef THREAD
#include "thr_lock.h"
#include <m_string.h>
#include <errno.h>
my_bool thr_lock_inited=0;
ulong locks_immediate = 0L, locks_waited = 0L;
-ulong table_lock_wait_timeout;
enum thr_lock_type thr_upgraded_concurrent_insert_lock = TL_WRITE;
/* The following constants are only for debug output */
@@ -107,7 +103,17 @@ enum thr_lock_type thr_upgraded_concurrent_insert_lock = TL_WRITE;
LIST *thr_lock_thread_list; /* List of threads in use */
ulong max_write_lock_count= ~(ulong) 0L;
-static inline pthread_cond_t *get_cond(void)
+static void (*before_lock_wait)(void)= 0;
+static void (*after_lock_wait)(void)= 0;
+
+void thr_set_lock_wait_callback(void (*before_wait)(void),
+ void (*after_wait)(void))
+{
+ before_lock_wait= before_wait;
+ after_lock_wait= after_wait;
+}
+
+static inline mysql_cond_t *get_cond(void)
{
return &my_thread_var->suspend;
}
@@ -137,15 +143,18 @@ static inline pthread_cond_t *get_cond(void)
*/
-inline int LOCK_CMP(THR_LOCK_DATA *A, THR_LOCK_DATA *B)
+static inline int LOCK_CMP(THR_LOCK_DATA *a, THR_LOCK_DATA *b)
{
- if (A->lock != B->lock)
- return A->lock < B->lock;
- if (A->type != B->type)
- return A->type > B->type; /* Prioritize read */
- return A->priority < B->priority;
+ if (a->lock != b->lock)
+ return a->lock < b->lock;
+
+ if (a->type != b->type)
+ return a->type > b->type;
+
+ return a->priority < b->priority;
}
+
/*
For the future (now the thread specific cond is alloced by my_pthread.c)
*/
@@ -157,7 +166,7 @@ my_bool init_thr_lock()
}
static inline my_bool
-thr_lock_owner_equal(THR_LOCK_OWNER *rhs, THR_LOCK_OWNER *lhs)
+thr_lock_owner_equal(THR_LOCK_INFO *rhs, THR_LOCK_INFO *lhs)
{
return rhs == lhs;
}
@@ -178,7 +187,7 @@ static int check_lock(struct st_lock_list *list, const char* lock_type,
if (list->data)
{
enum thr_lock_type last_lock_type= list->data->type;
- THR_LOCK_OWNER *first_owner= list->data->owner;
+ THR_LOCK_INFO *first_owner= list->data->owner;
for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next)
{
@@ -310,7 +319,6 @@ static void check_locks(THR_LOCK *lock, const char *where,
(((lock->write_wait.data->type == TL_WRITE_CONCURRENT_INSERT ||
lock->write_wait.data->type == TL_WRITE_ALLOW_WRITE) &&
!lock->read_no_write_count) ||
- lock->write_wait.data->type == TL_WRITE_ALLOW_READ ||
(lock->write_wait.data->type == TL_WRITE_DELAYED &&
!lock->read.data)))
{
@@ -416,16 +424,16 @@ void thr_lock_init(THR_LOCK *lock)
{
DBUG_ENTER("thr_lock_init");
bzero((char*) lock,sizeof(*lock));
- VOID(pthread_mutex_init(&lock->mutex,MY_MUTEX_INIT_FAST));
+ mysql_mutex_init(key_THR_LOCK_mutex, &lock->mutex, MY_MUTEX_INIT_FAST);
lock->read.last= &lock->read.data;
lock->read_wait.last= &lock->read_wait.data;
lock->write_wait.last= &lock->write_wait.data;
lock->write.last= &lock->write.data;
- pthread_mutex_lock(&THR_LOCK_lock); /* Add to locks in use */
+ mysql_mutex_lock(&THR_LOCK_lock); /* Add to locks in use */
lock->list.data=(void*) lock;
thr_lock_thread_list=list_add(thr_lock_thread_list,&lock->list);
- pthread_mutex_unlock(&THR_LOCK_lock);
+ mysql_mutex_unlock(&THR_LOCK_lock);
DBUG_VOID_RETURN;
}
@@ -433,10 +441,10 @@ void thr_lock_init(THR_LOCK *lock)
void thr_lock_delete(THR_LOCK *lock)
{
DBUG_ENTER("thr_lock_delete");
- pthread_mutex_lock(&THR_LOCK_lock);
+ mysql_mutex_lock(&THR_LOCK_lock);
thr_lock_thread_list=list_delete(thr_lock_thread_list,&lock->list);
- pthread_mutex_unlock(&THR_LOCK_lock);
- pthread_mutex_destroy(&lock->mutex);
+ mysql_mutex_unlock(&THR_LOCK_lock);
+ mysql_mutex_destroy(&lock->mutex);
DBUG_VOID_RETURN;
}
@@ -446,7 +454,6 @@ void thr_lock_info_init(THR_LOCK_INFO *info)
struct st_my_thread_var *tmp= my_thread_var;
info->thread= tmp->pthread_self;
info->thread_id= tmp->id;
- info->n_cursors= 0;
}
/* Initialize a lock instance */
@@ -464,7 +471,7 @@ void thr_lock_data_init(THR_LOCK *lock,THR_LOCK_DATA *data, void *param)
static inline my_bool
-have_old_read_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner)
+has_old_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner)
{
for ( ; data ; data=data->next)
{
@@ -491,13 +498,14 @@ static void wake_up_waiters(THR_LOCK *lock);
static enum enum_thr_lock_result
wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
- my_bool in_wait_list)
+ my_bool in_wait_list, ulong lock_wait_timeout)
{
struct st_my_thread_var *thread_var= my_thread_var;
- pthread_cond_t *cond= &thread_var->suspend;
+ mysql_cond_t *cond= &thread_var->suspend;
struct timespec wait_timeout;
enum enum_thr_lock_result result= THR_LOCK_ABORTED;
- my_bool can_deadlock= test(data->owner->info->n_cursors);
+ const char *old_proc_info;
+ my_bool use_wait_callbacks= FALSE;
DBUG_ENTER("wait_for_lock");
/*
@@ -536,14 +544,29 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
thread_var->current_cond= cond;
data->cond= cond;
- if (can_deadlock)
- set_timespec(wait_timeout, table_lock_wait_timeout);
+ old_proc_info= proc_info_hook(NULL, "Waiting for table level lock",
+ __func__, __FILE__, __LINE__);
+
+ /*
+ Since before_lock_wait potentially can create more threads to
+ scheduler work for, we don't want to call the before_lock_wait
+ callback unless it will really start to wait.
+
+ For similar reasons, we do not want to call before_lock_wait and
+ after_lock_wait for each lap around the loop, so we restrict
+ ourselves to call it before_lock_wait once before starting to wait
+ and once after the thread has exited the wait loop.
+ */
+ if ((!thread_var->abort || in_wait_list) && before_lock_wait)
+ {
+ use_wait_callbacks= TRUE;
+ (*before_lock_wait)();
+ }
+
+ set_timespec(wait_timeout, lock_wait_timeout);
while (!thread_var->abort || in_wait_list)
{
- int rc= (can_deadlock ?
- pthread_cond_timedwait(cond, &data->lock->mutex,
- &wait_timeout) :
- pthread_cond_wait(cond, &data->lock->mutex));
+ int rc= mysql_cond_timedwait(cond, &data->lock->mutex, &wait_timeout);
/*
We must break the wait if one of the following occurs:
- the connection has been aborted (!thread_var->abort), but
@@ -571,6 +594,14 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
/* purecov: end */
}
}
+
+ /*
+ We call the after_lock_wait callback once the wait loop has
+ finished.
+ */
+ if (after_lock_wait && use_wait_callbacks)
+ (*after_lock_wait)();
+
DBUG_PRINT("thr_lock", ("aborted: %d in_wait_list: %d",
thread_var->abort, in_wait_list));
@@ -601,24 +632,26 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
data->type == TL_WRITE_CONCURRENT_INSERT);
check_locks(data->lock,"got wait_for_lock", data->type, 0);
}
- pthread_mutex_unlock(&data->lock->mutex);
+ mysql_mutex_unlock(&data->lock->mutex);
/* The following must be done after unlock of lock->mutex */
- pthread_mutex_lock(&thread_var->mutex);
+ mysql_mutex_lock(&thread_var->mutex);
thread_var->current_mutex= 0;
thread_var->current_cond= 0;
- pthread_mutex_unlock(&thread_var->mutex);
+ mysql_mutex_unlock(&thread_var->mutex);
+
+ proc_info_hook(NULL, old_proc_info, __func__, __FILE__, __LINE__);
+
DBUG_RETURN(result);
}
static enum enum_thr_lock_result
-thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner)
+thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout)
{
THR_LOCK *lock=data->lock;
enum enum_thr_lock_result result= THR_LOCK_SUCCESS;
struct st_lock_list *wait_queue;
- THR_LOCK_DATA *lock_owner;
enum thr_lock_type lock_type= data->type;
DBUG_ENTER("thr_lock");
@@ -626,9 +659,9 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner)
data->cond=0; /* safety */
data->owner= owner; /* Must be reset ! */
data->priority&= ~THR_LOCK_LATE_PRIV;
- VOID(pthread_mutex_lock(&lock->mutex));
+ mysql_mutex_lock(&lock->mutex);
DBUG_PRINT("lock",("data: 0x%lx thread: 0x%lx lock: 0x%lx type: %d",
- (long) data, data->owner->info->thread_id,
+ (long) data, data->owner->thread_id,
(long) lock, (int) lock_type));
check_locks(lock,(uint) lock_type <= (uint) TL_READ_NO_INSERT ?
"enter read_lock" : "enter write_lock", lock_type, 0);
@@ -638,22 +671,38 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner)
if (lock->write.data)
{
/*
- We can allow a read lock even if there is already a write lock
- on the table in one the following cases:
- - This thread alread have a write lock on the table
- - The write lock is TL_WRITE_ALLOW_READ or TL_WRITE_DELAYED
- and the read lock is TL_READ_HIGH_PRIORITY or TL_READ
- - The write lock is TL_WRITE_CONCURRENT_INSERT or TL_WRITE_ALLOW_WRITE
- and the read lock is not TL_READ_NO_INSERT
+ We can allow a read lock even if there is already a
+ write lock on the table if they are owned by the same
+ thread or if they satisfy the following lock
+ compatibility matrix:
+
+ Request
+ /-------
+ H|++++ WRITE_ALLOW_WRITE
+ e|+++- WRITE_CONCURRENT_INSERT
+ l|++++ WRITE_DELAYED
+ d ||||
+ |||\= READ_NO_INSERT
+ ||\ = READ_HIGH_PRIORITY
+ |\ = READ_WITH_SHARED_LOCKS
+ \ = READ
+
+
+ + = Request can be satisified.
+ - = Request cannot be satisified.
+
+ READ_NO_INSERT and WRITE_ALLOW_WRITE should in principle
+ be incompatible. However this will cause starvation of
+ LOCK TABLE READ in InnoDB under high write load.
+ See Bug#42147 for more information.
*/
DBUG_PRINT("lock",("write locked 1 by thread: 0x%lx",
- lock->write.data->owner->info->thread_id));
+ lock->write.data->owner->thread_id));
if (thr_lock_owner_equal(data->owner, lock->write.data->owner) ||
(lock->write.data->type <= TL_WRITE_DELAYED &&
(((int) lock_type <= (int) TL_READ_HIGH_PRIORITY) ||
- (lock->write.data->type != TL_WRITE_CONCURRENT_INSERT &&
- lock->write.data->type != TL_WRITE_ALLOW_READ))))
+ (lock->write.data->type != TL_WRITE_CONCURRENT_INSERT))))
{ /* Already got a write lock */
(*lock->read.last)=data; /* Add to running FIFO */
data->prev=lock->read.last;
@@ -677,7 +726,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner)
else if (!lock->write_wait.data ||
lock->write_wait.data->type <= TL_WRITE_LOW_PRIORITY ||
lock_type == TL_READ_HIGH_PRIORITY ||
- have_old_read_lock(lock->read.data, data->owner))
+ has_old_lock(lock->read.data, data->owner)) /* Has old read lock */
{ /* No important write-locks */
(*lock->read.last)=data; /* Add to running FIFO */
data->prev=lock->read.last;
@@ -707,14 +756,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner)
result= THR_LOCK_ABORTED; /* Can't wait for this one */
goto end;
}
- /*
- if there is a TL_WRITE_ALLOW_READ lock, we have to wait for a lock
- (TL_WRITE_ALLOW_READ is used for ALTER TABLE in MySQL)
- */
- if ((!lock->write.data ||
- lock->write.data->type != TL_WRITE_ALLOW_READ) &&
- !have_specific_lock(lock->write_wait.data,TL_WRITE_ALLOW_READ) &&
- (lock->write.data || lock->read.data))
+ if (lock->write.data || lock->read.data)
{
/* Add delayed write lock to write_wait queue, and return at once */
(*lock->write_wait.last)=data;
@@ -736,6 +778,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner)
{
if (lock->write.data->type == TL_WRITE_ONLY)
{
+ /* purecov: begin tested */
/* Allow lock owner to bypass TL_WRITE_ONLY. */
if (!thr_lock_owner_equal(data->owner, lock->write.data->owner))
{
@@ -744,23 +787,50 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner)
result= THR_LOCK_ABORTED; /* Can't wait for this one */
goto end;
}
+ /* purecov: end */
}
/*
- The following test will not work if the old lock was a
- TL_WRITE_ALLOW_WRITE, TL_WRITE_ALLOW_READ or TL_WRITE_DELAYED in
- the same thread, but this will never happen within MySQL.
-
The idea is to allow us to get a lock at once if we already have
a write lock or if there is no pending write locks and if all
write locks are of the same type and are either
TL_WRITE_ALLOW_WRITE or TL_WRITE_CONCURRENT_INSERT
+
+ Note that, since lock requests for the same table are sorted in
+ such way that requests with higher thr_lock_type value come first
+ (with one exception (*)), lock being requested usually (**) has
+ equal or "weaker" type than one which thread might have already
+ acquired.
+ *) The only exception to this rule is case when type of old lock
+ is TL_WRITE_LOW_PRIORITY and type of new lock is changed inside
+ of thr_lock() from TL_WRITE_CONCURRENT_INSERT to TL_WRITE since
+ engine turns out to be not supporting concurrent inserts.
+ Note that since TL_WRITE has the same compatibility rules as
+ TL_WRITE_LOW_PRIORITY (their only difference is priority),
+ it is OK to grant new lock without additional checks in such
+ situation.
+ **) The exceptions are situations when:
+ - when old lock type is TL_WRITE_DELAYED
+ But these should never happen within MySQL.
+ Therefore it is OK to allow acquiring write lock on the table if
+ this thread already holds some write lock on it.
+
+ (INSERT INTO t1 VALUES (f1()), where f1() is stored function which
+ tries to update t1, is an example of statement which requests two
+ different types of write lock on the same table).
*/
- if (thr_lock_owner_equal(data->owner, lock->write.data->owner) ||
- (!lock->write_wait.data && lock_type == lock->write.data->type &&
- (lock_type == TL_WRITE_ALLOW_WRITE ||
- (lock_type == TL_WRITE_CONCURRENT_INSERT &&
- lock->allow_multiple_concurrent_insert))))
+ DBUG_ASSERT(! has_old_lock(lock->write.data, data->owner) ||
+ ((lock_type <= lock->write.data->type ||
+ (lock_type == TL_WRITE &&
+ lock->write.data->type == TL_WRITE_LOW_PRIORITY)) &&
+ lock->write.data->type != TL_WRITE_DELAYED));
+
+ if (((lock_type == TL_WRITE_ALLOW_WRITE ||
+ (lock_type == TL_WRITE_CONCURRENT_INSERT &&
+ lock->allow_multiple_concurrent_insert)) &&
+ ! lock->write_wait.data &&
+ lock->write.data->type == lock_type) ||
+ has_old_lock(lock->write.data, data->owner))
{
DBUG_PRINT("info", ("write_wait.data: 0x%lx old_type: %d",
(ulong) lock->write_wait.data,
@@ -777,7 +847,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner)
goto end;
}
DBUG_PRINT("lock",("write locked 2 by thread: 0x%lx",
- lock->write.data->owner->info->thread_id));
+ lock->write.data->owner->thread_id));
}
else
{
@@ -813,27 +883,14 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner)
}
}
DBUG_PRINT("lock",("write locked 3 by thread: 0x%lx type: %d",
- lock->read.data->owner->info->thread_id, data->type));
+ lock->read.data->owner->thread_id, data->type));
}
wait_queue= &lock->write_wait;
}
- /*
- Try to detect a trivial deadlock when using cursors: attempt to
- lock a table that is already locked by an open cursor within the
- same connection. lock_owner can be zero if we succumbed to a high
- priority writer in the write_wait queue.
- */
- lock_owner= lock->read.data ? lock->read.data : lock->write.data;
- if (lock_owner && lock_owner->owner->info == owner->info)
- {
- DBUG_PRINT("lock",("deadlock"));
- result= THR_LOCK_DEADLOCK;
- goto end;
- }
/* Can't get lock yet; Wait for it */
- DBUG_RETURN(wait_for_lock(wait_queue, data, 0));
+ DBUG_RETURN(wait_for_lock(wait_queue, data, 0, lock_wait_timeout));
end:
- pthread_mutex_unlock(&lock->mutex);
+ mysql_mutex_unlock(&lock->mutex);
DBUG_RETURN(result);
}
@@ -855,7 +912,7 @@ static inline void free_all_read_locks(THR_LOCK *lock,
do
{
- pthread_cond_t *cond=data->cond;
+ mysql_cond_t *cond= data->cond;
if ((int) data->type == (int) TL_READ_NO_INSERT)
{
if (using_concurrent_insert)
@@ -877,10 +934,10 @@ static inline void free_all_read_locks(THR_LOCK *lock,
}
/* purecov: begin inspected */
DBUG_PRINT("lock",("giving read lock to thread: 0x%lx",
- data->owner->info->thread_id));
+ data->owner->thread_id));
/* purecov: end */
data->cond=0; /* Mark thread free */
- VOID(pthread_cond_signal(cond));
+ mysql_cond_signal(cond);
} while ((data=data->next));
*lock->read_wait.last=0;
if (!lock->read_wait.data)
@@ -896,8 +953,8 @@ void thr_unlock(THR_LOCK_DATA *data, uint unlock_flags)
enum thr_lock_type lock_type=data->type;
DBUG_ENTER("thr_unlock");
DBUG_PRINT("lock",("data: 0x%lx thread: 0x%lx lock: 0x%lx",
- (long) data, data->owner->info->thread_id, (long) lock));
- pthread_mutex_lock(&lock->mutex);
+ (long) data, data->owner->thread_id, (long) lock));
+ mysql_mutex_lock(&lock->mutex);
check_locks(lock,"start of release lock", lock_type, 0);
if (((*data->prev)=data->next)) /* remove from lock-list */
@@ -933,7 +990,7 @@ void thr_unlock(THR_LOCK_DATA *data, uint unlock_flags)
lock->read_no_write_count--;
data->type=TL_UNLOCK; /* Mark unlocked */
wake_up_waiters(lock);
- pthread_mutex_unlock(&lock->mutex);
+ mysql_mutex_unlock(&lock->mutex);
DBUG_VOID_RETURN;
}
@@ -989,12 +1046,12 @@ static void wake_up_waiters(THR_LOCK *lock)
data->type=TL_WRITE; /* Upgrade lock */
/* purecov: begin inspected */
DBUG_PRINT("lock",("giving write lock of type %d to thread: 0x%lx",
- data->type, data->owner->info->thread_id));
+ data->type, data->owner->thread_id));
/* purecov: end */
{
- pthread_cond_t *cond=data->cond;
+ mysql_cond_t *cond= data->cond;
data->cond=0; /* Mark thread free */
- VOID(pthread_cond_signal(cond)); /* Start waiting thread */
+ mysql_cond_signal(cond); /* Start waiting thread */
}
if (data->type != TL_WRITE_ALLOW_WRITE ||
!lock->write_wait.data ||
@@ -1035,7 +1092,7 @@ static void wake_up_waiters(THR_LOCK *lock)
goto end;
}
do {
- pthread_cond_t *cond=data->cond;
+ mysql_cond_t *cond= data->cond;
if (((*data->prev)=data->next)) /* remove from wait-list */
data->next->prev= data->prev;
else
@@ -1045,7 +1102,7 @@ static void wake_up_waiters(THR_LOCK *lock)
lock->write.last= &data->next;
data->next=0; /* Only one write lock */
data->cond=0; /* Mark thread free */
- VOID(pthread_cond_signal(cond)); /* Start waiting thread */
+ mysql_cond_signal(cond); /* Start waiting thread */
} while (lock_type == TL_WRITE_ALLOW_WRITE &&
(data=lock->write_wait.data) &&
data->type == TL_WRITE_ALLOW_WRITE);
@@ -1092,7 +1149,8 @@ static void sort_locks(THR_LOCK_DATA **data,uint count)
enum enum_thr_lock_result
-thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_OWNER *owner)
+thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_INFO *owner,
+ ulong lock_wait_timeout)
{
THR_LOCK_DATA **pos, **end, **first_lock;
DBUG_ENTER("thr_multi_lock");
@@ -1106,7 +1164,7 @@ thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_OWNER *owner)
/* lock everything */
for (pos=data,end=data+count; pos < end ; pos++)
{
- enum enum_thr_lock_result result= thr_lock(*pos, owner);
+ enum enum_thr_lock_result result= thr_lock(*pos, owner, lock_wait_timeout);
if (result != THR_LOCK_SUCCESS)
{ /* Aborted */
thr_multi_unlock(data,(uint) (pos-data), 0);
@@ -1115,6 +1173,7 @@ thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_OWNER *owner)
(*pos)->type= TL_UNLOCK;
DBUG_RETURN(result);
}
+ DEBUG_SYNC_C("thr_multi_lock_after_thr_lock");
#ifdef MAIN
printf("Thread: %s Got lock: 0x%lx type: %d\n",my_thread_name(),
(long) pos[0]->lock, pos[0]->type); fflush(stdout);
@@ -1230,7 +1289,7 @@ void thr_multi_unlock(THR_LOCK_DATA **data,uint count, uint unlock_flags)
else
{
DBUG_PRINT("lock",("Free lock: data: 0x%lx thread: 0x%lx lock: 0x%lx",
- (long) *pos, (*pos)->owner->info->thread_id,
+ (long) *pos, (*pos)->owner->thread_id,
(long) (*pos)->lock));
}
}
@@ -1246,19 +1305,19 @@ void thr_abort_locks(THR_LOCK *lock, my_bool upgrade_lock)
{
THR_LOCK_DATA *data;
DBUG_ENTER("thr_abort_locks");
- pthread_mutex_lock(&lock->mutex);
+ mysql_mutex_lock(&lock->mutex);
for (data=lock->read_wait.data; data ; data=data->next)
{
data->type=TL_UNLOCK; /* Mark killed */
/* It's safe to signal the cond first: we're still holding the mutex. */
- pthread_cond_signal(data->cond);
+ mysql_cond_signal(data->cond);
data->cond=0; /* Removed from list */
}
for (data=lock->write_wait.data; data ; data=data->next)
{
data->type=TL_UNLOCK;
- pthread_cond_signal(data->cond);
+ mysql_cond_signal(data->cond);
data->cond=0;
}
lock->read_wait.last= &lock->read_wait.data;
@@ -1266,7 +1325,7 @@ void thr_abort_locks(THR_LOCK *lock, my_bool upgrade_lock)
lock->read_wait.data=lock->write_wait.data=0;
if (upgrade_lock && lock->write.data)
lock->write.data->type=TL_WRITE_ONLY;
- pthread_mutex_unlock(&lock->mutex);
+ mysql_mutex_unlock(&lock->mutex);
DBUG_VOID_RETURN;
}
@@ -1283,16 +1342,16 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id)
my_bool found= FALSE;
DBUG_ENTER("thr_abort_locks_for_thread");
- pthread_mutex_lock(&lock->mutex);
+ mysql_mutex_lock(&lock->mutex);
for (data= lock->read_wait.data; data ; data= data->next)
{
- if (data->owner->info->thread_id == thread_id) /* purecov: tested */
+ if (data->owner->thread_id == thread_id) /* purecov: tested */
{
DBUG_PRINT("info",("Aborting read-wait lock"));
data->type= TL_UNLOCK; /* Mark killed */
/* It's safe to signal the cond first: we're still holding the mutex. */
found= TRUE;
- pthread_cond_signal(data->cond);
+ mysql_cond_signal(data->cond);
data->cond= 0; /* Removed from list */
if (((*data->prev)= data->next))
@@ -1303,12 +1362,12 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id)
}
for (data= lock->write_wait.data; data ; data= data->next)
{
- if (data->owner->info->thread_id == thread_id) /* purecov: tested */
+ if (data->owner->thread_id == thread_id) /* purecov: tested */
{
DBUG_PRINT("info",("Aborting write-wait lock"));
data->type= TL_UNLOCK;
found= TRUE;
- pthread_cond_signal(data->cond);
+ mysql_cond_signal(data->cond);
data->cond= 0;
if (((*data->prev)= data->next))
@@ -1318,7 +1377,7 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id)
}
}
wake_up_waiters(lock);
- pthread_mutex_unlock(&lock->mutex);
+ mysql_mutex_unlock(&lock->mutex);
DBUG_RETURN(found);
}
@@ -1336,10 +1395,7 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id)
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 and TL_WRITE_ALLOW_READ. The normal downgrade variants are
- TL_WRITE_ONLY => TL_WRITE_ALLOW_READ After a short exclusive lock
- TL_WRITE_ALLOW_READ => TL_WRITE_ALLOW_WRITE After discovering that the
- operation didn't need such a high lock.
+ 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
@@ -1360,198 +1416,32 @@ void thr_downgrade_write_lock(THR_LOCK_DATA *in_data,
#ifndef DBUG_OFF
enum thr_lock_type old_lock_type= in_data->type;
#endif
-#ifdef TO_BE_REMOVED
- THR_LOCK_DATA *data, *next;
- bool start_writers= FALSE;
- bool start_readers= FALSE;
-#endif
DBUG_ENTER("thr_downgrade_write_only_lock");
- pthread_mutex_lock(&lock->mutex);
+ 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);
-#if TO_BE_REMOVED
- switch (old_lock_type)
- {
- case TL_WRITE_ONLY:
- case TL_WRITE:
- case TL_WRITE_LOW_PRIORITY:
- /*
- Previous lock was exclusive we are now ready to start up most waiting
- threads.
- */
- switch (new_lock_type)
- {
- case TL_WRITE_ALLOW_READ:
- /* Still cannot start WRITE operations. Can only start readers. */
- start_readers= TRUE;
- break;
- case TL_WRITE:
- case TL_WRITE_LOW_PRIORITY:
- /*
- Still cannot start anything, but new requests are no longer
- aborted.
- */
- break;
- case TL_WRITE_ALLOW_WRITE:
- /*
- We can start both writers and readers.
- */
- start_writers= TRUE;
- start_readers= TRUE;
- break;
- case TL_WRITE_CONCURRENT_INSERT:
- case TL_WRITE_DELAYED:
- /*
- This routine is not designed for those. Lock will be downgraded
- but no start of waiters will occur. This is not the optimal but
- should be a correct behaviour.
- */
- break;
- default:
- DBUG_ASSERT(0);
- }
- break;
- case TL_WRITE_DELAYED:
- case TL_WRITE_CONCURRENT_INSERT:
- /*
- This routine is not designed for those. Lock will be downgraded
- but no start of waiters will occur. This is not the optimal but
- should be a correct behaviour.
- */
- break;
- case TL_WRITE_ALLOW_READ:
- DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE);
- /*
- Previously writers were not allowed to start, now it is ok to
- start them again. Readers are already allowed so no reason to
- handle them.
- */
- start_writers= TRUE;
- break;
- default:
- DBUG_ASSERT(0);
- break;
- }
- if (start_writers)
- {
- /*
- At this time the only active writer can be ourselves. Thus we need
- not worry about that there are other concurrent write operations
- active on the table. Thus we only need to worry about starting
- waiting operations.
- We also only come here with TL_WRITE_ALLOW_WRITE as the new
- lock type, thus we can start other writers also of the same type.
- If we find a lock at exclusive level >= TL_WRITE_LOW_PRIORITY we
- don't start any more operations that would be mean those operations
- will have to wait for things started afterwards.
- */
- DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE);
- for (data=lock->write_wait.data; data ; data= next)
- {
- /*
- All WRITE requests compatible with new lock type are also
- started
- */
- next= data->next;
- if (start_writers && data->type == new_lock_type)
- {
- pthread_cond_t *cond= data->cond;
- /*
- It is ok to start this waiter.
- Move from being first in wait queue to be last in write queue.
- */
- if (((*data->prev)= data->next))
- data->next->prev= data->prev;
- else
- lock->write_wait.last= data->prev;
- data->prev= lock->write.last;
- lock->write.last= &data->next;
- data->next= 0;
- check_locks(lock, "Started write lock after downgrade", new_lock_type,
- 0);
- data->cond= 0;
- pthread_cond_signal(cond);
- }
- else
- {
- /*
- We found an incompatible lock, we won't start any more write
- requests to avoid letting writers pass other writers in the
- queue.
- */
- start_writers= FALSE;
- if (data->type >= TL_WRITE_LOW_PRIORITY)
- {
- /*
- We have an exclusive writer in the queue so we won't start
- readers either.
- */
- start_readers= FALSE;
- }
- }
- }
- }
- if (start_readers)
- {
- DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE ||
- new_lock_type == TL_WRITE_ALLOW_READ);
- /*
- When we come here we know that the write locks are
- TL_WRITE_ALLOW_WRITE or TL_WRITE_ALLOW_READ. This means that reads
- are ok
- */
- for (data=lock->read_wait.data; data ; data=next)
- {
- next= data->next;
- /*
- All reads are ok to start now except TL_READ_NO_INSERT when
- write lock is TL_WRITE_ALLOW_READ.
- */
- if (new_lock_type != TL_WRITE_ALLOW_READ ||
- data->type != TL_READ_NO_INSERT)
- {
- pthread_cond_t *cond= data->cond;
- if (((*data->prev)= data->next))
- data->next->prev= data->prev;
- else
- lock->read_wait.last= data->prev;
- data->prev= lock->read.last;
- lock->read.last= &data->next;
- data->next= 0;
-
- if (data->type == TL_READ_NO_INSERT)
- lock->read_no_write_count++;
- check_locks(lock, "Started read lock after downgrade", new_lock_type,
- 0);
- data->cond= 0;
- pthread_cond_signal(cond);
- }
- }
- }
- check_locks(lock,"after starting waiters after downgrading lock",
- new_lock_type, 0);
-#endif
- pthread_mutex_unlock(&lock->mutex);
+ 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,
- enum thr_lock_type new_lock_type)
+ enum thr_lock_type new_lock_type,
+ ulong lock_wait_timeout)
{
THR_LOCK *lock=data->lock;
enum enum_thr_lock_result res;
DBUG_ENTER("thr_upgrade_write_delay_lock");
- pthread_mutex_lock(&lock->mutex);
+ mysql_mutex_lock(&lock->mutex);
if (data->type == TL_UNLOCK || data->type >= TL_WRITE_LOW_PRIORITY)
{
- pthread_mutex_unlock(&lock->mutex);
+ mysql_mutex_unlock(&lock->mutex);
DBUG_RETURN(data->type == TL_UNLOCK); /* Test if Aborted */
}
check_locks(lock,"before upgrading lock", data->type, 0);
@@ -1563,9 +1453,9 @@ my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data,
{
if (!lock->read.data) /* No read locks */
{ /* We have the lock */
- if (lock->get_status)
- (*lock->get_status)(data->status_param, 0);
- pthread_mutex_unlock(&lock->mutex);
+ if (data->lock->get_status)
+ (*data->lock->get_status)(data->status_param, 0);
+ mysql_mutex_unlock(&lock->mutex);
if (lock->start_trans)
(*lock->start_trans)(data->status_param);
DBUG_RETURN(0);
@@ -1588,7 +1478,7 @@ my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data,
{
check_locks(lock,"waiting for lock", new_lock_type, 0);
}
- res= wait_for_lock(&lock->write_wait,data,1);
+ res= wait_for_lock(&lock->write_wait, data, 1, lock_wait_timeout);
if (res == THR_LOCK_SUCCESS && lock->start_trans)
DBUG_RETURN((*lock->start_trans)(data->status_param));
DBUG_RETURN(0);
@@ -1597,16 +1487,17 @@ my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data,
/* downgrade a WRITE lock to a WRITE_DELAY lock if there is pending locks */
-my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data)
+my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data,
+ ulong lock_wait_timeout)
{
THR_LOCK *lock=data->lock;
enum thr_lock_type write_lock_type;
DBUG_ENTER("thr_reschedule_write_lock");
- pthread_mutex_lock(&lock->mutex);
+ mysql_mutex_lock(&lock->mutex);
if (!lock->read_wait.data) /* No waiting read locks */
{
- pthread_mutex_unlock(&lock->mutex);
+ mysql_mutex_unlock(&lock->mutex);
DBUG_RETURN(0);
}
@@ -1628,8 +1519,9 @@ my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data)
lock->write_wait.data=data;
free_all_read_locks(lock,0);
- pthread_mutex_unlock(&lock->mutex);
- DBUG_RETURN(thr_upgrade_write_delay_lock(data, write_lock_type));
+ mysql_mutex_unlock(&lock->mutex);
+ DBUG_RETURN(thr_upgrade_write_delay_lock(data, write_lock_type,
+ lock_wait_timeout));
}
@@ -1646,7 +1538,7 @@ static void thr_print_lock(const char* name,struct st_lock_list *list)
prev= &list->data;
for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next)
{
- printf("0x%lx (%lu:%d); ", (ulong) data, data->owner->info->thread_id,
+ printf("0x%lx (%lu:%d); ", (ulong) data, data->owner->thread_id,
(int) data->type);
if (data->prev != prev)
printf("\nWarning: prev didn't point at previous lock\n");
@@ -1663,13 +1555,13 @@ void thr_print_locks(void)
LIST *list;
uint count=0;
- pthread_mutex_lock(&THR_LOCK_lock);
+ mysql_mutex_lock(&THR_LOCK_lock);
puts("Current locks:");
for (list= thr_lock_thread_list; list && count++ < MAX_THREADS;
list= list_rest(list))
{
THR_LOCK *lock=(THR_LOCK*) list->data;
- VOID(pthread_mutex_lock(&lock->mutex));
+ mysql_mutex_lock(&lock->mutex);
printf("lock: 0x%lx:",(ulong) lock);
if ((lock->write_wait.data || lock->read_wait.data) &&
(! lock->read.data && ! lock->write.data))
@@ -1687,14 +1579,13 @@ void thr_print_locks(void)
thr_print_lock("write_wait",&lock->write_wait);
thr_print_lock("read",&lock->read);
thr_print_lock("read_wait",&lock->read_wait);
- VOID(pthread_mutex_unlock(&lock->mutex));
+ mysql_mutex_unlock(&lock->mutex);
puts("");
}
fflush(stdout);
- pthread_mutex_unlock(&THR_LOCK_lock);
+ mysql_mutex_unlock(&THR_LOCK_lock);
}
-#endif /* THREAD */
/*****************************************************************************
** Test of thread locks
@@ -1702,8 +1593,6 @@ void thr_print_locks(void)
#ifdef MAIN
-#ifdef THREAD
-
struct st_test {
uint lock_nr;
enum thr_lock_type lock_type;
@@ -1723,26 +1612,14 @@ struct st_test test_8[] = {{1,TL_READ_NO_INSERT},{2,TL_READ_NO_INSERT},{3,TL_REA
struct st_test test_9[] = {{4,TL_READ_HIGH_PRIORITY}};
struct st_test test_10[] ={{4,TL_WRITE}};
struct st_test test_11[] = {{0,TL_WRITE_LOW_PRIORITY},{1,TL_WRITE_LOW_PRIORITY},{2,TL_WRITE_LOW_PRIORITY},{3,TL_WRITE_LOW_PRIORITY}}; /* Many writes */
-struct st_test test_12[] = {{0,TL_WRITE_ALLOW_READ},{1,TL_WRITE_ALLOW_READ},{2,TL_WRITE_ALLOW_READ},{3,TL_WRITE_ALLOW_READ}}; /* Many writes */
-struct st_test test_13[] = {{0,TL_WRITE_CONCURRENT_INSERT},{1,TL_WRITE_CONCURRENT_INSERT},{2,TL_WRITE_CONCURRENT_INSERT},{3,TL_WRITE_CONCURRENT_INSERT}};
-struct st_test test_14[] = {{0,TL_WRITE_CONCURRENT_INSERT},{1,TL_READ}};
-struct st_test test_15[] = {{0,TL_WRITE_ALLOW_WRITE},{1,TL_READ}};
-struct st_test test_16[] = {{0,TL_WRITE_ALLOW_WRITE},{1,TL_WRITE_ALLOW_WRITE}};
-
-struct st_test test_17[] = {{5,TL_WRITE_CONCURRENT_INSERT}};
-struct st_test test_18[] = {{5,TL_WRITE_CONCURRENT_INSERT}};
-struct st_test test_19[] = {{5,TL_READ}};
-struct st_test test_20[] = {{5,TL_READ_NO_INSERT}};
-struct st_test test_21[] = {{5,TL_WRITE}};
-
-
-struct st_test *tests[]=
-{
- test_0, test_1, test_2, test_3, test_4, test_5, test_6, test_7, test_8,
- test_9, test_10, test_11, test_12, test_13, test_14, test_15, test_16,
- test_17, test_18, test_19, test_20, test_21
-};
-
+struct st_test test_12[] = {{0,TL_WRITE_CONCURRENT_INSERT},{1,TL_WRITE_CONCURRENT_INSERT},{2,TL_WRITE_CONCURRENT_INSERT},{3,TL_WRITE_CONCURRENT_INSERT}};
+struct st_test test_13[] = {{0,TL_WRITE_CONCURRENT_INSERT},{1,TL_READ}};
+struct st_test test_14[] = {{0,TL_WRITE_ALLOW_WRITE},{1,TL_READ}};
+struct st_test test_15[] = {{0,TL_WRITE_ALLOW_WRITE},{1,TL_WRITE_ALLOW_WRITE}};
+
+struct st_test *tests[] = {test_0,test_1,test_2,test_3,test_4,test_5,test_6,
+ test_7,test_8,test_9,test_10,test_11,test_12,
+ test_13,test_14,test_15};
int lock_counts[]= {sizeof(test_0)/sizeof(struct st_test),
sizeof(test_1)/sizeof(struct st_test),
sizeof(test_2)/sizeof(struct st_test),
@@ -1758,27 +1635,22 @@ int lock_counts[]= {sizeof(test_0)/sizeof(struct st_test),
sizeof(test_12)/sizeof(struct st_test),
sizeof(test_13)/sizeof(struct st_test),
sizeof(test_14)/sizeof(struct st_test),
- sizeof(test_15)/sizeof(struct st_test),
- sizeof(test_16)/sizeof(struct st_test),
- sizeof(test_17)/sizeof(struct st_test),
- sizeof(test_18)/sizeof(struct st_test),
- sizeof(test_19)/sizeof(struct st_test),
- sizeof(test_20)/sizeof(struct st_test),
- sizeof(test_21)/sizeof(struct st_test)
+ sizeof(test_15)/sizeof(struct st_test)
};
-static pthread_cond_t COND_thread_count;
-static pthread_mutex_t LOCK_thread_count;
+static mysql_cond_t COND_thread_count;
+static mysql_mutex_t LOCK_thread_count;
static uint thread_count;
static ulong sum=0;
#define MAX_LOCK_COUNT 8
+#define TEST_TIMEOUT 100000
/* The following functions is for WRITE_CONCURRENT_INSERT */
static void test_get_status(void* param __attribute__((unused)),
- int concurrent_insert __attribute__((unused)))
+ my_bool concurrent_insert __attribute__((unused)))
{
}
@@ -1801,7 +1673,6 @@ static void *test_thread(void *arg)
{
int i,j,param=*((int*) arg);
THR_LOCK_DATA data[MAX_LOCK_COUNT];
- THR_LOCK_OWNER owner;
THR_LOCK_INFO lock_info;
THR_LOCK_DATA *multi_locks[MAX_LOCK_COUNT];
my_thread_init();
@@ -1809,7 +1680,6 @@ static void *test_thread(void *arg)
printf("Thread %s (%d) started\n",my_thread_name(),param); fflush(stdout);
thr_lock_info_init(&lock_info);
- thr_lock_owner_init(&owner, &lock_info);
for (i=0; i < lock_counts[param] ; i++)
thr_lock_data_init(locks+tests[param][i].lock_nr,data+i,NULL);
for (j=1 ; j < 10 ; j++) /* try locking 10 times */
@@ -1819,8 +1689,8 @@ static void *test_thread(void *arg)
multi_locks[i]= &data[i];
data[i].type= tests[param][i].lock_type;
}
- thr_multi_lock(multi_locks, lock_counts[param], &owner);
- pthread_mutex_lock(&LOCK_thread_count);
+ thr_multi_lock(multi_locks, lock_counts[param], &lock_info, TEST_TIMEOUT);
+ mysql_mutex_lock(&LOCK_thread_count);
{
int tmp=rand() & 7; /* Do something from 0-2 sec */
if (tmp == 0)
@@ -1834,16 +1704,16 @@ static void *test_thread(void *arg)
sum+=k;
}
}
- pthread_mutex_unlock(&LOCK_thread_count);
+ mysql_mutex_unlock(&LOCK_thread_count);
thr_multi_unlock(multi_locks,lock_counts[param], THR_UNLOCK_UPDATE_STATUS);
}
printf("Thread %s (%d) ended\n",my_thread_name(),param); fflush(stdout);
thr_print_locks();
- pthread_mutex_lock(&LOCK_thread_count);
+ mysql_mutex_lock(&LOCK_thread_count);
thread_count--;
- VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
- pthread_mutex_unlock(&LOCK_thread_count);
+ mysql_cond_signal(&COND_thread_count); /* Tell main we are ready */
+ mysql_mutex_unlock(&LOCK_thread_count);
free((uchar*) arg);
return 0;
}
@@ -1861,15 +1731,15 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
printf("Main thread: %s\n",my_thread_name());
- if ((error=pthread_cond_init(&COND_thread_count,NULL)))
+ if ((error= mysql_cond_init(0, &COND_thread_count, NULL)))
{
- fprintf(stderr,"Got error: %d from pthread_cond_init (errno: %d)",
+ fprintf(stderr, "Got error: %d from mysql_cond_init (errno: %d)",
error,errno);
exit(1);
}
- if ((error=pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST)))
+ if ((error= mysql_mutex_init(0, &LOCK_thread_count, MY_MUTEX_INIT_FAST)))
{
- fprintf(stderr,"Got error: %d from pthread_cond_init (errno: %d)",
+ fprintf(stderr, "Got error: %d from mysql_cond_init (errno: %d)",
error,errno);
exit(1);
}
@@ -1905,40 +1775,42 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
}
#endif
#ifdef HAVE_THR_SETCONCURRENCY
- VOID(thr_setconcurrency(2));
+ (void) thr_setconcurrency(2);
#endif
for (i=0 ; i < array_elements(lock_counts) ; i++)
{
param=(int*) malloc(sizeof(int));
*param=i;
- if ((error=pthread_mutex_lock(&LOCK_thread_count)))
+ if ((error= mysql_mutex_lock(&LOCK_thread_count)))
{
- fprintf(stderr,"Got error: %d from pthread_mutex_lock (errno: %d)",
- error,errno);
+ fprintf(stderr, "Got error: %d from mysql_mutex_lock (errno: %d)",
+ error, errno);
exit(1);
}
- if ((error=pthread_create(&tid,&thr_attr,test_thread,(void*) param)))
+ if ((error= mysql_thread_create(0,
+ &tid, &thr_attr, test_thread,
+ (void*) param)))
{
- fprintf(stderr,"Got error: %d from pthread_create (errno: %d)\n",
- error,errno);
- pthread_mutex_unlock(&LOCK_thread_count);
+ fprintf(stderr, "Got error: %d from mysql_thread_create (errno: %d)\n",
+ error, errno);
+ mysql_mutex_unlock(&LOCK_thread_count);
exit(1);
}
thread_count++;
- pthread_mutex_unlock(&LOCK_thread_count);
+ mysql_mutex_unlock(&LOCK_thread_count);
}
pthread_attr_destroy(&thr_attr);
- if ((error=pthread_mutex_lock(&LOCK_thread_count)))
- fprintf(stderr,"Got error: %d from pthread_mutex_lock\n",error);
+ if ((error= mysql_mutex_lock(&LOCK_thread_count)))
+ fprintf(stderr, "Got error: %d from mysql_mutex_lock\n", error);
while (thread_count)
{
- if ((error=pthread_cond_wait(&COND_thread_count,&LOCK_thread_count)))
- fprintf(stderr,"Got error: %d from pthread_cond_wait\n",error);
+ if ((error= mysql_cond_wait(&COND_thread_count, &LOCK_thread_count)))
+ fprintf(stderr, "Got error: %d from mysql_cond_wait\n", error);
}
- if ((error=pthread_mutex_unlock(&LOCK_thread_count)))
- fprintf(stderr,"Got error: %d from pthread_mutex_unlock\n",error);
+ if ((error= mysql_mutex_unlock(&LOCK_thread_count)))
+ fprintf(stderr, "Got error: %d from mysql_mutex_unlock\n", error);
for (i=0 ; i < array_elements(locks) ; i++)
thr_lock_delete(locks+i);
#ifdef EXTRA_DEBUG
@@ -1950,13 +1822,4 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
return 0;
}
-#else /* THREAD */
-
-int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
-{
- printf("thr_lock disabled because we are not using threads\n");
- exit(1);
-}
-
-#endif /* THREAD */
#endif /* MAIN */
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index d881a68eb4e..17cda782b30 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2011, Monty Program 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
@@ -12,8 +13,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* This makes a wrapper for mutex handling to make it easier to debug mutex */
@@ -21,12 +21,12 @@
#if defined(TARGET_OS_LINUX) && !defined (__USE_UNIX98)
#define __USE_UNIX98 /* To get rw locks under Linux */
#endif
+
#ifdef SAFE_MUTEX
#define SAFE_MUTEX_DEFINED
+#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */
#endif
-#if defined(THREAD)
-#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */
#include "mysys_priv.h"
#include "my_static.h"
#include <m_string.h>
@@ -43,9 +43,6 @@
#undef pthread_cond_wait
#undef pthread_cond_timedwait
#undef safe_mutex_free_deadlock_data
-#ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT
-#define pthread_mutex_init(a,b) my_pthread_noposix_mutex_init((a),(b))
-#endif
#endif /* DO_NOT_REMOVE_THREAD_WRAPPERS */
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
@@ -54,6 +51,7 @@ pthread_mutexattr_t my_fast_mutexattr;
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
pthread_mutexattr_t my_errorcheck_mutexattr;
#endif
+
#ifdef SAFE_MUTEX_DEFINED
static pthread_mutex_t THR_LOCK_mutex;
static ulong safe_mutex_count= 0; /* Number of mutexes created */
@@ -172,12 +170,12 @@ static int safe_mutex_lazy_init_deadlock_detection(safe_mutex_t *mp)
pthread_mutex_lock(&THR_LOCK_mutex);
mp->id= ++safe_mutex_id;
pthread_mutex_unlock(&THR_LOCK_mutex);
- hash_init2(mp->locked_mutex, 64, &my_charset_bin,
+ my_hash_init2(mp->locked_mutex, 64, &my_charset_bin,
128,
offsetof(safe_mutex_deadlock_t, id),
sizeof(mp->id),
0, 0, HASH_UNIQUE);
- hash_init2(mp->used_mutex, 64, &my_charset_bin,
+ my_hash_init2(mp->used_mutex, 64, &my_charset_bin,
128,
offsetof(safe_mutex_t, id),
sizeof(mp->id),
@@ -187,10 +185,7 @@ static int safe_mutex_lazy_init_deadlock_detection(safe_mutex_t *mp)
int safe_mutex_init(safe_mutex_t *mp,
const pthread_mutexattr_t *attr __attribute__((unused)),
- const char *name,
- myf my_flags,
- const char *file,
- uint line)
+ const char *name, const char *file, uint line)
{
DBUG_ENTER("safe_mutex_init");
DBUG_PRINT("enter",("mutex: 0x%lx name: %s", (ulong) mp, name));
@@ -203,11 +198,9 @@ int safe_mutex_init(safe_mutex_t *mp,
/* Skip the very common '&' prefix from the autogenerated name */
mp->name= name[0] == '&' ? name + 1 : name;
- if (!safe_mutex_deadlock_detector)
- my_flags|= MYF_NO_DEADLOCK_DETECTION;
/* Deadlock detection is initialised only lazily, on first use. */
- mp->create_flags= my_flags;
+ mp->create_flags= safe_mutex_deadlock_detector ? 0 : MYF_NO_DEADLOCK_DETECTION;
#ifdef SAFE_MUTEX_DETECT_DESTROY
/*
@@ -231,7 +224,9 @@ int safe_mutex_init(safe_mutex_t *mp,
pthread_mutex_unlock(&THR_LOCK_mutex);
}
#else
- thread_safe_increment(safe_mutex_count, &THR_LOCK_mutex);
+ pthread_mutex_lock(&THR_LOCK_mutex);
+ safe_mutex_count++;
+ pthread_mutex_unlock(&THR_LOCK_mutex);
#endif /* SAFE_MUTEX_DETECT_DESTROY */
DBUG_RETURN(0);
}
@@ -341,7 +336,7 @@ int safe_mutex_lock(safe_mutex_t *mp, myf my_flags, const char *file,
*/
pthread_mutex_lock(&THR_LOCK_mutex);
- if (!hash_search(mutex_root->locked_mutex, (uchar*) &mp->id, 0))
+ if (!my_hash_search(mutex_root->locked_mutex, (uchar*) &mp->id, 0))
{
safe_mutex_deadlock_t *deadlock;
safe_mutex_t *mutex;
@@ -361,7 +356,7 @@ int safe_mutex_lock(safe_mutex_t *mp, myf my_flags, const char *file,
mutex= mutex_root;
do
{
- if (hash_search(mp->locked_mutex, (uchar*) &mutex->id, 0))
+ if (my_hash_search(mp->locked_mutex, (uchar*) &mutex->id, 0))
{
print_deadlock_warning(mp, mutex);
/* Mark wrong usage to avoid future warnings for same error */
@@ -529,8 +524,8 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file,
int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
- const struct timespec *abstime,
- const char *file, uint line)
+ const struct timespec *abstime,
+ const char *file, uint line)
{
int error;
safe_mutex_t save_state;
@@ -639,7 +634,9 @@ int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line)
mp->info= NULL; /* Get crash if double free */
}
#else
- thread_safe_sub(safe_mutex_count, 1, &THR_LOCK_mutex);
+ pthread_mutex_lock(&THR_LOCK_mutex);
+ safe_mutex_count--;
+ pthread_mutex_unlock(&THR_LOCK_mutex);
#endif /* SAFE_MUTEX_DETECT_DESTROY */
DBUG_RETURN(error);
}
@@ -666,9 +663,9 @@ void safe_mutex_free_deadlock_data(safe_mutex_t *mp)
mp);
pthread_mutex_unlock(&THR_LOCK_mutex);
- hash_free(mp->used_mutex);
- hash_free(mp->locked_mutex);
- my_free(mp->locked_mutex, 0);
+ my_hash_free(mp->used_mutex);
+ my_hash_free(mp->locked_mutex);
+ my_free(mp->locked_mutex);
mp->create_flags|= MYF_NO_DEADLOCK_DETECTION;
}
}
@@ -713,7 +710,6 @@ void safe_mutex_end(FILE *file __attribute__((unused)))
#endif /* SAFE_MUTEX_DETECT_DESTROY */
}
-
static my_bool add_used_to_locked_mutex(safe_mutex_t *used_mutex,
safe_mutex_deadlock_t *locked_mutex)
{
@@ -776,17 +772,17 @@ static my_bool remove_from_locked_mutex(safe_mutex_t *mp,
(ulong) delete_mutex, (ulong) mp,
delete_mutex->id, mp->id));
- found= (safe_mutex_deadlock_t *) hash_search(mp->locked_mutex,
+ found= (safe_mutex_deadlock_t *) my_hash_search(mp->locked_mutex,
(uchar*) &delete_mutex->id, 0);
DBUG_ASSERT(found);
if (found)
{
- if (hash_delete(mp->locked_mutex, (uchar*) found))
+ if (my_hash_delete(mp->locked_mutex, (uchar*) found))
{
DBUG_ASSERT(0);
}
if (!--found->count)
- my_free(found, MYF(0));
+ my_free(found);
}
DBUG_RETURN(0);
}
@@ -798,12 +794,12 @@ static my_bool remove_from_used_mutex(safe_mutex_deadlock_t *locked_mutex,
DBUG_PRINT("enter", ("delete_mutex: 0x%lx mutex: 0x%lx (id: %lu <- %lu)",
(ulong) mutex, (ulong) locked_mutex,
mutex->id, locked_mutex->id));
- if (hash_delete(locked_mutex->mutex->used_mutex, (uchar*) mutex))
+ if (my_hash_delete(locked_mutex->mutex->used_mutex, (uchar*) mutex))
{
DBUG_ASSERT(0);
}
if (!--locked_mutex->count)
- my_free(locked_mutex, MYF(0));
+ my_free(locked_mutex);
DBUG_RETURN(0);
}
@@ -927,4 +923,3 @@ void fastmutex_global_init(void)
}
#endif /* defined(MY_PTHREAD_FASTMUTEX) */
-#endif /* THREAD */
diff --git a/mysys/thr_rwlock.c b/mysys/thr_rwlock.c
index 2978d91090d..dd6c625a286 100644
--- a/mysys/thr_rwlock.c
+++ b/mysys/thr_rwlock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* 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
@@ -11,12 +11,12 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* Synchronization - readers / writer thread locks */
#include "mysys_priv.h"
-#if defined(THREAD) && !defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && !defined(HAVE_RWLOCK_INIT)
+#if defined(NEED_MY_RW_LOCK)
#include <errno.h>
#ifdef _WIN32
@@ -24,7 +24,7 @@
static BOOL have_srwlock= FALSE;
/* Prototypes and function pointers for windows functions */
typedef VOID (WINAPI* srw_func) (PSRWLOCK SRWLock);
-typedef BOOL (WINAPI* srw_bool_func) (PSRWLOCK SRWLock);
+typedef BOOLEAN (WINAPI* srw_bool_func) (PSRWLOCK SRWLock);
static srw_func my_InitializeSRWLock;
static srw_func my_AcquireSRWLockExclusive;
@@ -171,7 +171,7 @@ static int srw_unlock(my_rw_lock_t *rwp)
* Mountain View, California 94043
*/
-int my_rwlock_init(rw_lock_t *rwp, void *arg __attribute__((unused)))
+int my_rw_init(my_rw_lock_t *rwp)
{
pthread_condattr_t cond_attr;
@@ -199,17 +199,21 @@ int my_rwlock_init(rw_lock_t *rwp, void *arg __attribute__((unused)))
rwp->state = 0;
rwp->waiters = 0;
+#ifdef SAFE_MUTEX
+ rwp->write_thread = 0;
+#endif
return(0);
}
-int my_rwlock_destroy(rw_lock_t *rwp)
+int my_rw_destroy(my_rw_lock_t *rwp)
{
#ifdef _WIN32
if (have_srwlock)
return 0; /* no destroy function */
#endif
+ DBUG_ASSERT(rwp->state == 0);
pthread_mutex_destroy( &rwp->lock );
pthread_cond_destroy( &rwp->readers );
pthread_cond_destroy( &rwp->writers );
@@ -217,7 +221,7 @@ int my_rwlock_destroy(rw_lock_t *rwp)
}
-int my_rw_rdlock(rw_lock_t *rwp)
+int my_rw_rdlock(my_rw_lock_t *rwp)
{
#ifdef _WIN32
if (have_srwlock)
@@ -227,7 +231,7 @@ int my_rw_rdlock(rw_lock_t *rwp)
pthread_mutex_lock(&rwp->lock);
/* active or queued writers */
- while ((rwp->state < 0 ) || rwp->waiters)
+ while (( rwp->state < 0 ) || rwp->waiters)
pthread_cond_wait( &rwp->readers, &rwp->lock);
rwp->state++;
@@ -235,7 +239,7 @@ int my_rw_rdlock(rw_lock_t *rwp)
return(0);
}
-int my_rw_tryrdlock(rw_lock_t *rwp)
+int my_rw_tryrdlock(my_rw_lock_t *rwp)
{
int res;
@@ -257,7 +261,7 @@ int my_rw_tryrdlock(rw_lock_t *rwp)
}
-int my_rw_wrlock(rw_lock_t *rwp)
+int my_rw_wrlock(my_rw_lock_t *rwp)
{
#ifdef _WIN32
if (have_srwlock)
@@ -267,16 +271,21 @@ int my_rw_wrlock(rw_lock_t *rwp)
pthread_mutex_lock(&rwp->lock);
rwp->waiters++; /* another writer queued */
+ my_rw_lock_assert_not_write_owner(rwp);
+
while (rwp->state)
pthread_cond_wait(&rwp->writers, &rwp->lock);
rwp->state = -1;
rwp->waiters--;
+#ifdef SAFE_MUTEX
+ rwp->write_thread= pthread_self();
+#endif
pthread_mutex_unlock(&rwp->lock);
return(0);
}
-int my_rw_trywrlock(rw_lock_t *rwp)
+int my_rw_trywrlock(my_rw_lock_t *rwp)
{
int res;
@@ -292,13 +301,16 @@ int my_rw_trywrlock(rw_lock_t *rwp)
{
res=0;
rwp->state = -1;
+#ifdef SAFE_MUTEX
+ rwp->write_thread= pthread_self();
+#endif
}
pthread_mutex_unlock(&rwp->lock);
return(res);
}
-int my_rw_unlock(rw_lock_t *rwp)
+int my_rw_unlock(my_rw_lock_t *rwp)
{
#ifdef _WIN32
if (have_srwlock)
@@ -309,9 +321,15 @@ int my_rw_unlock(rw_lock_t *rwp)
("state: %d waiters: %d", rwp->state, rwp->waiters));
pthread_mutex_lock(&rwp->lock);
+ DBUG_ASSERT(rwp->state != 0);
+
if (rwp->state == -1) /* writer releasing */
{
+ my_rw_lock_assert_write_owner(rwp);
rwp->state= 0; /* mark as available */
+#ifdef SAFE_MUTEX
+ rwp->write_thread= 0;
+#endif
if ( rwp->waiters ) /* writers queued */
pthread_cond_signal( &rwp->writers );
@@ -320,7 +338,8 @@ int my_rw_unlock(rw_lock_t *rwp)
}
else
{
- if ( --rwp->state == 0 ) /* no more readers */
+ if ( --rwp->state == 0 && /* no more readers */
+ rwp->waiters)
pthread_cond_signal( &rwp->writers );
}
@@ -328,4 +347,126 @@ int my_rw_unlock(rw_lock_t *rwp)
return(0);
}
+#endif /* defined(NEED_MY_RW_LOCK) */
+
+
+int rw_pr_init(rw_pr_lock_t *rwlock)
+{
+ pthread_mutex_init(&rwlock->lock, NULL);
+ pthread_cond_init(&rwlock->no_active_readers, NULL);
+ rwlock->active_readers= 0;
+ rwlock->writers_waiting_readers= 0;
+ rwlock->active_writer= FALSE;
+#ifdef SAFE_MUTEX
+ rwlock->writer_thread= 0;
+#endif
+ return 0;
+}
+
+
+int rw_pr_destroy(rw_pr_lock_t *rwlock)
+{
+ pthread_cond_destroy(&rwlock->no_active_readers);
+ pthread_mutex_destroy(&rwlock->lock);
+ return 0;
+}
+
+
+int rw_pr_rdlock(rw_pr_lock_t *rwlock)
+{
+ pthread_mutex_lock(&rwlock->lock);
+ /*
+ The fact that we were able to acquire 'lock' mutex means
+ that there are no active writers and we can acquire rd-lock.
+ Increment active readers counter to prevent requests for
+ wr-lock from succeeding and unlock mutex.
+ */
+ rwlock->active_readers++;
+ pthread_mutex_unlock(&rwlock->lock);
+ return 0;
+}
+
+
+int rw_pr_wrlock(rw_pr_lock_t *rwlock)
+{
+ pthread_mutex_lock(&rwlock->lock);
+
+ if (rwlock->active_readers != 0)
+ {
+ /* There are active readers. We have to wait until they are gone. */
+ rwlock->writers_waiting_readers++;
+
+ while (rwlock->active_readers != 0)
+ pthread_cond_wait(&rwlock->no_active_readers, &rwlock->lock);
+
+ rwlock->writers_waiting_readers--;
+ }
+
+ /*
+ We own 'lock' mutex so there is no active writers.
+ Also there are no active readers.
+ This means that we can grant wr-lock.
+ Not releasing 'lock' mutex until unlock will block
+ both requests for rd and wr-locks.
+ Set 'active_writer' flag to simplify unlock.
+
+ Thanks to the fact wr-lock/unlock in the absence of
+ contention from readers is essentially mutex lock/unlock
+ with a few simple checks make this rwlock implementation
+ wr-lock optimized.
+ */
+ rwlock->active_writer= TRUE;
+#ifdef SAFE_MUTEX
+ rwlock->writer_thread= pthread_self();
#endif
+ return 0;
+}
+
+
+int rw_pr_unlock(rw_pr_lock_t *rwlock)
+{
+ if (rwlock->active_writer)
+ {
+ /* We are unlocking wr-lock. */
+#ifdef SAFE_MUTEX
+ rwlock->writer_thread= 0;
+#endif
+ rwlock->active_writer= FALSE;
+ if (rwlock->writers_waiting_readers)
+ {
+ /*
+ Avoid expensive cond signal in case when there is no contention
+ or it is wr-only.
+
+ Note that from view point of performance it would be better to
+ signal on the condition variable after unlocking mutex (as it
+ reduces number of contex switches).
+
+ Unfortunately this would mean that such rwlock can't be safely
+ used by MDL subsystem, which relies on the fact that it is OK
+ to destroy rwlock once it is in unlocked state.
+ */
+ pthread_cond_signal(&rwlock->no_active_readers);
+ }
+ pthread_mutex_unlock(&rwlock->lock);
+ }
+ else
+ {
+ /* We are unlocking rd-lock. */
+ pthread_mutex_lock(&rwlock->lock);
+ rwlock->active_readers--;
+ if (rwlock->active_readers == 0 &&
+ rwlock->writers_waiting_readers)
+ {
+ /*
+ If we are last reader and there are waiting
+ writers wake them up.
+ */
+ pthread_cond_signal(&rwlock->no_active_readers);
+ }
+ pthread_mutex_unlock(&rwlock->lock);
+ }
+ return 0;
+}
+
+
diff --git a/mysys/tree.c b/mysys/tree.c
index eba058b22f8..85770194f25 100644
--- a/mysys/tree.c
+++ b/mysys/tree.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, 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
@@ -11,7 +11,7 @@
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
Code for handling red-black (balanced) binary trees.
@@ -183,7 +183,7 @@ static void delete_tree_element(TREE *tree, TREE_ELEMENT *element)
(*tree->free)(ELEMENT_KEY(tree,element), free_free, tree->custom_arg);
delete_tree_element(tree,element->right);
if (tree->with_delete)
- my_free((char*) element,MYF(0));
+ my_free(element);
}
}
@@ -329,7 +329,7 @@ int tree_delete(TREE *tree, void *key, uint key_size, void *custom_arg)
if (tree->free)
(*tree->free)(ELEMENT_KEY(tree,element), free_free, tree->custom_arg);
tree->allocated-= sizeof(TREE_ELEMENT) + tree->size_of_element + key_size;
- my_free((uchar*) element,MYF(0));
+ my_free(element);
tree->elements_in_tree--;
return 0;
}
diff --git a/mysys/trie.c b/mysys/trie.c
deleted file mode 100644
index 5738b9b866b..00000000000
--- a/mysys/trie.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/* Copyright (C) 2005 MySQL 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*
- Implementation of trie and Aho-Corasick automaton.
- Supports only charsets that can be compared byte-wise.
-
- TODO:
- Add character frequencies. Can increase lookup speed
- up to 30%.
- Implement character-wise comparision.
-*/
-
-
-#include "mysys_priv.h"
-#include <m_string.h>
-#include <my_trie.h>
-#include <my_base.h>
-
-
-/*
- SYNOPSIS
- TRIE *trie_init (TRIE *trie, CHARSET_INFO *charset);
-
- DESCRIPTION
- Allocates or initializes a `TRIE' object. If `trie' is a `NULL'
- pointer, the function allocates, initializes, and returns a new
- object. Otherwise, the object is initialized and the address of
- the object is returned. If `trie_init()' allocates a new object,
- it will be freed when `trie_free()' is called.
-
- RETURN VALUE
- An initialized `TRIE*' object. `NULL' if there was insufficient
- memory to allocate a new object.
-*/
-
-TRIE *trie_init (TRIE *trie, CHARSET_INFO *charset)
-{
- MEM_ROOT mem_root;
- DBUG_ENTER("trie_init");
- DBUG_ASSERT(charset);
- init_alloc_root(&mem_root,
- (sizeof(TRIE_NODE) * 128) + ALLOC_ROOT_MIN_BLOCK_SIZE,
- sizeof(TRIE_NODE) * 128);
- if (! trie)
- {
- if (! (trie= (TRIE *)alloc_root(&mem_root, sizeof(TRIE))))
- {
- free_root(&mem_root, MYF(0));
- DBUG_RETURN(NULL);
- }
- }
-
- memcpy(&trie->mem_root, &mem_root, sizeof(MEM_ROOT));
- trie->root.leaf= 0;
- trie->root.c= 0;
- trie->root.next= NULL;
- trie->root.links= NULL;
- trie->root.fail= NULL;
- trie->charset= charset;
- trie->nnodes= 0;
- trie->nwords= 0;
- DBUG_RETURN(trie);
-}
-
-
-/*
- SYNOPSIS
- void trie_free (TRIE *trie);
- trie - valid pointer to `TRIE'
-
- DESCRIPTION
- Frees the memory allocated for a `trie'.
-
- RETURN VALUE
- None.
-*/
-
-void trie_free (TRIE *trie)
-{
- MEM_ROOT mem_root;
- DBUG_ENTER("trie_free");
- DBUG_ASSERT(trie);
- memcpy(&mem_root, &trie->mem_root, sizeof(MEM_ROOT));
- free_root(&mem_root, MYF(0));
- DBUG_VOID_RETURN;
-}
-
-
-/*
- SYNOPSIS
- my_bool trie_insert (TRIE *trie, const uchar *key, uint keylen);
- trie - valid pointer to `TRIE'
- key - valid pointer to key to insert
- keylen - non-0 key length
-
- DESCRIPTION
- Inserts new key into trie.
-
- RETURN VALUE
- Upon successful completion, `trie_insert' returns `FALSE'. Otherwise
- `TRUE' is returned.
-
- NOTES
- If this function fails you must assume `trie' is broken.
- However it can be freed with trie_free().
-*/
-
-my_bool trie_insert (TRIE *trie, const uchar *key, uint keylen)
-{
- TRIE_NODE *node;
- TRIE_NODE *next;
- uchar p;
- uint k;
- DBUG_ENTER("trie_insert");
- DBUG_ASSERT(trie && key && keylen);
- node= &trie->root;
- trie->root.fail= NULL;
- for (k= 0; k < keylen; k++)
- {
- p= key[k];
- for (next= node->links; next; next= next->next)
- if (next->c == p)
- break;
-
- if (! next)
- {
- TRIE_NODE *tmp= (TRIE_NODE *)alloc_root(&trie->mem_root,
- sizeof(TRIE_NODE));
- if (! tmp)
- DBUG_RETURN(TRUE);
- tmp->leaf= 0;
- tmp->c= p;
- tmp->links= tmp->fail= tmp->next= NULL;
- trie->nnodes++;
- if (! node->links)
- {
- node->links= tmp;
- }
- else
- {
- for (next= node->links; next->next; next= next->next) /* no-op */;
- next->next= tmp;
- }
- node= tmp;
- }
- else
- {
- node= next;
- }
- }
- node->leaf= keylen;
- trie->nwords++;
- DBUG_RETURN(FALSE);
-}
-
-
-/*
- SYNOPSIS
- my_bool trie_prepare (TRIE *trie);
- trie - valid pointer to `TRIE'
-
- DESCRIPTION
- Constructs Aho-Corasick automaton.
-
- RETURN VALUE
- Upon successful completion, `trie_prepare' returns `FALSE'. Otherwise
- `TRUE' is returned.
-*/
-
-my_bool ac_trie_prepare (TRIE *trie)
-{
- TRIE_NODE **tmp_nodes;
- TRIE_NODE *node;
- uint32 fnode= 0;
- uint32 lnode= 0;
- DBUG_ENTER("trie_prepare");
- DBUG_ASSERT(trie);
-
- tmp_nodes= (TRIE_NODE **)my_malloc(trie->nnodes * sizeof(TRIE_NODE *), MYF(0));
- if (! tmp_nodes)
- DBUG_RETURN(TRUE);
-
- trie->root.fail= &trie->root;
- for (node= trie->root.links; node; node= node->next)
- {
- node->fail= &trie->root;
- tmp_nodes[lnode++]= node;
- }
-
- while (fnode < lnode)
- {
- TRIE_NODE *current= (TRIE_NODE *)tmp_nodes[fnode++];
- for (node= current->links; node; node= node->next)
- {
- TRIE_NODE *fail= current->fail;
- tmp_nodes[lnode++]= node;
- while (! (node->fail= trie_goto(&trie->root, fail, node->c)))
- fail= fail->fail;
- }
- }
- my_free((uchar*)tmp_nodes, MYF(0));
- DBUG_RETURN(FALSE);
-}
-
-
-/*
- SYNOPSIS
- void ac_trie_init (TRIE *trie, AC_TRIE_STATE *state);
- trie - valid pointer to `TRIE'
- state - value pointer to `AC_TRIE_STATE'
-
- DESCRIPTION
- Initializes `AC_TRIE_STATE' object.
-*/
-
-void ac_trie_init (TRIE *trie, AC_TRIE_STATE *state)
-{
- DBUG_ENTER("ac_trie_init");
- DBUG_ASSERT(trie && state);
- state->trie= trie;
- state->node= &trie->root;
- DBUG_VOID_RETURN;
-}
diff --git a/mysys/typelib.c b/mysys/typelib.c
index 6aee9987162..402d108e51c 100644
--- a/mysys/typelib.c
+++ b/mysys/typelib.c
@@ -1,6 +1,4 @@
-/*
- Copyright (c) 2000-2004, 2006, 2007 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
+/* 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
@@ -13,8 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Functions to handle typelib */
@@ -23,14 +20,15 @@
#include <m_ctype.h>
-static const char field_separator=',';
+#define is_field_separator(F, X) \
+ ((F & FIND_TYPE_COMMA_TERM) && ((X) == ',' || (X) == '='))
int find_type_with_warning(const char *x, TYPELIB *typelib, const char *option)
{
int res;
const char **ptr;
- if ((res= find_type((char *) x, typelib, 2)) <= 0)
+ if ((res= find_type((char *) x, typelib, FIND_TYPE_BASIC)) <= 0)
{
ptr= typelib->type_names;
if (!*x)
@@ -46,47 +44,52 @@ int find_type_with_warning(const char *x, TYPELIB *typelib, const char *option)
}
-uint find_type_or_exit(const char *x, TYPELIB *typelib, const char *option)
+int find_type_or_exit(const char *x, TYPELIB *typelib, const char *option)
{
int res;
if ((res= find_type_with_warning(x, typelib, option)) <= 0)
+ {
+ sf_leaking_memory= 1; /* no memory leak reports here */
exit(1);
- return (uint) res;
+ }
+ return res;
}
-/*
+/**
Search after a string in a list of strings. Endspace in x is not compared.
- SYNOPSIS
- find_type()
- x String to find
- lib TYPELIB (struct of pointer to values + count)
- full_name bitmap of what to do
- If & 1 accept only whole names
- If & 2 don't expand if half field
- If & 4 allow #number# as type
- If & 8 use ',' as string terminator
-
- NOTES
- If part, uniq field is found and full_name == 0 then x is expanded
- to full field.
-
- RETURN
- -1 Too many matching values
- 0 No matching value
+ @param x pointer to string to find
+ (not necessarily zero-terminated).
+ by return it'll be advanced to point to the terminator.
+ @param typelib TYPELIB (struct of pointer to values + count)
+ @param flags flags to tune behaviour: a combination of
+ FIND_TYPE_NO_PREFIX
+ FIND_TYPE_COMMA_TERM.
+ @param eol a pointer to the end of the string.
+
+ @retval
+ -1 Too many matching values
+ @retval
+ 0 No matching value
+ @retval
>0 Offset+1 in typelib for matched string
*/
-int find_type(char *x, const TYPELIB *typelib, uint full_name)
+static int find_type_eol(const char **x, const TYPELIB *typelib, uint flags,
+ const char *eol)
{
int find,pos;
int UNINIT_VAR(findpos); /* guarded by find */
- reg1 char * i;
- reg2 const char *j;
- DBUG_ENTER("find_type");
- DBUG_PRINT("enter",("x: '%s' lib: 0x%lx", x, (long) typelib));
+ const char *UNINIT_VAR(termptr);
+ const char *i;
+ const char *j;
+ CHARSET_INFO *cs= &my_charset_latin1;
+ DBUG_ENTER("find_type_eol");
+ DBUG_PRINT("enter",("x: '%s' lib: 0x%lx", *x, (long) typelib));
+
+ DBUG_ASSERT(!(flags & ~(FIND_TYPE_NO_PREFIX | FIND_TYPE_COMMA_TERM)));
if (!typelib->count)
{
@@ -96,45 +99,59 @@ int find_type(char *x, const TYPELIB *typelib, uint full_name)
find=0;
for (pos=0 ; (j=typelib->type_names[pos]) ; pos++)
{
- for (i=x ;
- *i && (!(full_name & 8) || *i != field_separator) &&
- my_toupper(&my_charset_latin1,*i) ==
- my_toupper(&my_charset_latin1,*j) ; i++, j++) ;
+ for (i=*x ;
+ i < eol && !is_field_separator(flags, *i) &&
+ my_toupper(cs, *i) == my_toupper(cs, *j) ; i++, j++) ;
if (! *j)
{
- while (*i == ' ')
+ while (i < eol && *i == ' ')
i++; /* skip_end_space */
- if (! *i || ((full_name & 8) && *i == field_separator))
+ if (i >= eol || is_field_separator(flags, *i))
+ {
+ *x= i;
DBUG_RETURN(pos+1);
+ }
}
- if ((!*i && (!(full_name & 8) || *i != field_separator)) &&
- (!*j || !(full_name & 1)))
+ if ((i >= eol && !is_field_separator(flags, *i)) &&
+ (!*j || !(flags & FIND_TYPE_NO_PREFIX)))
{
find++;
findpos=pos;
+ termptr=i;
}
}
- if (find == 0 && (full_name & 4) && x[0] == '#' && strend(x)[-1] == '#' &&
- (findpos=atoi(x+1)-1) >= 0 && (uint) findpos < typelib->count)
- find=1;
- else if (find == 0 || ! x[0])
+ if (find == 0 || *x == eol)
{
DBUG_PRINT("exit",("Couldn't find type"));
DBUG_RETURN(0);
}
- else if (find != 1 || (full_name & 1))
+ else if (find != 1 || (flags & FIND_TYPE_NO_PREFIX))
{
- DBUG_PRINT("exit",("Too many possybilities"));
+ DBUG_PRINT("exit",("Too many possibilities"));
DBUG_RETURN(-1);
}
- if (!(full_name & 2))
- (void) strmov(x,typelib->type_names[findpos]);
+ *x= termptr;
DBUG_RETURN(findpos+1);
-} /* find_type */
+} /* find_type_eol */
- /* Get name of type nr 'nr' */
- /* Warning first type is 1, 0 = empty field */
+/**
+ Search after a string in a list of strings. Endspace in x is not compared.
+
+ Same as find_type_eol, but for zero-terminated strings,
+ and without advancing the pointer.
+*/
+int find_type(const char *x, const TYPELIB *typelib, uint flags)
+{
+ return find_type_eol(&x, typelib, flags, x + strlen(x));
+}
+
+/**
+ Get name of type nr
+
+ @note
+ first type is 1, 0 = empty field
+*/
void make_type(register char * to, register uint nr,
register TYPELIB *typelib)
@@ -148,8 +165,12 @@ void make_type(register char * to, register uint nr,
} /* make_type */
- /* Get type */
- /* Warning first type is 0 */
+/**
+ Get type
+
+ @note
+ first type is 0
+*/
const char *get_type(TYPELIB *typelib, uint nr)
{
@@ -159,18 +180,16 @@ const char *get_type(TYPELIB *typelib, uint nr)
}
-/*
+/**
Create an integer value to represent the supplied comma-seperated
string where each string in the TYPELIB denotes a bit position.
- SYNOPSIS
- find_typeset()
- x string to decompose
- lib TYPELIB (struct of pointer to values + count)
- err index (not char position) of string element which was not
+ @param x string to decompose
+ @param lib TYPELIB (struct of pointer to values + count)
+ @param err index (not char position) of string element which was not
found or 0 if there was no error
- RETURN
+ @retval
a integer representation of the supplied string
*/
@@ -193,11 +212,11 @@ my_ulonglong find_typeset(char *x, TYPELIB *lib, int *err)
{
(*err)++;
i= x;
- while (*x && *x != field_separator)
+ while (*x && *x != ',')
x++;
- if (x[0] && x[1]) /* skip separator if found */
+ if (x[0] && x[1]) /* skip separator if found */
x++;
- if ((find= find_type(i, lib, 2 | 8) - 1) < 0)
+ if ((find= find_type(i, lib, FIND_TYPE_COMMA_TERM) - 1) < 0)
DBUG_RETURN(0);
result|= (ULL(1) << find);
}
@@ -206,16 +225,15 @@ my_ulonglong find_typeset(char *x, TYPELIB *lib, int *err)
} /* find_set */
-/*
+/**
Create a copy of a specified TYPELIB structure.
- SYNOPSIS
- copy_typelib()
- root pointer to a MEM_ROOT object for allocations
- from pointer to a source TYPELIB structure
+ @param root pointer to a MEM_ROOT object for allocations
+ @param from pointer to a source TYPELIB structure
- RETURN
- pointer to the new TYPELIB structure on successful copy, or
+ @retval
+ pointer to the new TYPELIB structure on successful copy
+ @retval
NULL otherwise
*/
@@ -255,3 +273,138 @@ TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from)
return to;
}
+
+
+static const char *on_off_default_names[]= { "off","on","default", 0};
+static TYPELIB on_off_default_typelib= {array_elements(on_off_default_names)-1,
+ "", on_off_default_names, 0};
+
+/**
+ Parse a TYPELIB name from the buffer
+
+ @param lib Set of names to scan for.
+ @param strpos INOUT Start of the buffer (updated to point to the next
+ character after the name)
+ @param end End of the buffer
+
+ @note
+ The buffer is assumed to contain one of the names specified in the TYPELIB,
+ followed by comma, '=', or end of the buffer.
+
+ @retval
+ 0 No matching name
+ @retval
+ >0 Offset+1 in typelib for matched name
+*/
+
+static uint parse_name(const TYPELIB *lib, const char **pos, const char *end)
+{
+ uint find= find_type_eol(pos, lib,
+ FIND_TYPE_COMMA_TERM | FIND_TYPE_NO_PREFIX, end);
+ return find;
+}
+
+/**
+ Parse and apply a set of flag assingments
+
+ @param lib Flag names
+ @param default_name Number of "default" in the typelib
+ @param cur_set Current set of flags (start from this state)
+ @param default_set Default set of flags (use this for assign-default
+ keyword and flag=default assignments)
+ @param str String to be parsed
+ @param length Length of the string
+ @param err_pos OUT If error, set to point to start of wrong set string
+ NULL on success
+ @param err_len OUT If error, set to the length of wrong set string
+
+ @details
+ Parse a set of flag assignments, that is, parse a string in form:
+
+ param_name1=value1,param_name2=value2,...
+
+ where the names are specified in the TYPELIB, and each value can be
+ either 'on','off', or 'default'. Setting the same name twice is not
+ allowed.
+
+ Besides param=val assignments, we support the "default" keyword (keyword
+ #default_name in the typelib). It can be used one time, if specified it
+ causes us to build the new set over the default_set rather than cur_set
+ value.
+
+ @note
+ it's not charset aware
+
+ @retval
+ Parsed set value if (*errpos == NULL), otherwise undefined
+*/
+
+my_ulonglong find_set_from_flags(const TYPELIB *lib, uint default_name,
+ my_ulonglong cur_set, my_ulonglong default_set,
+ const char *str, uint length,
+ char **err_pos, uint *err_len)
+{
+ const char *end= str + length;
+ my_ulonglong flags_to_set= 0, flags_to_clear= 0, res;
+ my_bool set_defaults= 0;
+
+ *err_pos= 0; /* No error yet */
+ if (str != end)
+ {
+ const char *start= str;
+ for (;;)
+ {
+ const char *pos= start;
+ uint flag_no, value;
+
+ if (!(flag_no= parse_name(lib, &pos, end)))
+ goto err;
+
+ if (flag_no == default_name)
+ {
+ /* Using 'default' twice isn't allowed. */
+ if (set_defaults)
+ goto err;
+ set_defaults= TRUE;
+ }
+ else
+ {
+ my_ulonglong bit= (1ULL << (flag_no - 1));
+ /* parse the '=on|off|default' */
+ if ((flags_to_clear | flags_to_set) & bit ||
+ pos >= end || *pos++ != '=' ||
+ !(value= parse_name(&on_off_default_typelib, &pos, end)))
+ goto err;
+
+ if (value == 1) /* this is '=off' */
+ flags_to_clear|= bit;
+ else if (value == 2) /* this is '=on' */
+ flags_to_set|= bit;
+ else /* this is '=default' */
+ {
+ if (default_set & bit)
+ flags_to_set|= bit;
+ else
+ flags_to_clear|= bit;
+ }
+ }
+ if (pos >= end)
+ break;
+
+ if (*pos++ != ',')
+ goto err;
+
+ start=pos;
+ continue;
+ err:
+ *err_pos= (char*)start;
+ *err_len= end - start;
+ break;
+ }
+ }
+ res= set_defaults? default_set : cur_set;
+ res|= flags_to_set;
+ res&= ~flags_to_clear;
+ return res;
+}
+
diff --git a/mysys/waiting_threads.c b/mysys/waiting_threads.c
index 6ee79cb8e87..0a9474e68b4 100644
--- a/mysys/waiting_threads.c
+++ b/mysys/waiting_threads.c
@@ -193,6 +193,10 @@ uint32 wt_success_stats;
static my_atomic_rwlock_t cycle_stats_lock, wait_stats_lock, success_stats_lock;
+#ifdef HAVE_PSI_INTERFACE
+extern PSI_cond_key key_WT_RESOURCE_cond;
+#endif
+
#ifdef SAFE_STATISTICS
#define incr(VAR, LOCK) \
do { \
@@ -253,7 +257,7 @@ struct st_wt_resource {
uint waiter_count;
enum { ACTIVE, FREE } state;
#ifndef DBUG_OFF
- pthread_mutex_t *cond_mutex; /* a mutex for the 'cond' below */
+ mysql_mutex_t *cond_mutex; /* a mutex for the 'cond' below */
#endif
/*
before the 'lock' all elements are mutable, after (and including) -
@@ -301,7 +305,7 @@ struct st_wt_resource {
#else
rw_lock_t lock;
#endif
- pthread_cond_t cond; /* the corresponding mutex is provided by the caller */
+ mysql_cond_t cond; /* the corresponding mutex is provided by the caller */
DYNAMIC_ARRAY owners;
};
@@ -398,7 +402,7 @@ static void wt_resource_init(uchar *arg)
bzero(rc, sizeof(*rc));
rc_rwlock_init(rc);
- pthread_cond_init(&rc->cond, 0);
+ mysql_cond_init(key_WT_RESOURCE_cond, &rc->cond, 0);
my_init_dynamic_array(&rc->owners, sizeof(WT_THD *), 0, 5);
DBUG_VOID_RETURN;
}
@@ -416,11 +420,13 @@ static void wt_resource_destroy(uchar *arg)
DBUG_ASSERT(rc->owners.elements == 0);
rc_rwlock_destroy(rc);
- pthread_cond_destroy(&rc->cond);
+ mysql_cond_destroy(&rc->cond);
delete_dynamic(&rc->owners);
DBUG_VOID_RETURN;
}
+static int wt_init_done;
+
void wt_init()
{
DBUG_ENTER("wt_init");
@@ -454,18 +460,22 @@ void wt_init()
my_atomic_rwlock_init(&cycle_stats_lock);
my_atomic_rwlock_init(&success_stats_lock);
my_atomic_rwlock_init(&wait_stats_lock);
+ wt_init_done= 1;
DBUG_VOID_RETURN;
}
void wt_end()
{
DBUG_ENTER("wt_end");
+ if (!wt_init_done)
+ DBUG_VOID_RETURN;
DBUG_ASSERT(reshash.count == 0);
lf_hash_destroy(&reshash);
my_atomic_rwlock_destroy(&cycle_stats_lock);
my_atomic_rwlock_destroy(&success_stats_lock);
my_atomic_rwlock_destroy(&wait_stats_lock);
+ wt_init_done= 0;
DBUG_VOID_RETURN;
}
@@ -795,7 +805,7 @@ static int deadlock(WT_THD *thd, WT_THD *blocker, uint depth,
{
DBUG_PRINT("wt", ("killing %s", arg.victim->name));
arg.victim->killed= 1;
- pthread_cond_broadcast(&arg.victim->waiting_for->cond);
+ mysql_cond_broadcast(&arg.victim->waiting_for->cond);
rc_unlock(arg.victim->waiting_for);
ret= WT_OK;
}
@@ -1029,11 +1039,11 @@ retry:
called by a *waiter* (thd) to start waiting
It's supposed to be a drop-in replacement for
- pthread_cond_timedwait(), and it takes mutex as an argument.
+ mysql_cond_timedwait(), and it takes mutex as an argument.
@return one of WT_TIMEOUT, WT_DEADLOCK, WT_OK
*/
-int wt_thd_cond_timedwait(WT_THD *thd, pthread_mutex_t *mutex)
+int wt_thd_cond_timedwait(WT_THD *thd, mysql_mutex_t *mutex)
{
int ret= WT_TIMEOUT;
struct timespec timeout;
@@ -1048,7 +1058,7 @@ int wt_thd_cond_timedwait(WT_THD *thd, pthread_mutex_t *mutex)
DBUG_ASSERT(rc->cond_mutex == mutex);
else
rc->cond_mutex= mutex;
- safe_mutex_assert_owner(mutex);
+ mysql_mutex_assert_owner(mutex);
#endif
before= starttime= my_hrtime();
@@ -1061,7 +1071,7 @@ int wt_thd_cond_timedwait(WT_THD *thd, pthread_mutex_t *mutex)
end_wait_time= starttime.val *1000 + (*thd->timeout_short)*ULL(1000000);
set_timespec_time_nsec(timeout, end_wait_time);
if (ret == WT_TIMEOUT && !thd->killed)
- ret= pthread_cond_timedwait(&rc->cond, mutex, &timeout);
+ ret= mysql_cond_timedwait(&rc->cond, mutex, &timeout);
if (ret == WT_TIMEOUT && !thd->killed)
{
int r= deadlock(thd, thd, 0, *thd->deadlock_search_depth_long);
@@ -1074,7 +1084,7 @@ int wt_thd_cond_timedwait(WT_THD *thd, pthread_mutex_t *mutex)
end_wait_time= starttime.val *1000 + (*thd->timeout_long)*ULL(1000000);
set_timespec_time_nsec(timeout, end_wait_time);
if (!thd->killed)
- ret= pthread_cond_timedwait(&rc->cond, mutex, &timeout);
+ ret= mysql_cond_timedwait(&rc->cond, mutex, &timeout);
}
}
after= my_hrtime();
@@ -1120,10 +1130,10 @@ void wt_thd_release(WT_THD *thd, const WT_RESOURCE_ID *resid)
delete_dynamic_element(&rc->owners, j);
if (rc->owners.elements == 0)
{
- pthread_cond_broadcast(&rc->cond);
+ mysql_cond_broadcast(&rc->cond);
#ifndef DBUG_OFF
if (rc->cond_mutex)
- safe_mutex_assert_owner(rc->cond_mutex);
+ mysql_mutex_assert_owner(rc->cond_mutex);
#endif
}
unlock_lock_and_free_resource(thd, rc);
diff --git a/mysys/wqueue.c b/mysys/wqueue.c
index fcc0a39725d..2fcced14f77 100644
--- a/mysys/wqueue.c
+++ b/mysys/wqueue.c
@@ -1,3 +1,19 @@
+/*
+ Copyright (c) 2007, 2008, Sun Microsystems, Inc,
+ Copyright (c) 2011, 2012, Monty Program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <wqueue.h>
@@ -130,7 +146,7 @@ void wqueue_release_queue(WQUEUE *wqueue)
do
{
thread= next;
- pthread_cond_signal(&thread->suspend);
+ mysql_cond_signal(&thread->suspend);
next= thread->next;
thread->next= NULL;
}
@@ -158,7 +174,7 @@ void wqueue_release_one_locktype_from_queue(WQUEUE *wqueue)
if (first_type == MY_PTHREAD_LOCK_WRITE)
{
/* release first waiting for write lock */
- pthread_cond_signal(&next->suspend);
+ mysql_cond_signal(&next->suspend);
if (next == last)
wqueue->last_thread= NULL;
else
@@ -184,7 +200,7 @@ void wqueue_release_one_locktype_from_queue(WQUEUE *wqueue)
else
{
/* release waiting for read lock */
- pthread_cond_signal(&thread->suspend);
+ mysql_cond_signal(&thread->suspend);
thread->next= NULL;
}
} while (thread != last);
@@ -204,7 +220,7 @@ void wqueue_release_one_locktype_from_queue(WQUEUE *wqueue)
void wqueue_add_and_wait(WQUEUE *wqueue,
struct st_my_thread_var *thread,
- pthread_mutex_t *lock)
+ mysql_mutex_t *lock)
{
DBUG_ENTER("wqueue_add_and_wait");
DBUG_PRINT("enter",
@@ -215,7 +231,7 @@ void wqueue_add_and_wait(WQUEUE *wqueue,
{
DBUG_PRINT("info", ("wait... cond: 0x%lx mutex: 0x%lx",
(ulong) &thread->suspend, (ulong) lock));
- pthread_cond_wait(&thread->suspend, lock);
+ mysql_cond_wait(&thread->suspend, lock);
DBUG_PRINT("info", ("wait done cond: 0x%lx mutex: 0x%lx next: 0x%lx",
(ulong) &thread->suspend, (ulong) lock,
(ulong) thread->next));