summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/.cvsignore4
-rw-r--r--include/CMakeLists.txt63
-rw-r--r--include/Makefile.am56
-rw-r--r--include/atomic/gcc_builtins.h10
-rw-r--r--include/atomic/generic-msvc.h134
-rw-r--r--include/atomic/nolock.h58
-rw-r--r--include/atomic/rwlock.h74
-rw-r--r--include/atomic/solaris.h66
-rw-r--r--include/atomic/x86-gcc.h108
-rw-r--r--include/atomic/x86-msvc.h96
-rw-r--r--include/config-netware.h3
-rw-r--r--include/config-win.h62
-rw-r--r--include/errmsg.h7
-rw-r--r--include/ft_global.h4
-rw-r--r--include/hash.h60
-rw-r--r--include/heap.h4
-rw-r--r--include/help_end.h4
-rw-r--r--include/help_start.h4
-rw-r--r--include/keycache.h17
-rw-r--r--include/lf.h268
-rw-r--r--include/m_ctype.h107
-rw-r--r--include/m_string.h144
-rw-r--r--include/my_aes.h5
-rw-r--r--include/my_alarm.h10
-rw-r--r--include/my_atomic.h276
-rw-r--r--include/my_base.h29
-rw-r--r--include/my_bit.h5
-rw-r--r--include/my_bitmap.h4
-rw-r--r--include/my_dbug.h198
-rw-r--r--include/my_dir.h22
-rw-r--r--include/my_getopt.h53
-rw-r--r--include/my_global.h281
-rw-r--r--include/my_handler.h4
-rw-r--r--include/my_libwrap.h4
-rw-r--r--include/my_md5.h5
-rw-r--r--include/my_net.h19
-rw-r--r--include/my_no_pthread.h21
-rw-r--r--include/my_pthread.h238
-rw-r--r--include/my_rdtsc.h129
-rw-r--r--include/my_sys.h103
-rw-r--r--include/my_time.h6
-rw-r--r--include/my_tree.h1
-rw-r--r--include/my_uctype.h4
-rw-r--r--include/myisam.h16
-rw-r--r--include/myisammrg.h4
-rw-r--r--include/myisampack.h4
-rw-r--r--include/mysql.h136
-rw-r--r--include/mysql.h.pp87
-rw-r--r--include/mysql/innodb_priv.h37
-rw-r--r--include/mysql/plugin.h322
-rw-r--r--include/mysql/plugin.h.pp56
-rw-r--r--include/mysql/plugin_audit.h98
-rw-r--r--include/mysql/plugin_ftparser.h211
-rw-r--r--include/mysql/psi/mysql_file.h1400
-rw-r--r--include/mysql/psi/mysql_thread.h1164
-rw-r--r--include/mysql/psi/psi.h1091
-rw-r--r--include/mysql/psi/psi_abi_v1.h26
-rw-r--r--include/mysql/psi/psi_abi_v1.h.pp244
-rw-r--r--include/mysql/psi/psi_abi_v2.h26
-rw-r--r--include/mysql/psi/psi_abi_v2.h.pp92
-rw-r--r--include/mysql/service_my_snprintf.h98
-rw-r--r--include/mysql/service_thd_alloc.h128
-rw-r--r--include/mysql/services.h30
-rw-r--r--include/mysql_com.h44
-rw-r--r--include/mysql_embed.h6
-rw-r--r--include/mysys_err.h3
-rw-r--r--include/password.h32
-rw-r--r--include/probes_mysql.d.base176
-rw-r--r--include/probes_mysql.h13
-rw-r--r--include/probes_mysql_nodtrace.h129
-rw-r--r--include/queues.h3
-rw-r--r--include/rijndael.h5
-rw-r--r--include/service_versions.h24
-rw-r--r--include/sha1.h5
-rw-r--r--include/sha2.h72
-rw-r--r--include/sql_common.h4
-rw-r--r--include/sslopt-case.h6
-rw-r--r--include/sslopt-longopts.h12
-rw-r--r--include/sslopt-vars.h6
-rw-r--r--include/thr_alarm.h2
-rw-r--r--include/thr_lock.h24
-rw-r--r--include/typelib.h5
-rw-r--r--include/violite.h47
83 files changed, 7499 insertions, 1159 deletions
diff --git a/include/.cvsignore b/include/.cvsignore
deleted file mode 100644
index fc53b1b5f65..00000000000
--- a/include/.cvsignore
+++ /dev/null
@@ -1,4 +0,0 @@
-Makefile
-Makefile.in
-my_config.h
-mysql_version.h
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
new file mode 100644
index 00000000000..e2ef01b3b4c
--- /dev/null
+++ b/include/CMakeLists.txt
@@ -0,0 +1,63 @@
+# Copyright (C) 2009 Sun Microsystems, Inc
+#
+# 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
+
+SET(HEADERS_GEN_CONFIGURE
+${CMAKE_CURRENT_BINARY_DIR}/mysql_version.h
+${CMAKE_CURRENT_BINARY_DIR}/my_config.h
+${CMAKE_CURRENT_BINARY_DIR}/mysqld_ername.h
+${CMAKE_CURRENT_BINARY_DIR}/mysqld_error.h
+${CMAKE_CURRENT_BINARY_DIR}/sql_state.h
+)
+SET(HEADERS_ABI
+ mysql.h
+ mysql_com.h
+ mysql_time.h
+ my_list.h
+ my_alloc.h
+ typelib.h
+ mysql/plugin.h
+ mysql/plugin_audit.h
+ mysql/plugin_ftparser.h
+)
+
+SET(HEADERS
+ ${HEADERS_ABI}
+ my_dbug.h
+ m_string.h
+ my_sys.h
+ my_xml.h
+ mysql_embed.h
+ my_pthread.h
+ my_no_pthread.h
+ decimal.h
+ errmsg.h
+ my_global.h
+ my_net.h
+ my_getopt.h
+ sslopt-longopts.h
+ my_dir.h
+ sslopt-vars.h
+ sslopt-case.h
+ sql_common.h
+ keycache.h
+ m_ctype.h
+ my_attribute.h
+ ${HEADERS_GEN_CONFIGURE}
+)
+
+INSTALL(FILES ${HEADERS} DESTINATION ${INSTALL_INCLUDEDIR})
+INSTALL(DIRECTORY mysql/ DESTINATION ${INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.h")
+
+
diff --git a/include/Makefile.am b/include/Makefile.am
index 64f73af8606..da50ecf2178 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (C) 2000-2006 MySQL AB
+# Copyright (C) 2000-2006 MySQL AB, 2009 Sun Microsystems, Inc
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
@@ -15,36 +15,45 @@
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA
-BUILT_SOURCES = $(HEADERS_GEN_MAKE) link_sources
+BUILT_SOURCES = $(HEADERS_GEN_MAKE) link_sources probes_mysql_nodtrace.h
HEADERS_GEN_CONFIGURE = mysql_version.h
HEADERS_GEN_MAKE = my_config.h
HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \
- my_list.h my_alloc.h typelib.h mysql/plugin.h
+ my_list.h my_alloc.h typelib.h mysql/plugin.h \
+ mysql/plugin_audit.h mysql/plugin_ftparser.h
pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
- my_xml.h mysql_embed.h \
+ my_xml.h mysql_embed.h mysql/services.h \
+ mysql/service_my_snprintf.h mysql/service_thd_alloc.h \
my_pthread.h my_no_pthread.h \
+ mysql/psi/psi.h mysql/psi/mysql_thread.h \
+ mysql/psi/mysql_file.h \
decimal.h errmsg.h my_global.h my_net.h \
my_getopt.h sslopt-longopts.h my_dir.h \
sslopt-vars.h sslopt-case.h sql_common.h keycache.h \
m_ctype.h my_attribute.h $(HEADERS_GEN_CONFIGURE) \
- $(HEADERS_GEN_MAKE)
+ $(HEADERS_GEN_MAKE) probes_mysql.h probes_mysql_nodtrace.h
-noinst_HEADERS = config-win.h config-netware.h my_bit.h \
- heap.h my_bitmap.h my_uctype.h \
+noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \
+ heap.h my_bitmap.h my_uctype.h password.h \
myisam.h myisampack.h myisammrg.h ft_global.h\
mysys_err.h my_base.h help_start.h help_end.h \
- my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \
+ my_nosys.h my_alarm.h queues.h rijndael.h sha1.h sha2.h \
my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \
thr_lock.h t_ctype.h violite.h my_md5.h base64.h \
- my_handler.h my_time.h \
+ my_handler.h my_time.h service_versions.h \
+ my_rdtsc.h mysql/psi/psi_abi_v1.h mysql/psi/psi_abi_v2.h \
my_vle.h my_user.h my_atomic.h atomic/nolock.h \
- atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \
- atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h
+ atomic/rwlock.h atomic/x86-gcc.h atomic/generic-msvc.h \
+ atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h \
+ atomic/solaris.h mysql/innodb_priv.h
-EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp
+EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp probes_mysql.d.base \
+ CMakeLists.txt \
+ mysql/psi/psi_abi_v1.h.pp \
+ mysql/psi/psi_abi_v2.h.pp
# Remove built files and the symlinked directories
-CLEANFILES = $(BUILT_SOURCES) readline openssl
+CLEANFILES = $(BUILT_SOURCES) readline openssl probes_mysql.d probes_mysql_nodtrace.h
# Some include files that may be moved and patched by configure
@@ -67,5 +76,26 @@ my_config.h: config.h
dist-hook:
$(RM) -f $(distdir)/mysql_version.h $(distdir)/my_config.h
+probes_mysql.d:
+ if ! test -f probes_mysql.d ; then \
+ $(CP) -f $(top_srcdir)/include/probes_mysql.d.base probes_mysql.d; \
+ fi
+
+DTRACEPROVIDER = probes_mysql.d
+if HAVE_DTRACE
+BUILT_SOURCES += probes_mysql_dtrace.h
+CLEANFILES += $(DTRACEPROVIDER)
+
+# Fake for creating the probes file. If we are building a separate directory
+# then we copy the probes from the source location and use that
+# If we are building in the same directory as the source, we do not copy
+
+probes_mysql_dtrace.h: $(DTRACEPROVIDER)
+ $(DTRACE) $(DTRACEFLAGS) -h -s $(DTRACEPROVIDER) -o $@
+endif
+
+probes_mysql_nodtrace.h: $(DTRACEPROVIDER)
+ @PERL@ $(top_srcdir)/scripts/dheadgen.pl -f $(DTRACEPROVIDER) > $@
+
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/include/atomic/gcc_builtins.h b/include/atomic/gcc_builtins.h
index 509701b30a5..100ff80cacd 100644
--- a/include/atomic/gcc_builtins.h
+++ b/include/atomic/gcc_builtins.h
@@ -1,3 +1,6 @@
+#ifndef ATOMIC_GCC_BUILTINS_INCLUDED
+#define ATOMIC_GCC_BUILTINS_INCLUDED
+
/* Copyright (C) 2008 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -15,7 +18,7 @@
#define make_atomic_add_body(S) \
v= __sync_fetch_and_add(a, v);
-#define make_atomic_swap_body(S) \
+#define make_atomic_fas_body(S) \
v= __sync_lock_test_and_set(a, v);
#define make_atomic_cas_body(S) \
int ## S sav; \
@@ -25,9 +28,14 @@
#ifdef MY_ATOMIC_MODE_DUMMY
#define make_atomic_load_body(S) ret= *a
#define make_atomic_store_body(S) *a= v
+#define MY_ATOMIC_MODE "gcc-builtins-up"
+
#else
+#define MY_ATOMIC_MODE "gcc-builtins-smp"
#define make_atomic_load_body(S) \
ret= __sync_fetch_and_or(a, 0);
#define make_atomic_store_body(S) \
(void) __sync_lock_test_and_set(a, v);
#endif
+
+#endif /* ATOMIC_GCC_BUILTINS_INCLUDED */
diff --git a/include/atomic/generic-msvc.h b/include/atomic/generic-msvc.h
new file mode 100644
index 00000000000..a84cde6b2c3
--- /dev/null
+++ b/include/atomic/generic-msvc.h
@@ -0,0 +1,134 @@
+/* Copyright (C) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+
+ 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 */
+
+#ifndef _atomic_h_cleanup_
+#define _atomic_h_cleanup_ "atomic/generic-msvc.h"
+
+/*
+ We don't implement anything specific for MY_ATOMIC_MODE_DUMMY, always use
+ intrinsics.
+ 8 and 16-bit atomics are not implemented, but it can be done if necessary.
+*/
+#undef MY_ATOMIC_HAS_8_16
+
+#include <windows.h>
+/*
+ x86 compilers (both VS2003 or VS2005) never use instrinsics, but generate
+ function calls to kernel32 instead, even in the optimized build.
+ We force intrinsics as described in MSDN documentation for
+ _InterlockedCompareExchange.
+*/
+#ifdef _M_IX86
+
+#if (_MSC_VER >= 1500)
+#include <intrin.h>
+#else
+C_MODE_START
+/*Visual Studio 2003 and earlier do not have prototypes for atomic intrinsics*/
+LONG _InterlockedCompareExchange (LONG volatile *Target, LONG Value, LONG Comp);
+LONGLONG _InterlockedCompareExchange64 (LONGLONG volatile *Target,
+ LONGLONG Value, LONGLONG Comp);
+C_MODE_END
+
+#pragma intrinsic(_InterlockedCompareExchange)
+#pragma intrinsic(_InterlockedCompareExchange64)
+#endif
+
+#define InterlockedCompareExchange _InterlockedCompareExchange
+#define InterlockedCompareExchange64 _InterlockedCompareExchange64
+/*
+ No need to do something special for InterlockedCompareExchangePointer
+ as it is a #define to InterlockedCompareExchange. The same applies to
+ InterlockedExchangePointer.
+*/
+#endif /*_M_IX86*/
+
+#define MY_ATOMIC_MODE "msvc-intrinsics"
+/* Implement using CAS on WIN32 */
+#define IL_COMP_EXCHG32(X,Y,Z) \
+ InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z))
+#define IL_COMP_EXCHG64(X,Y,Z) \
+ InterlockedCompareExchange64((volatile LONGLONG *)(X), \
+ (LONGLONG)(Y),(LONGLONG)(Z))
+#define IL_COMP_EXCHGptr InterlockedCompareExchangePointer
+
+#define make_atomic_cas_body(S) \
+ int ## S initial_cmp= *cmp; \
+ int ## S initial_a= IL_COMP_EXCHG ## S (a, set, initial_cmp); \
+ if (!(ret= (initial_a == initial_cmp))) *cmp= initial_a;
+
+#ifndef _M_IX86
+/* Use full set of optimised functions on WIN64 */
+#define IL_EXCHG_ADD32(X,Y) \
+ InterlockedExchangeAdd((volatile LONG *)(X),(Y))
+#define IL_EXCHG_ADD64(X,Y) \
+ InterlockedExchangeAdd64((volatile LONGLONG *)(X),(LONGLONG)(Y))
+#define IL_EXCHG32(X,Y) \
+ InterlockedExchange((volatile LONG *)(X),(Y))
+#define IL_EXCHG64(X,Y) \
+ InterlockedExchange64((volatile LONGLONG *)(X),(LONGLONG)(Y))
+#define IL_EXCHGptr InterlockedExchangePointer
+
+#define make_atomic_add_body(S) \
+ v= IL_EXCHG_ADD ## S (a, v)
+#define make_atomic_swap_body(S) \
+ v= IL_EXCHG ## S (a, v)
+#define make_atomic_load_body(S) \
+ ret= 0; /* avoid compiler warning */ \
+ ret= IL_COMP_EXCHG ## S (a, ret, ret);
+#endif
+/*
+ my_yield_processor (equivalent of x86 PAUSE instruction) should be used
+ to improve performance on hyperthreaded CPUs. Intel recommends to use it in
+ spin loops also on non-HT machines to reduce power consumption (see e.g
+ http://softwarecommunity.intel.com/articles/eng/2004.htm)
+
+ Running benchmarks for spinlocks implemented with InterlockedCompareExchange
+ and YieldProcessor shows that much better performance is achieved by calling
+ YieldProcessor in a loop - that is, yielding longer. On Intel boxes setting
+ loop count in the range 200-300 brought best results.
+ */
+#ifndef YIELD_LOOPS
+#define YIELD_LOOPS 200
+#endif
+
+static __inline int my_yield_processor()
+{
+ int i;
+ for(i=0; i<YIELD_LOOPS; i++)
+ {
+#if (_MSC_VER <= 1310)
+ /* On older compilers YieldProcessor is not available, use inline assembly*/
+ __asm { rep nop }
+#else
+ YieldProcessor();
+#endif
+ }
+ return 1;
+}
+
+#define LF_BACKOFF my_yield_processor()
+#else /* cleanup */
+
+#undef IL_EXCHG_ADD32
+#undef IL_EXCHG_ADD64
+#undef IL_COMP_EXCHG32
+#undef IL_COMP_EXCHG64
+#undef IL_COMP_EXCHGptr
+#undef IL_EXCHG32
+#undef IL_EXCHG64
+#undef IL_EXCHGptr
+
+#endif
diff --git a/include/atomic/nolock.h b/include/atomic/nolock.h
index 10ac17884b6..5a0c41d9078 100644
--- a/include/atomic/nolock.h
+++ b/include/atomic/nolock.h
@@ -1,3 +1,6 @@
+#ifndef ATOMIC_NOLOCK_INCLUDED
+#define ATOMIC_NOLOCK_INCLUDED
+
/* Copyright (C) 2006 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -13,26 +16,46 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#if defined(__i386__) || defined(_M_IX86) || defined(HAVE_GCC_ATOMIC_BUILTINS)
-
-#ifdef MY_ATOMIC_MODE_DUMMY
-# define LOCK ""
-#else
-# define LOCK "lock"
-#endif
+#if defined(__i386__) || defined(_MSC_VER) || defined(__x86_64__) \
+ || defined(HAVE_GCC_ATOMIC_BUILTINS) \
+ || defined(HAVE_SOLARIS_ATOMIC)
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
-#include "gcc_builtins.h"
-#elif __GNUC__
-#include "x86-gcc.h"
-#elif defined(_MSC_VER)
-#include "x86-msvc.h"
+# ifdef MY_ATOMIC_MODE_DUMMY
+# define LOCK_prefix ""
+# else
+# define LOCK_prefix "lock"
+# endif
+/*
+ We choose implementation as follows:
+ ------------------------------------
+ On Windows using Visual C++ the native implementation should be
+ preferrable. When using gcc we prefer the native x86 implementation,
+ we prefer the Solaris implementation before the gcc because of
+ stability preference, we choose gcc implementation if nothing else
+ works on gcc. If neither Visual C++ or gcc we still choose the
+ Solaris implementation on Solaris (mainly for SunStudio compiles.
+*/
+# if defined(_MSV_VER)
+# include "generic-msvc.h"
+# elif __GNUC__
+# if defined(__i386__) || defined(__x86_64__)
+# include "x86-gcc.h"
+# elif defined(HAVE_SOLARIS_ATOMIC)
+# include "solaris.h"
+# elif defined(HAVE_GCC_ATOMIC_BUILTINS)
+# include "gcc_builtins.h"
+# endif
+# elif defined(HAVE_SOLARIS_ATOMIC)
+# include "solaris.h"
+# endif
#endif
-#endif
-
-#ifdef make_atomic_cas_body
-typedef struct { } my_atomic_rwlock_t;
+#if defined(make_atomic_cas_body)
+/*
+ Type not used so minimal size (emptry struct has different size between C
+ and C++, zero-length array is gcc-specific).
+*/
+typedef char my_atomic_rwlock_t __attribute__ ((unused));
#define my_atomic_rwlock_destroy(name)
#define my_atomic_rwlock_init(name)
#define my_atomic_rwlock_rdlock(name)
@@ -42,3 +65,4 @@ typedef struct { } my_atomic_rwlock_t;
#endif
+#endif /* ATOMIC_NOLOCK_INCLUDED */
diff --git a/include/atomic/rwlock.h b/include/atomic/rwlock.h
index 18b77e93d80..a31f8ed6ca1 100644
--- a/include/atomic/rwlock.h
+++ b/include/atomic/rwlock.h
@@ -1,4 +1,7 @@
-/* Copyright (C) 2006 MySQL AB
+#ifndef ATOMIC_RWLOCK_INCLUDED
+#define ATOMIC_RWLOCK_INCLUDED
+
+/* Copyright (C) 2006 MySQL AB, 2009 Sun Microsystems, Inc.
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,7 +16,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-typedef struct {pthread_rwlock_t rw;} my_atomic_rwlock_t;
+#define MY_ATOMIC_MODE_RWLOCKS 1
#ifdef MY_ATOMIC_MODE_DUMMY
/*
@@ -23,6 +26,9 @@ typedef struct {pthread_rwlock_t rw;} my_atomic_rwlock_t;
implementations (another way is to run a UP build on an SMP box).
*/
#warning MY_ATOMIC_MODE_DUMMY and MY_ATOMIC_MODE_RWLOCKS are incompatible
+
+typedef char my_atomic_rwlock_t;
+
#define my_atomic_rwlock_destroy(name)
#define my_atomic_rwlock_init(name)
#define my_atomic_rwlock_rdlock(name)
@@ -30,19 +36,65 @@ typedef struct {pthread_rwlock_t rw;} my_atomic_rwlock_t;
#define my_atomic_rwlock_rdunlock(name)
#define my_atomic_rwlock_wrunlock(name)
#define MY_ATOMIC_MODE "dummy (non-atomic)"
-#else
-#define my_atomic_rwlock_destroy(name) pthread_rwlock_destroy(& (name)->rw)
-#define my_atomic_rwlock_init(name) pthread_rwlock_init(& (name)->rw, 0)
-#define my_atomic_rwlock_rdlock(name) pthread_rwlock_rdlock(& (name)->rw)
-#define my_atomic_rwlock_wrlock(name) pthread_rwlock_wrlock(& (name)->rw)
-#define my_atomic_rwlock_rdunlock(name) pthread_rwlock_unlock(& (name)->rw)
-#define my_atomic_rwlock_wrunlock(name) pthread_rwlock_unlock(& (name)->rw)
-#define MY_ATOMIC_MODE "rwlocks"
+#else /* not MY_ATOMIC_MODE_DUMMY */
+
+typedef struct {pthread_mutex_t rw;} my_atomic_rwlock_t;
+
+#ifndef SAFE_MUTEX
+
+/*
+ we're using read-write lock macros but map them to mutex locks, and they're
+ faster. Still, having semantically rich API we can change the
+ underlying implementation, if necessary.
+*/
+#define my_atomic_rwlock_destroy(name) pthread_mutex_destroy(& (name)->rw)
+#define my_atomic_rwlock_init(name) pthread_mutex_init(& (name)->rw, 0)
+#define my_atomic_rwlock_rdlock(name) pthread_mutex_lock(& (name)->rw)
+#define my_atomic_rwlock_wrlock(name) pthread_mutex_lock(& (name)->rw)
+#define my_atomic_rwlock_rdunlock(name) pthread_mutex_unlock(& (name)->rw)
+#define my_atomic_rwlock_wrunlock(name) pthread_mutex_unlock(& (name)->rw)
+
+#else /* SAFE_MUTEX */
+
+/*
+ SAFE_MUTEX pollutes the compiling name space with macros
+ that alter pthread_mutex_t, pthread_mutex_init, etc.
+ Atomic operations should never use the safe mutex wrappers.
+ Unfortunately, there is no way to have both:
+ - safe mutex macros expanding pthread_mutex_lock to safe_mutex_lock
+ - my_atomic macros expanding to unmodified pthread_mutex_lock
+ inlined in the same compilation unit.
+ So, in case of SAFE_MUTEX, a function call is required.
+ Given that SAFE_MUTEX is a debugging facility,
+ this extra function call is not a performance concern for
+ production builds.
+*/
+C_MODE_START
+extern void plain_pthread_mutex_init(safe_mutex_t *);
+extern void plain_pthread_mutex_destroy(safe_mutex_t *);
+extern void plain_pthread_mutex_lock(safe_mutex_t *);
+extern void plain_pthread_mutex_unlock(safe_mutex_t *);
+C_MODE_END
+
+#define my_atomic_rwlock_destroy(name) plain_pthread_mutex_destroy(&(name)->rw)
+#define my_atomic_rwlock_init(name) plain_pthread_mutex_init(&(name)->rw)
+#define my_atomic_rwlock_rdlock(name) plain_pthread_mutex_lock(&(name)->rw)
+#define my_atomic_rwlock_wrlock(name) plain_pthread_mutex_lock(&(name)->rw)
+#define my_atomic_rwlock_rdunlock(name) plain_pthread_mutex_unlock(&(name)->rw)
+#define my_atomic_rwlock_wrunlock(name) plain_pthread_mutex_unlock(&(name)->rw)
+
+#endif /* SAFE_MUTEX */
+
+#define MY_ATOMIC_MODE "mutex"
+#ifndef MY_ATOMIC_MODE_RWLOCKS
+#define MY_ATOMIC_MODE_RWLOCKS 1
+#endif
#endif
#define make_atomic_add_body(S) int ## S sav; sav= *a; *a+= v; v=sav;
-#define make_atomic_swap_body(S) int ## S sav; sav= *a; *a= v; v=sav;
+#define make_atomic_fas_body(S) int ## S sav; sav= *a; *a= v; v=sav;
#define make_atomic_cas_body(S) if ((ret= (*a == *cmp))) *a= set; else *cmp=*a;
#define make_atomic_load_body(S) ret= *a;
#define make_atomic_store_body(S) *a= v;
+#endif /* ATOMIC_RWLOCK_INCLUDED */
diff --git a/include/atomic/solaris.h b/include/atomic/solaris.h
new file mode 100644
index 00000000000..fc9f369c707
--- /dev/null
+++ b/include/atomic/solaris.h
@@ -0,0 +1,66 @@
+/* Copyright (C) 2008 MySQL AB, 2009 Sun Microsystems, Inc
+
+ 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 */
+
+#ifndef _atomic_h_cleanup_
+#define _atomic_h_cleanup_ "atomic/solaris.h"
+
+#include <atomic.h>
+
+#define MY_ATOMIC_MODE "solaris-atomic"
+
+#define uintptr_t void *
+#define atomic_or_ptr_nv(X,Y) (void *)atomic_or_ulong_nv((volatile ulong_t *)X, Y)
+
+#define make_atomic_cas_body(S) \
+ uint ## S ## _t sav; \
+ sav = atomic_cas_ ## S( \
+ (volatile uint ## S ## _t *)a, \
+ (uint ## S ## _t)*cmp, \
+ (uint ## S ## _t)set); \
+ if (! (ret= (sav == *cmp))) \
+ *cmp= sav;
+
+#define make_atomic_add_body(S) \
+ int ## S nv; /* new value */ \
+ nv= atomic_add_ ## S ## _nv((volatile uint ## S ## _t *)a, v); \
+ v= nv - v
+
+/* ------------------------------------------------------------------------ */
+
+#ifdef MY_ATOMIC_MODE_DUMMY
+
+#define make_atomic_load_body(S) ret= *a
+#define make_atomic_store_body(S) *a= v
+
+#else /* MY_ATOMIC_MODE_DUMMY */
+
+#define make_atomic_load_body(S) \
+ ret= atomic_or_ ## S ## _nv((volatile uint ## S ## _t *)a, 0)
+
+#define make_atomic_store_body(S) \
+ (void) atomic_swap_ ## S((volatile uint ## S ## _t *)a, (uint ## S ## _t)v)
+
+#endif
+
+#define make_atomic_fas_body(S) \
+ v= atomic_swap_ ## S((volatile uint ## S ## _t *)a, (uint ## S ## _t)v)
+
+#else /* cleanup */
+
+#undef uintptr_t
+#undef atomic_or_ptr_nv
+
+#endif
+
diff --git a/include/atomic/x86-gcc.h b/include/atomic/x86-gcc.h
index d79dadbf05e..61b94a48568 100644
--- a/include/atomic/x86-gcc.h
+++ b/include/atomic/x86-gcc.h
@@ -1,3 +1,6 @@
+#ifndef ATOMIC_X86_GCC_INCLUDED
+#define ATOMIC_X86_GCC_INCLUDED
+
/* Copyright (C) 2006 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -19,10 +22,24 @@
architectures support double-word (128-bit) cas.
*/
-#ifdef MY_ATOMIC_NO_XADD
-#define MY_ATOMIC_MODE "gcc-x86" LOCK "-no-xadd"
+/*
+ No special support of 8 and 16 bit operations are implemented here
+ currently.
+*/
+#undef MY_ATOMIC_HAS_8_AND_16
+
+#ifdef __x86_64__
+# ifdef MY_ATOMIC_NO_XADD
+# define MY_ATOMIC_MODE "gcc-amd64" LOCK_prefix "-no-xadd"
+# else
+# define MY_ATOMIC_MODE "gcc-amd64" LOCK_prefix
+# endif
#else
-#define MY_ATOMIC_MODE "gcc-x86" LOCK
+# ifdef MY_ATOMIC_NO_XADD
+# define MY_ATOMIC_MODE "gcc-x86" LOCK_prefix "-no-xadd"
+# else
+# define MY_ATOMIC_MODE "gcc-x86" LOCK_prefix
+# endif
#endif
/* fix -ansi errors while maintaining readability */
@@ -31,28 +48,79 @@
#endif
#ifndef MY_ATOMIC_NO_XADD
-#define make_atomic_add_body(S) \
- asm volatile (LOCK "; xadd %0, %1;" : "+r" (v) , "+m" (*a))
+#define make_atomic_add_body(S) make_atomic_add_body ## S
+#define make_atomic_cas_body(S) make_atomic_cas_body ## S
#endif
-#define make_atomic_swap_body(S) \
- asm volatile ("; xchg %0, %1;" : "+r" (v) , "+m" (*a))
-#define make_atomic_cas_body(S) \
- asm volatile (LOCK "; cmpxchg %3, %0; setz %2;" \
+
+#define make_atomic_add_body32 \
+ asm volatile (LOCK_prefix "; xadd %0, %1;" : "+r" (v) , "+m" (*a))
+
+#define make_atomic_cas_body32 \
+ asm volatile (LOCK_prefix "; cmpxchg %3, %0; setz %2;" \
: "+m" (*a), "+a" (*cmp), "=q" (ret): "r" (set))
-#ifdef MY_ATOMIC_MODE_DUMMY
-#define make_atomic_load_body(S) ret=*a
-#define make_atomic_store_body(S) *a=v
-#else
+#ifdef __x86_64__
+#define make_atomic_add_body64 make_atomic_add_body32
+#define make_atomic_cas_body64 make_atomic_cas_body32
+
+#define make_atomic_fas_body(S) \
+ asm volatile ("xchg %0, %1;" : "+r" (v) , "+m" (*a))
+
/*
Actually 32-bit reads/writes are always atomic on x86
- But we add LOCK here anyway to force memory barriers
+ But we add LOCK_prefix here anyway to force memory barriers
*/
-#define make_atomic_load_body(S) \
- ret=0; \
- asm volatile (LOCK "; cmpxchg %2, %0" \
- : "+m" (*a), "+a" (ret): "r" (ret))
-#define make_atomic_store_body(S) \
- asm volatile ("; xchg %0, %1;" : "+m" (*a) : "r" (v))
+#define make_atomic_load_body(S) \
+ ret=0; \
+ asm volatile (LOCK_prefix "; cmpxchg %2, %0" \
+ : "+m" (*a), "+a" (ret): "r" (ret))
+#define make_atomic_store_body(S) \
+ asm volatile ("; xchg %0, %1;" : "+m" (*a), "+r" (v))
+
+#else
+/*
+ Use default implementations of 64-bit operations since we solved
+ the 64-bit problem on 32-bit platforms for CAS, no need to solve it
+ once more for ADD, LOAD, STORE and FAS as well.
+ Since we already added add32 support, we need to define add64
+ here, but we haven't defined fas, load and store at all, so
+ we can fallback on default implementations.
+*/
+#define make_atomic_add_body64 \
+ int64 tmp=*a; \
+ while (!my_atomic_cas64(a, &tmp, tmp+v)) ; \
+ v=tmp;
+
+/*
+ On some platforms (e.g. Mac OS X and Solaris) the ebx register
+ is held as a pointer to the global offset table. Thus we're not
+ allowed to use the b-register on those platforms when compiling
+ PIC code, to avoid this we push ebx and pop ebx and add a movl
+ instruction to avoid having ebx in the interface of the assembler
+ instruction.
+
+ cmpxchg8b works on both 32-bit platforms and 64-bit platforms but
+ the code here is only used on 32-bit platforms, on 64-bit
+ platforms the much simpler make_atomic_cas_body32 will work
+ fine.
+*/
+#define make_atomic_cas_body64 \
+ int32 ebx=(set & 0xFFFFFFFF), ecx=(set >> 32); \
+ asm volatile ("push %%ebx; movl %3, %%ebx;" \
+ LOCK_prefix "; cmpxchg8b %0; setz %2; pop %%ebx"\
+ : "+m" (*a), "+A" (*cmp), "=c" (ret) \
+ :"m" (ebx), "c" (ecx))
#endif
+/*
+ The implementation of make_atomic_cas_body32 is adaptable to
+ the OS word size, so on 64-bit platforms it will automatically
+ adapt to 64-bits and so it will work also on 64-bit platforms
+*/
+#define make_atomic_cas_bodyptr make_atomic_cas_body32
+
+#ifdef MY_ATOMIC_MODE_DUMMY
+#define make_atomic_load_body(S) ret=*a
+#define make_atomic_store_body(S) *a=v
+#endif
+#endif /* ATOMIC_X86_GCC_INCLUDED */
diff --git a/include/atomic/x86-msvc.h b/include/atomic/x86-msvc.h
deleted file mode 100644
index c4885bb8451..00000000000
--- a/include/atomic/x86-msvc.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Copyright (C) 2006 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 */
-
-/*
- XXX 64-bit atomic operations can be implemented using
- cmpxchg8b, if necessary
-*/
-
-// Would it be better to use intrinsics ?
-// (InterlockedCompareExchange, InterlockedCompareExchange16
-// InterlockedExchangeAdd, InterlockedExchange)
-
-#ifndef _atomic_h_cleanup_
-#define _atomic_h_cleanup_ "atomic/x86-msvc.h"
-
-#define MY_ATOMIC_MODE "msvc-x86" LOCK
-
-#define make_atomic_add_body(S) \
- _asm { \
- _asm mov reg_ ## S, v \
- _asm LOCK xadd *a, reg_ ## S \
- _asm movzx v, reg_ ## S \
- }
-#define make_atomic_cas_body(S) \
- _asm { \
- _asm mov areg_ ## S, *cmp \
- _asm mov reg2_ ## S, set \
- _asm LOCK cmpxchg *a, reg2_ ## S \
- _asm mov *cmp, areg_ ## S \
- _asm setz al \
- _asm movzx ret, al \
- }
-#define make_atomic_swap_body(S) \
- _asm { \
- _asm mov reg_ ## S, v \
- _asm xchg *a, reg_ ## S \
- _asm mov v, reg_ ## S \
- }
-
-#ifdef MY_ATOMIC_MODE_DUMMY
-#define make_atomic_load_body(S) ret=*a
-#define make_atomic_store_body(S) *a=v
-#else
-/*
- Actually 32-bit reads/writes are always atomic on x86
- But we add LOCK here anyway to force memory barriers
-*/
-#define make_atomic_load_body(S) \
- _asm { \
- _asm mov areg_ ## S, 0 \
- _asm mov reg2_ ## S, areg_ ## S \
- _asm LOCK cmpxchg *a, reg2_ ## S \
- _asm mov ret, areg_ ## S \
- }
-#define make_atomic_store_body(S) \
- _asm { \
- _asm mov reg_ ## S, v \
- _asm xchg *a, reg_ ## S \
- }
-#endif
-
-#define reg_8 al
-#define reg_16 ax
-#define reg_32 eax
-#define areg_8 al
-#define areg_16 ax
-#define areg_32 eax
-#define reg2_8 bl
-#define reg2_16 bx
-#define reg2_32 ebx
-
-#else /* cleanup */
-
-#undef reg_8
-#undef reg_16
-#undef reg_32
-#undef areg_8
-#undef areg_16
-#undef areg_32
-#undef reg2_8
-#undef reg2_16
-#undef reg2_32
-#endif
-
diff --git a/include/config-netware.h b/include/config-netware.h
index 4b9e1437170..a4465ea177a 100644
--- a/include/config-netware.h
+++ b/include/config-netware.h
@@ -73,7 +73,6 @@ extern "C" {
#undef HAVE_FINITE
#undef HAVE_GETPWNAM
#undef HAVE_GETPWUID
-#undef HAVE_PTHREAD_SETSCHEDPARAM
#undef HAVE_READLINK
#undef HAVE_STPCPY
/* changes end */
@@ -101,7 +100,7 @@ extern "C" {
#define USE_OLD_FUNCTIONS 1
/* no case sensitivity */
-#define FN_NO_CASE_SENCE 1
+#define FN_NO_CASE_SENSE 1
/* the thread alarm is not used */
#define DONT_USE_THR_ALARM 1
diff --git a/include/config-win.h b/include/config-win.h
index da9b1fc00c3..269ec0e925a 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -1,3 +1,6 @@
+#ifndef CONFIG_WIN_INCLUDED
+#define CONFIG_WIN_INCLUDED
+
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
@@ -17,6 +20,13 @@
#define BIG_TABLES
+/*
+ Minimal version of Windows we should be able to run on.
+ Currently Windows XP.
+*/
+#define _WIN32_WINNT 0x0501
+
+
#if defined(_MSC_VER) && _MSC_VER >= 1400
/* Avoid endless warnings about sprintf() etc. being unsafe. */
#define _CRT_SECURE_NO_DEPRECATE 1
@@ -24,9 +34,13 @@
#include <sys/locking.h>
#include <winsock2.h>
+#include <Ws2tcpip.h>
#include <fcntl.h>
#include <io.h>
#include <malloc.h>
+#include <sys/stat.h>
+#include <process.h> /* getpid()*/
+
#define HAVE_SMEM 1
@@ -65,7 +79,6 @@
#endif
/* File and lock constants */
-#define O_SHARE 0x1000 /* Open file in sharing mode */
#ifdef __BORLANDC__
#define F_RDLCK LK_NBLCK /* read lock */
#define F_WRLCK LK_NBRLCK /* write lock */
@@ -83,6 +96,12 @@
#define S_IROTH S_IREAD /* for my_lib */
+/* Winsock2 constant (Vista SDK and later)*/
+#define IPPROTO_IPV6 41
+#ifndef IPV6_V6ONLY
+#define IPV6_V6ONLY 27
+#endif
+
#ifdef __BORLANDC__
#define FILE_BINARY O_BINARY /* my_fopen in binary mode */
#define O_TEMPORARY 0
@@ -140,10 +159,21 @@ typedef __int64 os_off_t;
#ifdef _WIN64
typedef UINT_PTR rf_SetTimer;
#else
+typedef uint rf_SetTimer;
+#endif
+
#ifndef HAVE_SIZE_T
-typedef unsigned int size_t;
+#ifndef _SIZE_T_DEFINED
+typedef SIZE_T size_t;
+#define _SIZE_T_DEFINED
+#endif
+#endif
+
+#ifndef HAVE_SSIZE_T
+#ifndef _SSIZE_T_DEFINED
+typedef SSIZE_T ssize_t;
+#define _SSIZE_T_DEFINED
#endif
-typedef uint rf_SetTimer;
#endif
#define Socket_defined
@@ -175,7 +205,7 @@ typedef uint rf_SetTimer;
#define SIZEOF_CHARP 4
#endif
#define HAVE_BROKEN_NETINET_INCLUDES
-#ifdef __NT__
+#ifdef _WIN32
#define HAVE_NAMED_PIPE /* We can only create pipes on NT */
#endif
@@ -288,15 +318,11 @@ inline ulonglong double2ulonglong(double d)
#define strcasecmp stricmp
#define strncasecmp strnicmp
-#ifndef __NT__
-#undef FILE_SHARE_DELETE
-#define FILE_SHARE_DELETE 0 /* Not implemented on Win 98/ME */
-#endif
+#define HAVE_SNPRINTF 1
+#define snprintf _snprintf
-#ifdef NOT_USED
-#define HAVE_SNPRINTF /* Gave link error */
-#define _snprintf snprintf
-#endif
+#define HAVE_SETENV 1
+#define setenv(VAR,VAL,X) _putenv_s(VAR,VAL)
#ifdef _MSC_VER
#define HAVE_LDIV /* The optimizer breaks in zortech for ldiv */
@@ -335,14 +361,14 @@ inline ulonglong double2ulonglong(double d)
#define FN_ROOTDIR "\\"
#define FN_DEVCHAR ':'
#define FN_NETWORK_DRIVES /* Uses \\ to indicate network drives */
-#define FN_NO_CASE_SENCE /* Files are not case-sensitive */
-#define OS_FILE_LIMIT 2048
+#define FN_NO_CASE_SENSE /* Files are not case-sensitive */
+#define OS_FILE_LIMIT UINT_MAX /* No limit*/
#define DO_NOT_REMOVE_THREAD_WRAPPERS
#define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V))
#define thread_safe_decrement(V,L) InterlockedDecrement((long*) &(V))
/* The following is only used for statistics, so it should be good enough */
-#ifdef __NT__ /* This should also work on Win98 but .. */
+#ifdef _WIN32
#define thread_safe_add(V,C,L) InterlockedExchangeAdd((long*) &(V),(C))
#define thread_safe_sub(V,C,L) InterlockedExchangeAdd((long*) &(V),-(long) (C))
#endif
@@ -356,7 +382,6 @@ inline ulonglong double2ulonglong(double d)
#define HAVE_OPENSSL 1
#define HAVE_YASSL 1
-#define COMMUNITY_SERVER 1
#define ENABLED_PROFILING 1
/*
@@ -407,6 +432,11 @@ inline ulonglong double2ulonglong(double d)
#define HAVE_CHARSET_ucs2 1
#define HAVE_CHARSET_ujis 1
#define HAVE_CHARSET_utf8 1
+#define HAVE_CHARSET_utf8mb4 1
+#define HAVE_CHARSET_utf16 1
+#define HAVE_CHARSET_utf32 1
#define HAVE_UCA_COLLATIONS 1
#define HAVE_BOOL 1
+
+#endif /* CONFIG_WIN_INCLUDED */
diff --git a/include/errmsg.h b/include/errmsg.h
index a6d8c770de8..c55c94af169 100644
--- a/include/errmsg.h
+++ b/include/errmsg.h
@@ -1,3 +1,6 @@
+#ifndef ERRMSG_INCLUDED
+#define ERRMSG_INCLUDED
+
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -97,6 +100,8 @@ extern const char *client_errors[]; /* Error messages */
#define CR_SERVER_LOST_EXTENDED 2055
#define CR_STMT_CLOSED 2056
#define CR_NEW_STMT_METADATA 2057
-#define CR_ERROR_LAST /*Copy last error nr:*/ 2057
+#define CR_ALREADY_CONNECTED 2058
+#define CR_ERROR_LAST /*Copy last error nr:*/ 2058
/* Add error numbers before CR_ERROR_LAST and change it accordingly. */
+#endif /* ERRMSG_INCLUDED */
diff --git a/include/ft_global.h b/include/ft_global.h
index 752371d6bc6..ad56bce678b 100644
--- a/include/ft_global.h
+++ b/include/ft_global.h
@@ -28,6 +28,8 @@ extern "C" {
#define HA_FT_MAXBYTELEN 254
#define HA_FT_MAXCHARLEN (HA_FT_MAXBYTELEN/3)
+#define DEFAULT_FTB_SYNTAX "+ -><()~*:\"\"&|"
+
typedef struct st_ft_info FT_INFO;
struct _ft_vft
{
@@ -51,7 +53,7 @@ extern const char *ft_precompiled_stopwords[];
extern ulong ft_min_word_len;
extern ulong ft_max_word_len;
extern ulong ft_query_expansion_limit;
-extern char ft_boolean_syntax[15];
+extern const char *ft_boolean_syntax;
extern struct st_mysql_ftparser ft_default_parser;
int ft_init_stopwords(void);
diff --git a/include/hash.h b/include/hash.h
index 629b404e8a7..7b4ec1b4685 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -17,43 +17,24 @@
#ifndef _hash_h
#define _hash_h
-#ifdef __cplusplus
-extern "C" {
-#endif
+
+#include "my_global.h" /* uchar */
+#include "my_sys.h" /* DYNAMIC_ARRAY */
/*
- There was a problem on MacOSX with a shared object ha_example.so.
- It used hash_search(). During build of ha_example.so no libmysys
- was specified. Since MacOSX had a hash_search() in the system
- library, it built the shared object so that the dynamic linker
- linked hash_search() to the system library, which caused a crash
- when called. To come around this, we renamed hash_search() to
- my_hash_search(), as we did long ago with hash_insert() and
- hash_reset(). However, this time we made the move complete with
- all names. To keep compatibility, we redefine the old names.
- Since every C and C++ file, that uses HASH, needs to include
- this file, the change is complete. Both names could be used
- in the code, but the my_* versions are recommended now.
+ This forward declaration is used from C files where the real
+ definition is included before. Since C does not allow repeated
+ typedef declarations, even when identical, the definition may not be
+ repeated.
*/
-#define hash_get_key my_hash_get_key
-#define hash_free_key my_hash_free_key
-#define hash_init my_hash_init
-#define hash_init2 my_hash_init2
-#define _hash_init _my_hash_init
-#define hash_free my_hash_free
-#define hash_reset my_hash_reset
-#define hash_element my_hash_element
-#define hash_search my_hash_search
-#define hash_first my_hash_first
-#define hash_next my_hash_next
-#define hash_insert my_hash_insert
-#define hash_delete my_hash_delete
-#define hash_update my_hash_update
-#define hash_replace my_hash_replace
-#define hash_check my_hash_check
-#define hash_clear my_hash_clear
-#define hash_inited my_hash_inited
-#define hash_init_opt my_hash_init_opt
+#ifndef CHARSET_INFO_DEFINED
+#define CHARSET_INFO_DEFINED
+typedef struct charset_info_st CHARSET_INFO;
+#endif /* CHARSET_INFO_DEFINED */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
/*
Overhead to store an element in hash
@@ -64,6 +45,7 @@ extern "C" {
/* flags for hash_init */
#define HASH_UNIQUE 1 /* hash_insert fails on duplicate key */
+typedef uint my_hash_value_type;
typedef uchar *(*my_hash_get_key)(const uchar *,size_t*,my_bool);
typedef void (*my_hash_free_key)(void *);
@@ -94,8 +76,18 @@ void my_hash_free(HASH *tree);
void my_hash_reset(HASH *hash);
uchar *my_hash_element(HASH *hash, ulong idx);
uchar *my_hash_search(const HASH *info, const uchar *key, size_t length);
+uchar *my_hash_search_using_hash_value(const HASH *info,
+ my_hash_value_type hash_value,
+ const uchar *key, size_t length);
+my_hash_value_type my_calc_hash(const HASH *info,
+ const uchar *key, size_t length);
uchar *my_hash_first(const HASH *info, const uchar *key, size_t length,
HASH_SEARCH_STATE *state);
+uchar *my_hash_first_from_hash_value(const HASH *info,
+ my_hash_value_type hash_value,
+ const uchar *key,
+ size_t length,
+ HASH_SEARCH_STATE *state);
uchar *my_hash_next(const HASH *info, const uchar *key, size_t length,
HASH_SEARCH_STATE *state);
my_bool my_hash_insert(HASH *info, const uchar *data);
diff --git a/include/heap.h b/include/heap.h
index 4a1c7d419ed..27aefb5beda 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000,2004 MySQL AB
+/* Copyright (C) 2000-2004 MySQL AB, 2009 Sun Microsystems, Inc
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
@@ -148,7 +148,7 @@ typedef struct st_heap_share
char * name; /* Name of "memory-file" */
#ifdef THREAD
THR_LOCK lock;
- pthread_mutex_t intern_lock; /* Locking for use with _locking */
+ mysql_mutex_t intern_lock; /* Locking for use with _locking */
#endif
my_bool delete_on_close;
LIST open_list;
diff --git a/include/help_end.h b/include/help_end.h
index 4426cb80bce..92953efe35a 100644
--- a/include/help_end.h
+++ b/include/help_end.h
@@ -1,3 +1,6 @@
+#ifndef HELP_END_INCLUDED
+#define HELP_END_INCLUDED
+
/* Copyright (C) 2004-2005 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -20,3 +23,4 @@
#undef fputc
#undef putchar
#endif
+#endif /* HELP_END_INCLUDED */
diff --git a/include/help_start.h b/include/help_start.h
index 3ae20eea7d7..414f7ec93a0 100644
--- a/include/help_start.h
+++ b/include/help_start.h
@@ -1,3 +1,6 @@
+#ifndef HELP_START_INCLUDED
+#define HELP_START_INCLUDED
+
/* Copyright (C) 2004-2005 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -22,3 +25,4 @@
#define fputc(s,f) consoleprintf("%c", s)
#define putchar(s) consoleprintf("%c", s)
#endif
+#endif /* HELP_START_INCLUDED */
diff --git a/include/keycache.h b/include/keycache.h
index a6005bae878..fefa31afd87 100644
--- a/include/keycache.h
+++ b/include/keycache.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 MySQL AB
+/* Copyright (C) 2003 MySQL AB, 2009 Sun Microsystems, Inc
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
@@ -17,6 +17,9 @@
#ifndef _keycache_h
#define _keycache_h
+
+#include "my_sys.h" /* flush_type */
+
C_MODE_START
/* declare structures that is used by st_key_cache */
@@ -67,10 +70,10 @@ typedef struct st_key_cache
HASH_LINK *free_hash_list; /* list of free hash links */
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
@@ -87,10 +90,10 @@ typedef struct st_key_cache
initializing the key cache.
*/
- ulonglong param_buff_size; /* size the memory allocated for the cache */
- ulong param_block_size; /* size of the blocks in the key cache */
- ulong param_division_limit; /* min. percentage of warm blocks */
- ulong param_age_threshold; /* determines when hot block is downgraded */
+ ulonglong param_buff_size; /* size the memory allocated for the cache */
+ ulonglong param_block_size; /* size of the blocks in the key cache */
+ ulonglong param_division_limit; /* min. percentage of warm blocks */
+ ulonglong param_age_threshold; /* determines when hot block is downgraded */
/* Statistics variables. These are reset in reset_key_cache_counters(). */
ulong global_blocks_changed; /* number of currently dirty blocks */
diff --git a/include/lf.h b/include/lf.h
new file mode 100644
index 00000000000..7e8f05f4ada
--- /dev/null
+++ b/include/lf.h
@@ -0,0 +1,268 @@
+/* Copyright (C) 2007-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+
+ 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 */
+
+#ifndef _lf_h
+#define _lf_h
+
+#include <my_atomic.h>
+
+C_MODE_START
+
+/*
+ Helpers to define both func() and _func(), where
+ func() is a _func() protected by my_atomic_rwlock_wrlock()
+*/
+
+#define lock_wrap(f, t, proto_args, args, lock) \
+t _ ## f proto_args; \
+static inline t f proto_args \
+{ \
+ t ret; \
+ my_atomic_rwlock_wrlock(lock); \
+ ret= _ ## f args; \
+ my_atomic_rwlock_wrunlock(lock); \
+ return ret; \
+}
+
+#define lock_wrap_void(f, proto_args, args, lock) \
+void _ ## f proto_args; \
+static inline void f proto_args \
+{ \
+ my_atomic_rwlock_wrlock(lock); \
+ _ ## f args; \
+ my_atomic_rwlock_wrunlock(lock); \
+}
+
+#define nolock_wrap(f, t, proto_args, args) \
+t _ ## f proto_args; \
+static inline t f proto_args \
+{ \
+ return _ ## f args; \
+}
+
+#define nolock_wrap_void(f, proto_args, args) \
+void _ ## f proto_args; \
+static inline void f proto_args \
+{ \
+ _ ## f args; \
+}
+
+/*
+ wait-free dynamic array, see lf_dynarray.c
+
+ 4 levels of 256 elements each mean 4311810304 elements in an array - it
+ should be enough for a while
+*/
+#define LF_DYNARRAY_LEVEL_LENGTH 256
+#define LF_DYNARRAY_LEVELS 4
+
+typedef struct {
+ void * volatile level[LF_DYNARRAY_LEVELS];
+ uint size_of_element;
+ my_atomic_rwlock_t lock;
+} LF_DYNARRAY;
+
+typedef int (*lf_dynarray_func)(void *, void *);
+
+void lf_dynarray_init(LF_DYNARRAY *array, uint element_size);
+void lf_dynarray_destroy(LF_DYNARRAY *array);
+
+nolock_wrap(lf_dynarray_value, void *,
+ (LF_DYNARRAY *array, uint idx),
+ (array, idx))
+lock_wrap(lf_dynarray_lvalue, void *,
+ (LF_DYNARRAY *array, uint idx),
+ (array, idx),
+ &array->lock)
+nolock_wrap(lf_dynarray_iterate, int,
+ (LF_DYNARRAY *array, lf_dynarray_func func, void *arg),
+ (array, func, arg))
+
+/*
+ pin manager for memory allocator, lf_alloc-pin.c
+*/
+
+#define LF_PINBOX_PINS 4
+#define LF_PURGATORY_SIZE 10
+
+typedef void lf_pinbox_free_func(void *, void *, void*);
+
+typedef struct {
+ LF_DYNARRAY pinarray;
+ lf_pinbox_free_func *free_func;
+ void *free_func_arg;
+ uint free_ptr_offset;
+ uint32 volatile pinstack_top_ver; /* this is a versioned pointer */
+ uint32 volatile pins_in_array; /* number of elements in array */
+} LF_PINBOX;
+
+typedef struct {
+ void * volatile pin[LF_PINBOX_PINS];
+ LF_PINBOX *pinbox;
+ void **stack_ends_here;
+ void *purgatory;
+ uint32 purgatory_count;
+ uint32 volatile link;
+/* we want sizeof(LF_PINS) to be 64 to avoid false sharing */
+#if SIZEOF_INT*2+SIZEOF_CHARP*(LF_PINBOX_PINS+3) != 64
+ char pad[64-sizeof(uint32)*2-sizeof(void*)*(LF_PINBOX_PINS+3)];
+#endif
+} LF_PINS;
+
+/*
+ shortcut macros to do an atomic_wrlock on a structure that uses pins
+ (e.g. lf_hash).
+*/
+#define lf_rwlock_by_pins(PINS) \
+ my_atomic_rwlock_wrlock(&(PINS)->pinbox->pinarray.lock)
+#define lf_rwunlock_by_pins(PINS) \
+ my_atomic_rwlock_wrunlock(&(PINS)->pinbox->pinarray.lock)
+
+/*
+ compile-time assert, to require "no less than N" pins
+ it's enough if it'll fail on at least one compiler, so
+ we'll enable it on GCC only, which supports zero-length arrays.
+*/
+#if defined(__GNUC__) && defined(MY_LF_EXTRA_DEBUG)
+#define LF_REQUIRE_PINS(N) \
+ static const char require_pins[LF_PINBOX_PINS-N] \
+ __attribute__ ((unused)); \
+ static const int LF_NUM_PINS_IN_THIS_FILE= N;
+#define _lf_pin(PINS, PIN, ADDR) \
+ ( \
+ assert(PIN < LF_NUM_PINS_IN_THIS_FILE), \
+ my_atomic_storeptr(&(PINS)->pin[PIN], (ADDR)) \
+ )
+#else
+#define LF_REQUIRE_PINS(N)
+#define _lf_pin(PINS, PIN, ADDR) my_atomic_storeptr(&(PINS)->pin[PIN], (ADDR))
+#endif
+
+#define _lf_unpin(PINS, PIN) _lf_pin(PINS, PIN, NULL)
+#define lf_pin(PINS, PIN, ADDR) \
+ do { \
+ lf_rwlock_by_pins(PINS); \
+ _lf_pin(PINS, PIN, ADDR); \
+ lf_rwunlock_by_pins(PINS); \
+ } while (0)
+#define lf_unpin(PINS, PIN) lf_pin(PINS, PIN, NULL)
+#define _lf_assert_pin(PINS, PIN) assert((PINS)->pin[PIN] != 0)
+#define _lf_assert_unpin(PINS, PIN) assert((PINS)->pin[PIN] == 0)
+
+void lf_pinbox_init(LF_PINBOX *pinbox, uint free_ptr_offset,
+ lf_pinbox_free_func *free_func, void * free_func_arg);
+void lf_pinbox_destroy(LF_PINBOX *pinbox);
+
+lock_wrap(lf_pinbox_get_pins, LF_PINS *,
+ (LF_PINBOX *pinbox),
+ (pinbox),
+ &pinbox->pinarray.lock)
+lock_wrap_void(lf_pinbox_put_pins,
+ (LF_PINS *pins),
+ (pins),
+ &pins->pinbox->pinarray.lock)
+lock_wrap_void(lf_pinbox_free,
+ (LF_PINS *pins, void *addr),
+ (pins, addr),
+ &pins->pinbox->pinarray.lock)
+
+/*
+ memory allocator, lf_alloc-pin.c
+*/
+
+typedef struct st_lf_allocator {
+ LF_PINBOX pinbox;
+ uchar * volatile top;
+ uint element_size;
+ uint32 volatile mallocs;
+ void (*constructor)(uchar *); /* called, when an object is malloc()'ed */
+ void (*destructor)(uchar *); /* called, when an object is free()'d */
+} LF_ALLOCATOR;
+
+void lf_alloc_init(LF_ALLOCATOR *allocator, uint size, uint free_ptr_offset);
+void lf_alloc_destroy(LF_ALLOCATOR *allocator);
+uint lf_alloc_pool_count(LF_ALLOCATOR *allocator);
+/*
+ shortcut macros to access underlying pinbox functions from an LF_ALLOCATOR
+ see _lf_pinbox_get_pins() and _lf_pinbox_put_pins()
+*/
+#define _lf_alloc_free(PINS, PTR) _lf_pinbox_free((PINS), (PTR))
+#define lf_alloc_free(PINS, PTR) lf_pinbox_free((PINS), (PTR))
+#define _lf_alloc_get_pins(A) _lf_pinbox_get_pins(&(A)->pinbox)
+#define lf_alloc_get_pins(A) lf_pinbox_get_pins(&(A)->pinbox)
+#define _lf_alloc_put_pins(PINS) _lf_pinbox_put_pins(PINS)
+#define lf_alloc_put_pins(PINS) lf_pinbox_put_pins(PINS)
+#define lf_alloc_direct_free(ALLOC, ADDR) my_free((uchar*)(ADDR), MYF(0))
+
+lock_wrap(lf_alloc_new, void *,
+ (LF_PINS *pins),
+ (pins),
+ &pins->pinbox->pinarray.lock)
+
+C_MODE_END
+
+/*
+ extendible hash, lf_hash.c
+*/
+#include <hash.h>
+
+C_MODE_START
+
+#define LF_HASH_UNIQUE 1
+
+/* lf_hash overhead per element (that is, sizeof(LF_SLIST) */
+extern const int LF_HASH_OVERHEAD;
+
+typedef struct {
+ LF_DYNARRAY array; /* hash itself */
+ LF_ALLOCATOR alloc; /* allocator for elements */
+ my_hash_get_key get_key; /* see HASH */
+ CHARSET_INFO *charset; /* see HASH */
+ uint key_offset, key_length; /* see HASH */
+ uint element_size; /* size of memcpy'ed area on insert */
+ uint flags; /* LF_HASH_UNIQUE, etc */
+ int32 volatile size; /* size of array */
+ int32 volatile count; /* number of elements in the hash */
+} LF_HASH;
+
+void lf_hash_init(LF_HASH *hash, uint element_size, uint flags,
+ uint key_offset, uint key_length, my_hash_get_key get_key,
+ CHARSET_INFO *charset);
+void lf_hash_destroy(LF_HASH *hash);
+int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data);
+void *lf_hash_search(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen);
+int lf_hash_delete(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen);
+/*
+ shortcut macros to access underlying pinbox functions from an LF_HASH
+ see _lf_pinbox_get_pins() and _lf_pinbox_put_pins()
+*/
+#define _lf_hash_get_pins(HASH) _lf_alloc_get_pins(&(HASH)->alloc)
+#define lf_hash_get_pins(HASH) lf_alloc_get_pins(&(HASH)->alloc)
+#define _lf_hash_put_pins(PINS) _lf_pinbox_put_pins(PINS)
+#define lf_hash_put_pins(PINS) lf_pinbox_put_pins(PINS)
+#define lf_hash_search_unpin(PINS) lf_unpin((PINS), 2)
+/*
+ cleanup
+*/
+
+#undef lock_wrap_void
+#undef lock_wrap
+#undef nolock_wrap_void
+#undef nolock_wrap
+
+C_MODE_END
+
+#endif
+
diff --git a/include/m_ctype.h b/include/m_ctype.h
index 451c8db549b..06cbfd779c8 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -15,13 +15,13 @@
/*
A better inplementation of the UNIX ctype(3) library.
- Notes: my_global.h should be included before ctype.h
*/
#ifndef _m_ctype_h
#define _m_ctype_h
#include <my_attribute.h>
+#include "my_global.h" /* uint16, uchar */
#ifdef __cplusplus
extern "C" {
@@ -38,11 +38,29 @@ extern "C" {
#define my_wc_t ulong
+#define MY_CS_REPLACEMENT_CHARACTER 0xFFFD
+
+/*
+ On i386 we store Unicode->CS conversion tables for
+ some character sets using Big-endian order,
+ to copy two bytes at onces.
+ This gives some performance improvement.
+*/
+#ifdef __i386__
+#define MB2(x) (((x) >> 8) + (((x) & 0xFF) << 8))
+#define MY_PUT_MB2(s, code) { *((uint16*)(s))= (code); }
+#else
+#define MB2(x) (x)
+#define MY_PUT_MB2(s, code) { (s)[0]= code >> 8; (s)[1]= code & 0xFF; }
+#endif
+
+
+
typedef struct unicase_info_st
{
- uint16 toupper;
- uint16 tolower;
- uint16 sort;
+ uint32 toupper;
+ uint32 tolower;
+ uint32 sort;
} MY_UNICASE_INFO;
@@ -81,12 +99,14 @@ extern MY_UNI_CTYPE my_uni_ctype[256];
#define MY_CS_BINSORT 16 /* if binary sort order */
#define MY_CS_PRIMARY 32 /* if primary collation */
#define MY_CS_STRNXFRM 64 /* if strnxfrm is used for sort */
-#define MY_CS_UNICODE 128 /* is a charset is full unicode */
+#define MY_CS_UNICODE 128 /* is a charset is BMP Unicode */
#define MY_CS_READY 256 /* if a charset is initialized */
#define MY_CS_AVAILABLE 512 /* If either compiled-in or loaded*/
#define MY_CS_CSSORT 1024 /* if case sensitive sort order */
#define MY_CS_HIDDEN 2048 /* don't display in SHOW */
#define MY_CS_PUREASCII 4096 /* if a charset is pure ascii */
+#define MY_CS_NONASCII 8192 /* if not ASCII-compatible */
+#define MY_CS_UNICODE_SUPPLEMENT 16384 /* Non-BMP Unicode characters */
#define MY_CHARSET_UNDEFINED 0
/* Character repertoire flags */
@@ -94,7 +114,6 @@ extern MY_UNI_CTYPE my_uni_ctype[256];
#define MY_REPERTOIRE_EXTENDED 2 /* Extended characters: U+0080..U+FFFF */
#define MY_REPERTOIRE_UNICODE30 3 /* ASCII | EXTENDED: U+0000..U+FFFF */
-
typedef struct my_uni_idx_st
{
uint16 from;
@@ -246,6 +265,12 @@ extern MY_CHARSET_HANDLER my_charset_8bit_handler;
extern MY_CHARSET_HANDLER my_charset_ucs2_handler;
+/*
+ We define this CHARSET_INFO_DEFINED here to prevent a repeat of the
+ typedef in hash.c, which will cause a compiler error.
+*/
+#define CHARSET_INFO_DEFINED
+
/* See strings/CHARSET_INFO.txt about information on this structure */
typedef struct charset_info_st
{
@@ -286,10 +311,14 @@ typedef struct charset_info_st
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_bin;
+extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_latin1;
+extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_filename;
+
extern CHARSET_INFO my_charset_big5_chinese_ci;
extern CHARSET_INFO my_charset_big5_bin;
extern CHARSET_INFO my_charset_cp932_japanese_ci;
extern CHARSET_INFO my_charset_cp932_bin;
+extern CHARSET_INFO my_charset_cp1250_czech_ci;
extern CHARSET_INFO my_charset_eucjpms_japanese_ci;
extern CHARSET_INFO my_charset_eucjpms_bin;
extern CHARSET_INFO my_charset_euckr_korean_ci;
@@ -298,7 +327,6 @@ extern CHARSET_INFO my_charset_gb2312_chinese_ci;
extern CHARSET_INFO my_charset_gb2312_bin;
extern CHARSET_INFO my_charset_gbk_chinese_ci;
extern CHARSET_INFO my_charset_gbk_bin;
-extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_latin1;
extern CHARSET_INFO my_charset_latin1_german2_ci;
extern CHARSET_INFO my_charset_latin1_bin;
extern CHARSET_INFO my_charset_latin2_czech_ci;
@@ -311,11 +339,22 @@ extern CHARSET_INFO my_charset_ucs2_bin;
extern CHARSET_INFO my_charset_ucs2_unicode_ci;
extern CHARSET_INFO my_charset_ujis_japanese_ci;
extern CHARSET_INFO my_charset_ujis_bin;
+extern CHARSET_INFO my_charset_utf16_bin;
+extern CHARSET_INFO my_charset_utf16_general_ci;
+extern CHARSET_INFO my_charset_utf16_unicode_ci;
+extern CHARSET_INFO my_charset_utf32_bin;
+extern CHARSET_INFO my_charset_utf32_general_ci;
+extern CHARSET_INFO my_charset_utf32_unicode_ci;
+
extern CHARSET_INFO my_charset_utf8_general_ci;
extern CHARSET_INFO my_charset_utf8_unicode_ci;
extern CHARSET_INFO my_charset_utf8_bin;
-extern CHARSET_INFO my_charset_cp1250_czech_ci;
-extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_filename;
+extern CHARSET_INFO my_charset_utf8mb4_bin;
+extern CHARSET_INFO my_charset_utf8mb4_general_ci;
+extern CHARSET_INFO my_charset_utf8mb4_unicode_ci;
+#define MY_UTF8MB3 "utf8"
+#define MY_UTF8MB4 "utf8mb4"
+
/* declarations for simple charsets */
extern size_t my_strnxfrm_simple(CHARSET_INFO *, uchar *, size_t,
@@ -412,6 +451,19 @@ my_bool my_like_range_ucs2(CHARSET_INFO *cs,
char *min_str, char *max_str,
size_t *min_length, size_t *max_length);
+my_bool my_like_range_utf16(CHARSET_INFO *cs,
+ const char *ptr, size_t ptr_length,
+ pbool escape, pbool w_one, pbool w_many,
+ size_t res_length,
+ char *min_str, char *max_str,
+ size_t *min_length, size_t *max_length);
+
+my_bool my_like_range_utf32(CHARSET_INFO *cs,
+ const char *ptr, size_t ptr_length,
+ pbool escape, pbool w_one, pbool w_many,
+ size_t res_length,
+ char *min_str, char *max_str,
+ size_t *min_length, size_t *max_length);
int my_wildcmp_8bit(CHARSET_INFO *,
const char *str,const char *str_end,
@@ -438,6 +490,14 @@ extern size_t my_caseup_mb(CHARSET_INFO *, char *src, size_t srclen,
char *dst, size_t dstlen);
extern size_t my_casedn_mb(CHARSET_INFO *, char *src, size_t srclen,
char *dst, size_t dstlen);
+extern size_t my_caseup_mb_varlen(CHARSET_INFO *, char *src, size_t srclen,
+ char *dst, size_t dstlen);
+extern size_t my_casedn_mb_varlen(CHARSET_INFO *, char *src, size_t srclen,
+ char *dst, size_t dstlen);
+extern size_t my_caseup_ujis(CHARSET_INFO *, char *src, size_t srclen,
+ char *dst, size_t dstlen);
+extern size_t my_casedn_ujis(CHARSET_INFO *, char *src, size_t srclen,
+ char *dst, size_t dstlen);
extern int my_strcasecmp_mb(CHARSET_INFO * cs,const char *, const char *);
int my_wildcmp_mb(CHARSET_INFO *,
@@ -454,6 +514,31 @@ uint my_instr_mb(struct charset_info_st *,
const char *s, size_t s_length,
my_match_t *match, uint nmatch);
+int my_strnncoll_mb_bin(CHARSET_INFO * cs,
+ const uchar *s, size_t slen,
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix);
+
+int my_strnncollsp_mb_bin(CHARSET_INFO *cs,
+ const uchar *a, size_t a_length,
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference);
+
+int my_wildcmp_mb_bin(CHARSET_INFO *cs,
+ const char *str,const char *str_end,
+ const char *wildstr,const char *wildend,
+ int escape, int w_one, int w_many);
+
+int my_strcasecmp_mb_bin(CHARSET_INFO * cs __attribute__((unused)),
+ const char *s, const char *t);
+
+void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
+ const uchar *key, size_t len,ulong *nr1, ulong *nr2);
+
+size_t my_strnxfrm_unicode(CHARSET_INFO *,
+ uchar *dst, size_t dstlen,
+ const uchar *src, size_t srclen);
+
int my_wildcmp_unicode(CHARSET_INFO *cs,
const char *str, const char *str_end,
const char *wildstr, const char *wildend,
@@ -474,6 +559,10 @@ my_bool my_charset_is_ascii_based(CHARSET_INFO *cs);
my_bool my_charset_is_8bit_pure_ascii(CHARSET_INFO *cs);
uint my_charset_repertoire(CHARSET_INFO *cs);
+my_bool my_charset_is_ascii_compatible(CHARSET_INFO *cs);
+
+extern size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
+ const char* fmt, va_list ap);
#define _MY_U 01 /* Upper case */
#define _MY_L 02 /* Lower case */
diff --git a/include/m_string.h b/include/m_string.h
index a25675f2638..7bd39e7483f 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -20,6 +20,9 @@
#ifndef _m_string_h
#define _m_string_h
+
+#include "my_global.h" /* HAVE_* */
+
#ifndef __USE_GNU
#define __USE_GNU /* We want to use stpcpy */
#endif
@@ -92,9 +95,6 @@ extern char *stpcpy(char *, const char *); /* For AIX with gcc 2.95.3 */
extern char NEAR _dig_vec_upper[];
extern char NEAR _dig_vec_lower[];
-/* Defined in strtod.c */
-extern const double log_10[309];
-
#ifndef strmov
#define strmov_overlapp(A,B) strmov(A,B)
#define strmake_overlapp(A,B,C) strmake(A,B,C)
@@ -196,8 +196,42 @@ extern char *strstr(const char *, const char *);
extern int is_prefix(const char *, const char *);
/* Conversion routines */
+typedef enum {
+ MY_GCVT_ARG_FLOAT,
+ MY_GCVT_ARG_DOUBLE
+} my_gcvt_arg_type;
+
double my_strtod(const char *str, char **end, int *error);
double my_atof(const char *nptr);
+size_t my_fcvt(double x, int precision, char *to, my_bool *error);
+size_t my_gcvt(double x, my_gcvt_arg_type type, int width, char *to,
+ my_bool *error);
+
+#define NOT_FIXED_DEC 31
+
+/*
+ The longest string my_fcvt can return is 311 + "precision" bytes.
+ Here we assume that we never cal my_fcvt() with precision >= NOT_FIXED_DEC
+ (+ 1 byte for the terminating '\0').
+*/
+#define FLOATING_POINT_BUFFER (311 + NOT_FIXED_DEC)
+
+/*
+ We want to use the 'e' format in some cases even if we have enough space
+ for the 'f' one just to mimic sprintf("%.15g") behavior for large integers,
+ and to improve it for numbers < 10^(-4).
+ That is, for |x| < 1 we require |x| >= 10^(-15), and for |x| > 1 we require
+ it to be integer and be <= 10^DBL_DIG for the 'f' format to be used.
+ We don't lose precision, but make cases like "1e200" or "0.00001" look nicer.
+*/
+#define MAX_DECPT_FOR_F_FORMAT DBL_DIG
+
+/*
+ The maximum possible field width for my_gcvt() conversion.
+ (DBL_DIG + 2) significant digits + sign + "." + ("e-NNN" or
+ MAX_DECPT_FOR_F_FORMAT zeros for cases when |x|<1 and the 'f' format is used).
+*/
+#define MY_GCVT_MAX_FIELD_WIDTH (DBL_DIG + 4 + max(5, MAX_DECPT_FOR_F_FORMAT)) \
extern char *llstr(longlong value,char *buff);
extern char *ullstr(longlong value,char *buff);
@@ -212,7 +246,7 @@ extern char *str2int(const char *src,int radix,long lower,long upper,
long *val);
longlong my_strtoll10(const char *nptr, char **endptr, int *error);
#if SIZEOF_LONG == SIZEOF_LONG_LONG
-#define longlong2str(A,B,C) int2str((A),(B),(C),1)
+#define ll2str(A,B,C,D) int2str((A),(B),(C),(D))
#define longlong10_to_str(A,B,C) int10_to_str((A),(B),(C))
#undef strtoll
#define strtoll(A,B,C) strtol((A),(B),(C))
@@ -225,7 +259,7 @@ longlong my_strtoll10(const char *nptr, char **endptr, int *error);
#endif
#else
#ifdef HAVE_LONG_LONG
-extern char *longlong2str(longlong val,char *dst,int radix);
+extern char *ll2str(longlong val,char *dst,int radix, int upcase);
extern char *longlong10_to_str(longlong val,char *dst,int radix);
#if (!defined(HAVE_STRTOULL) || defined(NO_STRTOLL_PROTO))
extern longlong strtoll(const char *str, char **ptr, int base);
@@ -233,13 +267,7 @@ extern ulonglong strtoull(const char *str, char **ptr, int base);
#endif
#endif
#endif
-
-/* my_vsnprintf.c */
-
-extern size_t my_vsnprintf(char *str, size_t n,
- const char *format, va_list ap);
-extern size_t my_snprintf(char *to, size_t n, const char *fmt, ...)
- ATTRIBUTE_FORMAT(printf, 3, 4);
+#define longlong2str(A,B,C) ll2str((A),(B),(C),1)
#if defined(__cplusplus)
}
@@ -247,20 +275,96 @@ extern size_t my_snprintf(char *to, size_t n, const char *fmt, ...)
/*
LEX_STRING -- a pair of a C-string and its length.
+ (it's part of the plugin API as a MYSQL_LEX_STRING)
*/
-#ifndef _my_plugin_h
-/* This definition must match the one given in mysql/plugin.h */
-struct st_mysql_lex_string
-{
- char *str;
- size_t length;
-};
-#endif
+#include <mysql/plugin.h>
typedef struct st_mysql_lex_string LEX_STRING;
#define STRING_WITH_LEN(X) (X), ((size_t) (sizeof(X) - 1))
#define USTRING_WITH_LEN(X) ((uchar*) X), ((size_t) (sizeof(X) - 1))
#define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
+struct st_mysql_const_lex_string
+{
+ const char *str;
+ size_t length;
+};
+typedef struct st_mysql_const_lex_string LEX_CSTRING;
+
+/* SPACE_INT is a word that contains only spaces */
+#if SIZEOF_INT == 4
+#define SPACE_INT 0x20202020
+#elif SIZEOF_INT == 8
+#define SPACE_INT 0x2020202020202020
+#else
+#error define the appropriate constant for a word full of spaces
+#endif
+
+/**
+ Skip trailing space.
+
+ On most systems reading memory in larger chunks (ideally equal to the size of
+ the chinks that the machine physically reads from memory) causes fewer memory
+ access loops and hence increased performance.
+ This is why the 'int' type is used : it's closest to that (according to how
+ it's defined in C).
+ So when we determine the amount of whitespace at the end of a string we do
+ the following :
+ 1. We divide the string into 3 zones :
+ a) from the start of the string (__start) to the first multiple
+ of sizeof(int) (__start_words)
+ b) from the end of the string (__end) to the last multiple of sizeof(int)
+ (__end_words)
+ c) a zone that is aligned to sizeof(int) and can be safely accessed
+ through an int *
+ 2. We start comparing backwards from (c) char-by-char. If all we find is
+ space then we continue
+ 3. If there are elements in zone (b) we compare them as unsigned ints to a
+ int mask (SPACE_INT) consisting of all spaces
+ 4. Finally we compare the remaining part (a) of the string char by char.
+ This covers for the last non-space unsigned int from 3. (if any)
+
+ This algorithm works well for relatively larger strings, but it will slow
+ the things down for smaller strings (because of the additional calculations
+ and checks compared to the naive method). Thus the barrier of length 20
+ is added.
+
+ @param ptr pointer to the input string
+ @param len the length of the string
+ @return the last non-space character
+*/
+
+static inline const uchar *skip_trailing_space(const uchar *ptr,size_t len)
+{
+ const uchar *end= ptr + len;
+
+ if (len > 20)
+ {
+ const uchar *end_words= (const uchar *)(intptr)
+ (((ulonglong)(intptr)end) / SIZEOF_INT * SIZEOF_INT);
+ const uchar *start_words= (const uchar *)(intptr)
+ ((((ulonglong)(intptr)ptr) + SIZEOF_INT - 1) / SIZEOF_INT * SIZEOF_INT);
+
+ DBUG_ASSERT(((ulonglong)(intptr)ptr) >= SIZEOF_INT);
+ if (end_words > ptr)
+ {
+ while (end > end_words && end[-1] == 0x20)
+ end--;
+ if (end[-1] == 0x20 && start_words < end_words)
+ while (end > start_words && ((unsigned *)end)[-1] == SPACE_INT)
+ end -= SIZEOF_INT;
+ }
+ }
+ while (end > ptr && end[-1] == 0x20)
+ end--;
+ return (end);
+}
+
+static inline void lex_string_set(LEX_STRING *lex_str, const char *c_str)
+{
+ lex_str->str= (char *) c_str;
+ lex_str->length= strlen(c_str);
+}
+
#endif
diff --git a/include/my_aes.h b/include/my_aes.h
index 1bbdf5663ea..2e2a66b4968 100644
--- a/include/my_aes.h
+++ b/include/my_aes.h
@@ -1,3 +1,6 @@
+#ifndef MY_AES_INCLUDED
+#define MY_AES_INCLUDED
+
/* Copyright (C) 2002 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -63,3 +66,5 @@ int my_aes_decrypt(const char *source, int source_length, char *dest,
int my_aes_get_size(int source_length);
C_MODE_END
+
+#endif /* MY_AES_INCLUDED */
diff --git a/include/my_alarm.h b/include/my_alarm.h
index 750135d64ed..dd2d5642f5f 100644
--- a/include/my_alarm.h
+++ b/include/my_alarm.h
@@ -33,15 +33,15 @@ extern ulong my_time_to_wait_for_lock;
#define ALARM_INIT my_have_got_alarm=0 ; \
alarm_old=(uint) alarm(MY_HOW_OFTEN_TO_ALARM); \
alarm_signal=signal(SIGALRM,my_set_alarm_variable);
-#define ALARM_END VOID(signal(SIGALRM,alarm_signal)); \
- VOID(alarm(alarm_old));
+#define ALARM_END (void) signal(SIGALRM,alarm_signal); \
+ (void) alarm(alarm_old);
#define ALARM_TEST my_have_got_alarm
#ifdef DONT_REMEMBER_SIGNAL
-#define ALARM_REINIT VOID(alarm(MY_HOW_OFTEN_TO_ALARM)); \
- VOID(signal(SIGALRM,my_set_alarm_variable));\
+#define ALARM_REINIT (void) alarm(MY_HOW_OFTEN_TO_ALARM); \
+ (void) signal(SIGALRM,my_set_alarm_variable);\
my_have_got_alarm=0;
#else
-#define ALARM_REINIT VOID(alarm((uint) MY_HOW_OFTEN_TO_ALARM)); \
+#define ALARM_REINIT (void) alarm((uint) MY_HOW_OFTEN_TO_ALARM); \
my_have_got_alarm=0;
#endif /* DONT_REMEMBER_SIGNAL */
#else
diff --git a/include/my_atomic.h b/include/my_atomic.h
index ed439e5fe87..8ba3e201730 100644
--- a/include/my_atomic.h
+++ b/include/my_atomic.h
@@ -1,3 +1,6 @@
+#ifndef MY_ATOMIC_INCLUDED
+#define MY_ATOMIC_INCLUDED
+
/* Copyright (C) 2006 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -13,125 +16,285 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/*
+ This header defines five atomic operations:
+
+ my_atomic_add#(&var, what)
+ add 'what' to *var, and return the old value of *var
+
+ my_atomic_fas#(&var, what)
+ 'Fetch And Store'
+ store 'what' in *var, and return the old value of *var
+
+ my_atomic_cas#(&var, &old, new)
+ 'Compare And Swap'
+ if *var is equal to *old, then store 'new' in *var, and return TRUE
+ otherwise store *var in *old, and return FALSE
+
+ my_atomic_load#(&var)
+ return *var
+
+ my_atomic_store#(&var, what)
+ store 'what' in *var
+
+ '#' is substituted by a size suffix - 8, 16, 32, 64, or ptr
+ (e.g. my_atomic_add8, my_atomic_fas32, my_atomic_casptr).
+
+ NOTE This operations are not always atomic, so they always must be
+ enclosed in my_atomic_rwlock_rdlock(lock)/my_atomic_rwlock_rdunlock(lock)
+ or my_atomic_rwlock_wrlock(lock)/my_atomic_rwlock_wrunlock(lock).
+ Hint: if a code block makes intensive use of atomic ops, it make sense
+ to take/release rwlock once for the whole block, not for every statement.
+
+ On architectures where these operations are really atomic, rwlocks will
+ be optimized away.
+ 8- and 16-bit atomics aren't implemented for windows (see generic-msvc.h),
+ but can be added, if necessary.
+*/
+
#ifndef my_atomic_rwlock_init
#define intptr void *
+/**
+ Currently we don't support 8-bit and 16-bit operations.
+ It can be added later if needed.
+*/
+#undef MY_ATOMIC_HAS_8_16
#ifndef MY_ATOMIC_MODE_RWLOCKS
+/*
+ * Attempt to do atomic ops without locks
+ */
#include "atomic/nolock.h"
#endif
#ifndef make_atomic_cas_body
+/* nolock.h was not able to generate even a CAS function, fall back */
#include "atomic/rwlock.h"
#endif
+/* define missing functions by using the already generated ones */
#ifndef make_atomic_add_body
-#define make_atomic_add_body(S) \
+#define make_atomic_add_body(S) \
+ int ## S tmp=*a; \
+ while (!my_atomic_cas ## S(a, &tmp, tmp+v)) ; \
+ v=tmp;
+#endif
+#ifndef make_atomic_fas_body
+#define make_atomic_fas_body(S) \
int ## S tmp=*a; \
- while (!my_atomic_cas ## S(a, &tmp, tmp+v)); \
+ while (!my_atomic_cas ## S(a, &tmp, v)) ; \
v=tmp;
#endif
+#ifndef make_atomic_load_body
+#define make_atomic_load_body(S) \
+ ret= 0; /* avoid compiler warning */ \
+ (void)(my_atomic_cas ## S(a, &ret, ret));
+#endif
+#ifndef make_atomic_store_body
+#define make_atomic_store_body(S) \
+ (void)(my_atomic_fas ## S (a, v));
+#endif
+
+/*
+ transparent_union doesn't work in g++
+ Bug ?
+
+ Darwin's gcc doesn't want to put pointers in a transparent_union
+ when built with -arch ppc64. Complains:
+ warning: 'transparent_union' attribute ignored
+*/
+#if defined(__GNUC__) && !defined(__cplusplus) && \
+ ! (defined(__APPLE__) && (defined(_ARCH_PPC64) ||defined (_ARCH_PPC)))
+/*
+ we want to be able to use my_atomic_xxx functions with
+ both signed and unsigned integers. But gcc will issue a warning
+ "passing arg N of `my_atomic_XXX' as [un]signed due to prototype"
+ if the signedness of the argument doesn't match the prototype, or
+ "pointer targets in passing argument N of my_atomic_XXX differ in signedness"
+ if int* is used where uint* is expected (or vice versa).
+ Let's shut these warnings up
+*/
+#define make_transparent_unions(S) \
+ typedef union { \
+ int ## S i; \
+ uint ## S u; \
+ } U_ ## S __attribute__ ((transparent_union)); \
+ typedef union { \
+ int ## S volatile *i; \
+ uint ## S volatile *u; \
+ } Uv_ ## S __attribute__ ((transparent_union));
+#define uintptr intptr
+make_transparent_unions(8)
+make_transparent_unions(16)
+make_transparent_unions(32)
+make_transparent_unions(64)
+make_transparent_unions(ptr)
+#undef uintptr
+#undef make_transparent_unions
+#define a U_a.i
+#define cmp U_cmp.i
+#define v U_v.i
+#define set U_set.i
+#else
+#define U_8 int8
+#define U_16 int16
+#define U_32 int32
+#define U_64 int64
+#define U_ptr intptr
+#define Uv_8 int8
+#define Uv_16 int16
+#define Uv_32 int32
+#define Uv_64 int64
+#define Uv_ptr intptr
+#define U_a volatile *a
+#define U_cmp *cmp
+#define U_v v
+#define U_set set
+#endif /* __GCC__ transparent_union magic */
#ifdef HAVE_INLINE
-#define make_atomic_add(S) \
-STATIC_INLINE int ## S my_atomic_add ## S( \
- int ## S volatile *a, int ## S v) \
-{ \
- make_atomic_add_body(S); \
- return v; \
+#define make_atomic_cas(S) \
+STATIC_INLINE int my_atomic_cas ## S(Uv_ ## S U_a, \
+ Uv_ ## S U_cmp, U_ ## S U_set) \
+{ \
+ int8 ret; \
+ make_atomic_cas_body(S); \
+ return ret; \
}
-#define make_atomic_swap(S) \
-STATIC_INLINE int ## S my_atomic_swap ## S( \
- int ## S volatile *a, int ## S v) \
-{ \
- make_atomic_swap_body(S); \
- return v; \
+#define make_atomic_add(S) \
+STATIC_INLINE int ## S my_atomic_add ## S( \
+ Uv_ ## S U_a, U_ ## S U_v) \
+{ \
+ make_atomic_add_body(S); \
+ return v; \
}
-#define make_atomic_cas(S) \
-STATIC_INLINE int my_atomic_cas ## S(int ## S volatile *a, \
- int ## S *cmp, int ## S set) \
-{ \
- int8 ret; \
- make_atomic_cas_body(S); \
- return ret; \
+#define make_atomic_fas(S) \
+STATIC_INLINE int ## S my_atomic_fas ## S( \
+ Uv_ ## S U_a, U_ ## S U_v) \
+{ \
+ make_atomic_fas_body(S); \
+ return v; \
}
-#define make_atomic_load(S) \
-STATIC_INLINE int ## S my_atomic_load ## S(int ## S volatile *a) \
-{ \
- int ## S ret; \
- make_atomic_load_body(S); \
- return ret; \
+#define make_atomic_load(S) \
+STATIC_INLINE int ## S my_atomic_load ## S(Uv_ ## S U_a) \
+{ \
+ int ## S ret; \
+ make_atomic_load_body(S); \
+ return ret; \
}
-#define make_atomic_store(S) \
-STATIC_INLINE void my_atomic_store ## S( \
- int ## S volatile *a, int ## S v) \
-{ \
- make_atomic_store_body(S); \
+#define make_atomic_store(S) \
+STATIC_INLINE void my_atomic_store ## S( \
+ Uv_ ## S U_a, U_ ## S U_v) \
+{ \
+ make_atomic_store_body(S); \
}
#else /* no inline functions */
-#define make_atomic_add(S) \
-extern int ## S my_atomic_add ## S(int ## S volatile *a, int ## S v);
+#define make_atomic_add(S) \
+extern int ## S my_atomic_add ## S(Uv_ ## S U_a, U_ ## S U_v);
-#define make_atomic_swap(S) \
-extern int ## S my_atomic_swap ## S(int ## S volatile *a, int ## S v);
+#define make_atomic_fas(S) \
+extern int ## S my_atomic_fas ## S(Uv_ ## S U_a, U_ ## S U_v);
-#define make_atomic_cas(S) \
-extern int my_atomic_cas ## S(int ## S volatile *a, int ## S *cmp, int ## S set);
+#define make_atomic_cas(S) \
+extern int my_atomic_cas ## S(Uv_ ## S U_a, Uv_ ## S U_cmp, U_ ## S U_set);
-#define make_atomic_load(S) \
-extern int ## S my_atomic_load ## S(int ## S volatile *a);
+#define make_atomic_load(S) \
+extern int ## S my_atomic_load ## S(Uv_ ## S U_a);
-#define make_atomic_store(S) \
-extern void my_atomic_store ## S(int ## S volatile *a, int ## S v);
+#define make_atomic_store(S) \
+extern void my_atomic_store ## S(Uv_ ## S U_a, U_ ## S U_v);
-#endif
+#endif /* HAVE_INLINE */
-make_atomic_cas( 8)
+#ifdef MY_ATOMIC_HAS_8_16
+make_atomic_cas(8)
make_atomic_cas(16)
+#endif
make_atomic_cas(32)
+make_atomic_cas(64)
make_atomic_cas(ptr)
-make_atomic_add( 8)
+#ifdef MY_ATOMIC_HAS_8_16
+make_atomic_add(8)
make_atomic_add(16)
+#endif
make_atomic_add(32)
+make_atomic_add(64)
-make_atomic_load( 8)
+#ifdef MY_ATOMIC_HAS_8_16
+make_atomic_load(8)
make_atomic_load(16)
+#endif
make_atomic_load(32)
+make_atomic_load(64)
make_atomic_load(ptr)
-make_atomic_store( 8)
+#ifdef MY_ATOMIC_HAS_8_16
+make_atomic_fas(8)
+make_atomic_fas(16)
+#endif
+make_atomic_fas(32)
+make_atomic_fas(64)
+make_atomic_fas(ptr)
+
+#ifdef MY_ATOMIC_HAS_8_16
+make_atomic_store(8)
make_atomic_store(16)
+#endif
make_atomic_store(32)
+make_atomic_store(64)
make_atomic_store(ptr)
-make_atomic_swap( 8)
-make_atomic_swap(16)
-make_atomic_swap(32)
-make_atomic_swap(ptr)
+#ifdef _atomic_h_cleanup_
+#include _atomic_h_cleanup_
+#undef _atomic_h_cleanup_
+#endif
+#undef U_8
+#undef U_16
+#undef U_32
+#undef U_64
+#undef U_ptr
+#undef Uv_8
+#undef Uv_16
+#undef Uv_32
+#undef Uv_64
+#undef Uv_ptr
+#undef a
+#undef cmp
+#undef v
+#undef set
+#undef U_a
+#undef U_cmp
+#undef U_v
+#undef U_set
#undef make_atomic_add
#undef make_atomic_cas
#undef make_atomic_load
#undef make_atomic_store
-#undef make_atomic_swap
+#undef make_atomic_fas
#undef make_atomic_add_body
#undef make_atomic_cas_body
#undef make_atomic_load_body
#undef make_atomic_store_body
-#undef make_atomic_swap_body
+#undef make_atomic_fas_body
#undef intptr
-#ifdef _atomic_h_cleanup_
-#include _atomic_h_cleanup_
-#undef _atomic_h_cleanup_
+/*
+ the macro below defines (as an expression) the code that
+ will be run in spin-loops. Intel manuals recummend to have PAUSE there.
+ It is expected to be defined in include/atomic/ *.h files
+*/
+#ifndef LF_BACKOFF
+#define LF_BACKOFF (1)
#endif
#define MY_ATOMIC_OK 0
@@ -140,3 +303,4 @@ extern int my_atomic_initialize();
#endif
+#endif /* MY_ATOMIC_INCLUDED */
diff --git a/include/my_base.h b/include/my_base.h
index a01b2ec9b82..7766d4165a2 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -191,10 +191,11 @@ enum ha_extra_function {
/* Inform handler that we will do a rename */
HA_EXTRA_PREPARE_FOR_RENAME,
/*
- Orders MERGE handler to attach or detach its child tables. Used at
- begin and end of a statement.
+ Special actions for MERGE tables.
*/
+ HA_EXTRA_ADD_CHILDREN_LIST,
HA_EXTRA_ATTACH_CHILDREN,
+ HA_EXTRA_IS_ATTACHED_CHILDREN,
HA_EXTRA_DETACH_CHILDREN
};
@@ -255,27 +256,27 @@ enum ha_base_keytype {
HA_BINARY_PACK_KEY | HA_FULLTEXT | HA_UNIQUE_CHECK | \
HA_SPATIAL | HA_NULL_ARE_EQUAL | HA_GENERATED_KEY)
-#define HA_KEY_HAS_PART_KEY_SEG 65536 /* Key contains partial segments */
+/*
+ Key contains partial segments.
+
+ This flag is internal to the MySQL server by design. It is not supposed
+ neither to be saved in FRM-files, nor to be passed to storage engines.
+ It is intended to pass information into internal static sort_keys(KEY *,
+ KEY *) function.
+
+ This flag can be calculated -- it's based on key lengths comparison.
+*/
+#define HA_KEY_HAS_PART_KEY_SEG 65536
/* Automatic bits in key-flag */
#define HA_SPACE_PACK_USED 4 /* Test for if SPACE_PACK used */
#define HA_VAR_LENGTH_KEY 8
#define HA_NULL_PART_KEY 64
+#define HA_USES_COMMENT 4096
#define HA_USES_PARSER 16384 /* Fulltext index uses [pre]parser */
#define HA_USES_BLOCK_SIZE ((uint) 32768)
#define HA_SORT_ALLOWS_SAME 512 /* Intern bit when sorting records */
-#if MYSQL_VERSION_ID < 0x50200
-/*
- Key has a part that can have end space. If this is an unique key
- we have to handle it differently from other unique keys as we can find
- many matching rows for one key (because end space are not compared)
-*/
-#define HA_END_SPACE_KEY 0 /* was: 4096 */
-#else
-#error HA_END_SPACE_KEY is obsolete, please remove it
-#endif
-
/* These flags can be added to key-seg-flag */
diff --git a/include/my_bit.h b/include/my_bit.h
index 2e464e89049..5cbf4f8b83e 100644
--- a/include/my_bit.h
+++ b/include/my_bit.h
@@ -1,3 +1,6 @@
+#ifndef MY_BIT_INCLUDED
+#define MY_BIT_INCLUDED
+
/*
Some useful bit functions
*/
@@ -107,3 +110,5 @@ extern uint my_count_bits(ulonglong v);
extern uint my_count_bits_ushort(ushort v);
#endif /* HAVE_INLINE */
C_MODE_END
+
+#endif /* MY_BIT_INCLUDED */
diff --git a/include/my_bitmap.h b/include/my_bitmap.h
index 78642df3362..314dac983b0 100644
--- a/include/my_bitmap.h
+++ b/include/my_bitmap.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2000 MySQL AB, 2009 Sun Microsystems, Inc
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
@@ -34,7 +34,7 @@ typedef struct st_bitmap
acquiring the mutex
*/
#ifdef THREAD
- pthread_mutex_t *mutex;
+ mysql_mutex_t *mutex;
#endif
} MY_BITMAP;
diff --git a/include/my_dbug.h b/include/my_dbug.h
index 0ba72b2210d..34681fbc633 100644
--- a/include/my_dbug.h
+++ b/include/my_dbug.h
@@ -16,101 +16,64 @@
#ifndef _dbug_h
#define _dbug_h
-#if defined(__cplusplus) && !defined(DBUG_OFF)
-class Dbug_violation_helper
-{
-public:
- inline Dbug_violation_helper() :
- _entered(TRUE)
- { }
-
- inline ~Dbug_violation_helper()
- {
- assert(!_entered);
- }
-
- inline void leave()
- {
- _entered= FALSE;
- }
-
-private:
- bool _entered;
-};
-#endif /* C++ */
-
-#ifdef __cplusplus
+#ifdef __cplusplus
extern "C" {
#endif
#if !defined(DBUG_OFF) && !defined(_lint)
-struct _db_code_state_;
-extern int _db_keyword_(struct _db_code_state_ *cs, const char *keyword);
-extern int _db_strict_keyword_(const char *keyword);
+
+struct _db_stack_frame_ {
+ const char *func; /* function name of the previous stack frame */
+ const char *file; /* filename of the function of previous frame */
+ uint level; /* this nesting level, highest bit enables tracing */
+ struct _db_stack_frame_ *prev; /* pointer to the previous frame */
+};
+
+struct _db_code_state_;
+extern my_bool _dbug_on_;
+extern my_bool _db_keyword_(struct _db_code_state_ *, const char *, int);
extern int _db_explain_(struct _db_code_state_ *cs, char *buf, size_t len);
extern int _db_explain_init_(char *buf, size_t len);
-extern void _db_setjmp_(void);
-extern void _db_longjmp_(void);
+extern int _db_is_pushed_(void);
+extern void _db_setjmp_(void);
+extern void _db_longjmp_(void);
extern void _db_process_(const char *name);
-extern void _db_push_(const char *control);
-extern void _db_pop_(void);
-extern void _db_set_(struct _db_code_state_ *cs, const char *control);
+extern void _db_push_(const char *control);
+extern void _db_pop_(void);
+extern void _db_set_(const char *control);
extern void _db_set_init_(const char *control);
-extern void _db_enter_(const char *_func_,const char *_file_,uint _line_,
- const char **_sfunc_,const char **_sfile_,
- uint *_slevel_, char ***);
-extern void _db_return_(uint _line_,const char **_sfunc_,const char **_sfile_,
- uint *_slevel_);
-extern void _db_pargs_(uint _line_,const char *keyword);
-extern void _db_doprnt_ _VARARGS((const char *format,...))
+extern void _db_enter_(const char *_func_, const char *_file_, uint _line_,
+ struct _db_stack_frame_ *_stack_frame_);
+extern void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_);
+extern void _db_pargs_(uint _line_,const char *keyword);
+extern void _db_doprnt_ _VARARGS((const char *format,...))
ATTRIBUTE_FORMAT(printf, 1, 2);
-extern void _db_dump_(uint _line_,const char *keyword,
+extern void _db_dump_(uint _line_,const char *keyword,
const unsigned char *memory, size_t length);
-extern void _db_end_(void);
-extern void _db_lock_file_(void);
-extern void _db_unlock_file_(void);
-extern FILE *_db_fp_(void);
-
-#ifdef __cplusplus
-
-#define DBUG_ENTER(a) \
- const char *_db_func_, *_db_file_; \
- uint _db_level_; \
- char **_db_framep_; \
- Dbug_violation_helper dbug_violation_helper; \
- _db_enter_ (a, __FILE__, __LINE__, &_db_func_, &_db_file_, \
- &_db_level_, &_db_framep_)
-#define DBUG_VIOLATION_HELPER_LEAVE dbug_violation_helper.leave()
-
-#else /* C */
-
-#define DBUG_ENTER(a) \
- const char *_db_func_, *_db_file_; \
- uint _db_level_; \
- char **_db_framep_; \
- _db_enter_ (a, __FILE__, __LINE__, &_db_func_, &_db_file_, \
- &_db_level_, &_db_framep_)
-#define DBUG_VIOLATION_HELPER_LEAVE do { } while(0)
-
-#endif /* C++ */
-
-#define DBUG_LEAVE \
- DBUG_VIOLATION_HELPER_LEAVE; \
- _db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_)
+extern void _db_end_(void);
+extern void _db_lock_file_(void);
+extern void _db_unlock_file_(void);
+extern FILE *_db_fp_(void);
+extern void _db_flush_();
+extern const char* _db_get_func_(void);
+
+#define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_; \
+ _db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_)
+#define DBUG_LEAVE _db_return_ (__LINE__, &_db_stack_frame_)
#define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0)
#define DBUG_VOID_RETURN do {DBUG_LEAVE; return;} while(0)
#define DBUG_EXECUTE(keyword,a1) \
- do {if (_db_keyword_(0, (keyword))) { a1 }} while(0)
+ do {if (_db_keyword_(0, (keyword), 0)) { a1 }} while(0)
#define DBUG_EXECUTE_IF(keyword,a1) \
- do {if (_db_strict_keyword_ (keyword)) { a1 } } while(0)
+ do {if (_db_keyword_(0, (keyword), 1)) { a1 }} while(0)
#define DBUG_EVALUATE(keyword,a1,a2) \
- (_db_keyword_(0,(keyword)) ? (a1) : (a2))
+ (_db_keyword_(0,(keyword), 0) ? (a1) : (a2))
#define DBUG_EVALUATE_IF(keyword,a1,a2) \
- (_db_strict_keyword_((keyword)) ? (a1) : (a2))
+ (_db_keyword_(0,(keyword), 1) ? (a1) : (a2))
#define DBUG_PRINT(keyword,arglist) \
do {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;} while(0)
#define DBUG_PUSH(a1) _db_push_ (a1)
#define DBUG_POP() _db_pop_ ()
-#define DBUG_SET(a1) _db_set_ (0, (a1))
+#define DBUG_SET(a1) _db_set_ (a1)
#define DBUG_SET_INITIAL(a1) _db_set_init_ (a1)
#define DBUG_PROCESS(a1) _db_process_(a1)
#define DBUG_FILE _db_fp_()
@@ -123,36 +86,81 @@ extern FILE *_db_fp_(void);
#define DBUG_ASSERT(A) assert(A)
#define DBUG_EXPLAIN(buf,len) _db_explain_(0, (buf),(len))
#define DBUG_EXPLAIN_INITIAL(buf,len) _db_explain_init_((buf),(len))
-#define IF_DBUG(A) A
-#else /* No debugger */
+#define DEBUGGER_OFF do { _dbug_on_= 0; } while(0)
+#define DEBUGGER_ON do { _dbug_on_= 1; } while(0)
+#ifndef __WIN__
+#define DBUG_ABORT() (_db_flush_(), abort())
+#else
+/*
+ Avoid popup with abort/retry/ignore buttons. When BUG#31745 is fixed we can
+ call abort() instead of _exit(3) (now it would cause a "test signal" popup).
+*/
+#include <crtdbg.h>
+#define DBUG_ABORT() (_db_flush_(),\
+ (void)_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE),\
+ (void)_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR),\
+ _exit(3))
+#endif
+#define DBUG_CHECK_CRASH(func, op) \
+ do { char _dbuf_[255]; strxnmov(_dbuf_, sizeof(_dbuf_)-1, (func), (op)); \
+ DBUG_EXECUTE_IF(_dbuf_, DBUG_ABORT()); } while(0)
+#define DBUG_CRASH_ENTER(func) \
+ DBUG_ENTER(func); DBUG_CHECK_CRASH(func, "_crash_enter")
+#define DBUG_CRASH_RETURN(val) \
+ DBUG_CHECK_CRASH(_db_get_func_(), "_crash_return")
+#define DBUG_CRASH_VOID_RETURN \
+ DBUG_CHECK_CRASH (_db_get_func_(), "_crash_return")
+
+#else /* No debugger */
#define DBUG_ENTER(a1)
#define DBUG_LEAVE
-#define DBUG_VIOLATION_HELPER_LEAVE
-#define DBUG_RETURN(a1) do { return(a1); } while(0)
-#define DBUG_VOID_RETURN do { return; } while(0)
-#define DBUG_EXECUTE(keyword,a1) do { } while(0)
-#define DBUG_EXECUTE_IF(keyword,a1) do { } while(0)
+#define DBUG_RETURN(a1) do { return(a1); } while(0)
+#define DBUG_VOID_RETURN do { return; } while(0)
+#define DBUG_EXECUTE(keyword,a1) do { } while(0)
+#define DBUG_EXECUTE_IF(keyword,a1) do { } while(0)
#define DBUG_EVALUATE(keyword,a1,a2) (a2)
#define DBUG_EVALUATE_IF(keyword,a1,a2) (a2)
-#define DBUG_PRINT(keyword,arglist) do { } while(0)
-#define DBUG_PUSH(a1)
-#define DBUG_SET(a1) do { } while(0)
-#define DBUG_SET_INITIAL(a1) do { } while(0)
-#define DBUG_POP()
-#define DBUG_PROCESS(a1)
+#define DBUG_PRINT(keyword,arglist) do { } while(0)
+#define DBUG_PUSH(a1) do { } while(0)
+#define DBUG_SET(a1) do { } while(0)
+#define DBUG_SET_INITIAL(a1) do { } while(0)
+#define DBUG_POP() do { } while(0)
+#define DBUG_PROCESS(a1) do { } while(0)
#define DBUG_SETJMP(a1) setjmp(a1)
#define DBUG_LONGJMP(a1) longjmp(a1)
-#define DBUG_DUMP(keyword,a1,a2) do { } while(0)
-#define DBUG_END()
-#define DBUG_ASSERT(A) do { } while(0)
-#define DBUG_LOCK_FILE
+#define DBUG_DUMP(keyword,a1,a2) do { } while(0)
+#define DBUG_END() do { } while(0)
+#define DBUG_ASSERT(A) do { } while(0)
+#define DBUG_LOCK_FILE do { } while(0)
#define DBUG_FILE (stderr)
-#define DBUG_UNLOCK_FILE
+#define DBUG_UNLOCK_FILE do { } while(0)
#define DBUG_EXPLAIN(buf,len)
#define DBUG_EXPLAIN_INITIAL(buf,len)
-#define IF_DBUG(A)
+#define DEBUGGER_OFF do { } while(0)
+#define DEBUGGER_ON do { } while(0)
+#define DBUG_ABORT() abort()
+#define DBUG_CRASH_ENTER(func)
+#define DBUG_CRASH_RETURN(val) do { return(val); } while(0)
+#define DBUG_CRASH_VOID_RETURN do { return; } while(0)
+
#endif
+
+#ifdef EXTRA_DEBUG
+/**
+ Sync points allow us to force the server to reach a certain line of code
+ and block there until the client tells the server it is ok to go on.
+ The client tells the server to block with SELECT GET_LOCK()
+ and unblocks it with SELECT RELEASE_LOCK(). Used for debugging difficult
+ concurrency problems
+*/
+#define DBUG_SYNC_POINT(lock_name,lock_timeout) \
+ debug_sync_point(lock_name,lock_timeout)
+void debug_sync_point(const char* lock_name, uint lock_timeout);
+#else
+#define DBUG_SYNC_POINT(lock_name,lock_timeout)
+#endif /* EXTRA_DEBUG */
+
#ifdef __cplusplus
}
#endif
diff --git a/include/my_dir.h b/include/my_dir.h
index 06509a3af19..de21bee7385 100644
--- a/include/my_dir.h
+++ b/include/my_dir.h
@@ -13,17 +13,17 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifndef _my_dir_h
-#define _my_dir_h
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef MY_DIR_H
#define MY_DIR_H
+#include "my_global.h"
+
#include <sys/stat.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Defines for my_dir and my_stat */
#define MY_S_IFMT S_IFMT /* type of file */
@@ -69,7 +69,11 @@ typedef struct my_stat
#else
+#if(_MSC_VER)
+#define MY_STAT struct _stati64 /* 64 bit file size */
+#else
#define MY_STAT struct stat /* Orginal struct have what we need */
+#endif
#endif /* USE_MY_STAT_STRUCT */
@@ -97,9 +101,9 @@ extern void my_dirend(MY_DIR *buffer);
extern MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags);
extern int my_fstat(int filenr, MY_STAT *stat_area, myf MyFlags);
-#endif /* MY_DIR_H */
-
#ifdef __cplusplus
}
#endif
-#endif
+
+#endif /* MY_DIR_H */
+
diff --git a/include/my_getopt.h b/include/my_getopt.h
index 7cbad607aac..54ae5982ea1 100644
--- a/include/my_getopt.h
+++ b/include/my_getopt.h
@@ -16,6 +16,8 @@
#ifndef _my_getopt_h
#define _my_getopt_h
+#include "my_sys.h" /* loglevel */
+
C_MODE_START
#define GET_NO_ARG 1
@@ -32,6 +34,7 @@ C_MODE_START
#define GET_ENUM 12
#define GET_SET 13
#define GET_DOUBLE 14
+#define GET_FLAGSET 15
#define GET_ASK_ADDR 128
#define GET_TYPE_MASK 127
@@ -42,24 +45,40 @@ struct st_typelib;
struct my_option
{
- const char *name; /* Name of the option */
- int id; /* unique id or short option */
- const char *comment; /* option comment, for autom. --help */
- uchar **value; /* The variable value */
- uchar **u_max_value; /* The user def. max variable value */
- struct st_typelib *typelib; /* Pointer to possible values */
- ulong var_type;
- enum get_opt_arg_type arg_type;
- longlong def_value; /* Default value */
- longlong min_value; /* Min allowed value */
- longlong max_value; /* Max allowed value */
- longlong sub_size; /* Subtract this from given value */
- long block_size; /* Value should be a mult. of this */
- void *app_type; /* To be used by an application */
+ const char *name; /**< Name of the option. name=NULL
+ marks the end of the my_option[]
+ array.
+ */
+ int id; /**< For 0<id<255 it's means one
+ character for a short option
+ (like -A), if >255 no short option
+ is created, but a long option still
+ can be identified uniquely in the
+ my_get_one_option() callback.
+ If an opton needs neither special
+ treatment in the my_get_one_option()
+ nor one-letter short equivalent
+ use id=0
+ */
+ const char *comment; /**< option comment, for autom. --help.
+ if it's NULL the option is not
+ visible in --help.
+ */
+ uchar **value; /**< A pointer to the variable value */
+ uchar **u_max_value; /**< The user def. max variable value */
+ struct st_typelib *typelib; /**< Pointer to possible values */
+ ulong var_type; /**< GET_BOOL, GET_ULL, etc */
+ enum get_opt_arg_type arg_type; /**< e.g. REQUIRED_ARG or OPT_ARG */
+ longlong def_value; /**< Default value */
+ longlong min_value; /**< Min allowed value (for numbers) */
+ longlong max_value; /**< Max allowed value (for numbers) */
+ longlong sub_size; /**< Unused */
+ long block_size; /**< Value should be a mult. of this (for numbers) */
+ void *app_type; /**< To be used by an application */
};
-typedef my_bool (* my_get_one_option) (int, const struct my_option *, char * );
-typedef void (* my_error_reporter) (enum loglevel level, const char *format, ... );
+typedef my_bool (*my_get_one_option) (int, const struct my_option *, char * );
+typedef void (*my_error_reporter) (enum loglevel level, const char *format, ... );
extern char *disabled_my_option;
extern my_bool my_getopt_print_errors;
@@ -78,6 +97,8 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp,
my_bool *fix);
longlong getopt_ll_limit_value(longlong, const struct my_option *,
my_bool *fix);
+double getopt_double_limit_value(double num, const struct my_option *optp,
+ my_bool *fix);
my_bool getopt_compare_strings(const char *s, const char *t, uint length);
C_MODE_END
diff --git a/include/my_global.h b/include/my_global.h
index e4e53aca20a..6558e402586 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright (C) 2000-2003 MySQL AB, 2009 Sun Microsystems, Inc
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
@@ -18,6 +18,11 @@
#ifndef _global_h
#define _global_h
+/* Client library users on Windows need this macro defined here. */
+#if !defined(__WIN__) && defined(_WIN32)
+#define __WIN__
+#endif
+
/*
InnoDB depends on some MySQL internals which other plugins should not
need. This is because of InnoDB's foreign key support, "safe" binlog
@@ -68,8 +73,8 @@
#define C_MODE_END
#endif
-#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
-#include <config-win.h>
+#if defined(_WIN32)
+#include <my_config.h>
#elif defined(__NETWARE__)
#include <my_config.h>
#include <config-netware.h>
@@ -83,11 +88,39 @@
#endif
#endif /* _WIN32... */
-/* Make it easier to add conditionl code for windows */
+#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
+#define HAVE_PSI_INTERFACE
+#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
+
+/* Make it easier to add conditional code in _expressions_ */
#ifdef __WIN__
-#define IF_WIN(A,B) (A)
+#define IF_WIN(A,B) A
+#else
+#define IF_WIN(A,B) B
+#endif
+
+#ifdef __NETWARE__
+#define IF_NETWARE(A,B) A
#else
-#define IF_WIN(A,B) (B)
+#define IF_NETWARE(A,B) B
+#endif
+
+#ifndef DBUG_OFF
+#define IF_DBUG(A,B) A
+#else
+#define IF_DBUG(A,B) B
+#endif
+
+#ifdef HAVE_purify
+#define IF_PURIFY(A,B) A
+#else
+#define IF_PURIFY(A,B) B
+#endif
+
+#ifdef DISABLE_GRANT_OPTIONS
+#define IF_DISABLE_GRANT_OPTIONS(A,B) A
+#else
+#define IF_DISABLE_GRANT_OPTIONS(A,B) B
#endif
#ifndef EMBEDDED_LIBRARY
@@ -107,6 +140,49 @@
#define NETWARE_SET_SCREEN_MODE(A)
#endif
+#if defined (_WIN32)
+/*
+ off_t is 32 bit long. We do not use C runtime functions
+ with off_t but native Win32 file IO APIs, that work with
+ 64 bit offsets.
+*/
+#undef SIZEOF_OFF_T
+#define SIZEOF_OFF_T 8
+
+/*
+ Prevent inclusion of Windows GDI headers - they define symbol
+ ERROR that conflicts with mysql headers.
+*/
+#ifndef NOGDI
+#define NOGDI
+#endif
+
+/* Include common headers.*/
+#include <winsock2.h>
+#include <ws2tcpip.h> /* SOCKET */
+#include <io.h> /* access(), chmod() */
+#include <process.h> /* getpid() */
+
+#define sleep(a) Sleep((a)*1000)
+
+/* Define missing access() modes. */
+#define F_OK 0
+#define W_OK 2
+
+/* Define missing file locking constants. */
+#define F_RDLCK 1
+#define F_WRLCK 2
+#define F_UNLCK 3
+#define F_TO_EOF 0x3FFFFFFF
+
+/* Shared memory and named pipe connections are supported. */
+#define HAVE_SMEM 1
+#define HAVE_NAMED_PIPE 1
+#define shared_memory_buffer_length 16000
+#define default_shared_memory_base_name "MYSQL"
+#endif /* _WIN32*/
+
+
/* Workaround for _LARGE_FILES and _LARGE_FILE_API incompatibility on AIX */
#if defined(_AIX) && defined(_LARGE_FILE_API)
#undef _LARGE_FILE_API
@@ -239,6 +315,8 @@
#define inline_test_2(X) inline_test_1(X)
#if inline_test_2(inline) != 1
#define HAVE_INLINE
+#else
+#warning No "inline" support in C, all "static inline" functions will be instantiated in every .o file!!!
#endif
#undef inline_test_2
#undef inline_test_1
@@ -410,6 +488,7 @@ C_MODE_END
#ifndef stdin
#include <stdio.h>
#endif
+#include <stdarg.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -478,15 +557,17 @@ C_MODE_END
#define compile_time_assert(X) \
do \
{ \
- char compile_time_assert[(X) ? 1 : -1] \
- __attribute__ ((unused)); \
+ typedef char compile_time_assert[(X) ? 1 : -1]; \
} while(0)
#endif
/* Go around some bugs in different OS and compilers */
#if defined (HPUX11) && defined(_LARGEFILE_SOURCE)
+#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
+#endif
+
#if defined(_HPUX_SOURCE) && defined(HAVE_SYS_STREAM_H)
#include <sys/stream.h> /* HPUX 10.20 defines ulong here. UGLY !!! */
#define HAVE_ULONG
@@ -541,17 +622,6 @@ extern "C" int madvise(void *addr, size_t len, int behav);
#define DONT_REMEMBER_SIGNAL
#endif
-/* Define void to stop lint from generating "null effekt" comments */
-#ifndef DONT_DEFINE_VOID
-#ifdef _lint
-int __void__;
-#define VOID(X) (__void__ = (int) (X))
-#else
-#undef VOID
-#define VOID(X) (X)
-#endif
-#endif /* DONT_DEFINE_VOID */
-
#if defined(_lint) || defined(FORCE_INIT_OF_VARS)
#define LINT_INIT(var) var=0 /* No uninitialize-warning */
#else
@@ -648,8 +718,6 @@ C_MODE_END
# endif
#endif
-#include <my_dbug.h>
-
#define MIN_ARRAY_SIZE 0 /* Zero or One. Gcc allows zero*/
#define ASCII_BITS_USED 8 /* Bit char used */
#define NEAR_F /* No near function handling */
@@ -657,7 +725,9 @@ C_MODE_END
/* Some types that is different between systems */
typedef int File; /* File descriptor */
-#ifndef Socket_defined
+#ifdef _WIN32
+typedef SOCKET my_socket;
+#else
typedef int my_socket; /* File descriptor for sockets */
#define INVALID_SOCKET -1
#endif
@@ -745,17 +815,59 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define FN_CURLIB '.' /* ./ is used as abbrev for current dir */
#define FN_PARENTDIR ".." /* Parent directory; Must be a string */
-#ifndef FN_LIBCHAR
+#ifdef _WIN32
+#define FN_LIBCHAR '\\'
+#define FN_LIBCHAR2 '/'
+#define FN_ROOTDIR "\\"
+#define FN_DEVCHAR ':'
+#define FN_NETWORK_DRIVES /* Uses \\ to indicate network drives */
+#define FN_NO_CASE_SENCE /* Files are not case-sensitive */
+#else
#define FN_LIBCHAR '/'
+#define FN_LIBCHAR2 '/'
#define FN_ROOTDIR "/"
#endif
-#define MY_NFILE 64 /* This is only used to save filenames */
+
+/*
+ MY_FILE_MIN is Windows speciality and is used to quickly detect
+ the mismatch of CRT and mysys file IO usage on Windows at runtime.
+ CRT file descriptors can be in the range 0-2047, whereas descriptors returned
+ by my_open() will start with 2048. If a file descriptor with value less then
+ MY_FILE_MIN is passed to mysys IO function, chances are it stemms from
+ open()/fileno() and not my_open()/my_fileno.
+
+ For Posix, mysys functions are light wrappers around libc, and MY_FILE_MIN
+ is logically 0.
+*/
+
+#ifdef _WIN32
+#define MY_FILE_MIN 2048
+#else
+#define MY_FILE_MIN 0
+#endif
+
+/*
+ MY_NFILE is the default size of my_file_info array.
+
+ It is larger on Windows, because it all file handles are stored in my_file_info
+ Default size is 16384 and this should be enough for most cases.If it is not
+ enough, --max-open-files with larger value can be used.
+
+ For Posix , my_file_info array is only used to store filenames for
+ error reporting and its size is not a limitation for number of open files.
+*/
+#ifdef _WIN32
+#define MY_NFILE (16384 + MY_FILE_MIN)
+#else
+#define MY_NFILE 64
+#endif
+
#ifndef OS_FILE_LIMIT
#define OS_FILE_LIMIT UINT_MAX
#endif
/* #define EXT_IN_LIBNAME */
-/* #define FN_NO_CASE_SENCE */
+/* #define FN_NO_CASE_SENSE */
/* #define FN_UPPER_CASE TRUE */
/*
@@ -778,7 +890,7 @@ typedef SOCKET_SIZE_TYPE size_socket;
/* Typical record cash */
#define RECORD_CACHE_SIZE (uint) (64*1024-MALLOC_OVERHEAD)
/* Typical key cash */
-#define KEY_CACHE_SIZE (uint) (8*1024*1024-MALLOC_OVERHEAD)
+#define KEY_CACHE_SIZE (uint) (8*1024*1024)
/* Default size of a key cache block */
#define KEY_CACHE_BLOCK_SIZE (uint) 1024
@@ -786,9 +898,8 @@ typedef SOCKET_SIZE_TYPE size_socket;
/* Some things that this system doesn't have */
#define NO_HASH /* Not needed anymore */
-#ifdef __WIN__
-#define NO_DIR_LIBRARY /* Not standar dir-library */
-#define USE_MY_STAT_STRUCT /* For my_lib */
+#ifdef _WIN32
+#define NO_DIR_LIBRARY /* Not standard dir-library */
#endif
/* Some defines of functions for portability */
@@ -796,6 +907,31 @@ typedef SOCKET_SIZE_TYPE size_socket;
#undef remove /* Crashes MySQL on SCO 5.0.0 */
#ifndef __WIN__
#define closesocket(A) close(A)
+#endif
+
+#if (_MSC_VER)
+#if !defined(_WIN64)
+inline double my_ulonglong2double(unsigned long long value)
+{
+ long long nr=(long long) value;
+ if (nr >= 0)
+ return (double) nr;
+ return (18446744073709551616.0 + (double) nr);
+}
+#define ulonglong2double my_ulonglong2double
+#define my_off_t2double my_ulonglong2double
+#endif /* _WIN64 */
+inline unsigned long long my_double2ulonglong(double d)
+{
+ double t= d - (double) 0x8000000000000000ULL;
+
+ if (t >= 0)
+ return ((unsigned long long) t) + 0x8000000000000000ULL;
+ return (unsigned long long) d;
+}
+#define double2ulonglong my_double2ulonglong
+#endif
+
#ifndef ulonglong2double
#define ulonglong2double(A) ((double) (ulonglong) (A))
#define my_off_t2double(A) ((double) (my_off_t) (A))
@@ -803,7 +939,6 @@ typedef SOCKET_SIZE_TYPE size_socket;
#ifndef double2ulonglong
#define double2ulonglong(A) ((ulonglong) (double) (A))
#endif
-#endif
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
@@ -845,6 +980,8 @@ typedef SOCKET_SIZE_TYPE size_socket;
#endif
#endif /* defined (HAVE_LONG_LONG) && !defined(ULONGLONG_MAX)*/
+#define INT_MIN64 (~0x7FFFFFFFFFFFFFFFLL)
+#define INT_MAX64 0x7FFFFFFFFFFFFFFFLL
#define INT_MIN32 (~0x7FFFFFFFL)
#define INT_MAX32 0x7FFFFFFFL
#define UINT_MAX32 0xFFFFFFFFL
@@ -957,10 +1094,14 @@ typedef long long my_ptrdiff_t;
#define HUGE_PTR
#endif
#endif
-#if defined(__IBMC__) || defined(__IBMCPP__)
-/* This was _System _Export but caused a lot of warnings on _AIX43 */
-#define STDCALL
-#elif !defined( STDCALL)
+
+#ifdef STDCALL
+#undef STDCALL
+#endif
+
+#ifdef _WIN32
+#define STDCALL __stdcall
+#else
#define STDCALL
#endif
@@ -1060,15 +1201,24 @@ typedef long long intptr;
#define SYSTEM_SIZEOF_OFF_T SIZEOF_OFF_T
#endif /* USE_RAID */
+#if defined(_WIN32)
+typedef unsigned long long my_off_t;
+typedef unsigned long long os_off_t;
+#else
+typedef off_t os_off_t;
#if SIZEOF_OFF_T > 4
typedef ulonglong my_off_t;
#else
typedef unsigned long my_off_t;
#endif
+#endif /*_WIN32*/
#define MY_FILEPOS_ERROR (~(my_off_t) 0)
-#if !defined(__WIN__)
-typedef off_t os_off_t;
-#endif
+
+/*
+ TODO Convert these to use Bitmap class.
+ */
+typedef ulonglong table_map; /* Used for table bits in join */
+typedef ulong nesting_map; /* Used for flags of nesting constructs */
#if defined(__WIN__)
#define socket_errno WSAGetLastError()
@@ -1095,9 +1245,6 @@ typedef uint8 int7; /* Most effective integer 0 <= x <= 127 */
typedef short int15; /* Most effective integer 0 <= x <= 32767 */
typedef int myf; /* Type of MyFlags in my_funcs */
typedef char my_bool; /* Small bool */
-#if !defined(bool) && (!defined(HAVE_BOOL) || !defined(__cplusplus))
-typedef char bool; /* Ordinary boolean values 0 1 */
-#endif
/* Macros for converting *constants* to the right type */
#define INT8(v) (int8) (v)
#define INT16(v) (int16) (v)
@@ -1143,6 +1290,8 @@ typedef char bool; /* Ordinary boolean values 0 1 */
#define reg16 register
#endif
+#include <my_dbug.h>
+
/*
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
@@ -1488,12 +1637,15 @@ do { doubleget_union _tmp; \
#define NO_EMBEDDED_ACCESS_CHECKS
#endif
-#ifdef HAVE_DLOPEN
-#if defined(__WIN__)
-#define dlsym(lib, name) GetProcAddress((HMODULE)lib, name)
+#if defined(_WIN32)
+#define dlsym(lib, name) (void*)GetProcAddress((HMODULE)lib, name)
#define dlopen(libname, unused) LoadLibraryEx(libname, NULL, 0)
#define dlclose(lib) FreeLibrary((HMODULE)lib)
-#elif defined(HAVE_DLFCN_H)
+#define HAVE_DLOPEN
+#endif
+
+#ifdef HAVE_DLOPEN
+#if defined(HAVE_DLFCN_H)
#include <dlfcn.h>
#endif
#endif
@@ -1539,6 +1691,12 @@ inline void operator delete[](void*, void*) { /* Do nothing */ }
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#endif
+
+#define x_free(A) \
+ do { my_free((uchar*)(A), MYF(MY_WME|MY_FAE|MY_ALLOW_ZERO_PTR)); } while (0)
+#define safeFree(X) \
+ do { if (X) { my_free((uchar*)(X), MYF(0)); (X) = NULL; } } while (0)
+
/*
Only Linux is known to need an explicit sync of the directory to make sure a
file creation/deletion/renaming in(from,to) this directory durable.
@@ -1551,6 +1709,25 @@ inline void operator delete[](void*, void*) { /* Do nothing */ }
#define bool In_C_you_should_use_my_bool_instead()
#endif
+/* Provide __func__ macro definition for platforms that miss it. */
+#if __STDC_VERSION__ < 199901L
+# if __GNUC__ >= 2
+# define __func__ __FUNCTION__
+# else
+# define __func__ "<unknown>"
+# endif
+#elif defined(_MSC_VER)
+# if _MSC_VER < 1300
+# define __func__ "<unknown>"
+# else
+# define __func__ __FUNCTION__
+# endif
+#elif defined(__BORLANDC__)
+# define __func__ __FUNC__
+#else
+# define __func__ "<unknown>"
+#endif
+
#ifndef HAVE_RINT
/**
All integers up to this number can be represented exactly as double precision
@@ -1599,4 +1776,20 @@ static inline double rint(double x)
#endif
#endif
+/* Defines that are unique to the embedded version of MySQL */
+
+#ifdef EMBEDDED_LIBRARY
+
+/* Things we don't need in the embedded version of MySQL */
+/* TODO HF add #undef HAVE_VIO if we don't want client in embedded library */
+
+#undef HAVE_PSTACK /* No stacktrace */
+#undef HAVE_OPENSSL
+#undef HAVE_SMEM /* No shared memory */
+#undef HAVE_NDBCLUSTER_DB /* No NDB cluster */
+
+#define DONT_USE_RAID
+
+#endif /* EMBEDDED_LIBRARY */
+
#endif /* my_global_h */
diff --git a/include/my_handler.h b/include/my_handler.h
index a3376cb74a2..977c0042938 100644
--- a/include/my_handler.h
+++ b/include/my_handler.h
@@ -23,6 +23,8 @@
extern "C" {
#endif
+#include "m_ctype.h" /* CHARSET_INFO */
+
/*
There is a hard limit for the maximum number of keys as there are only
8 bits in the index file header for the number of keys in a table.
@@ -53,8 +55,8 @@ typedef struct st_HA_KEYSEG /* Key-portion */
uint16 bit_pos; /* Position to bit part */
uint16 flag;
uint16 length; /* Keylength */
+ uint16 language;
uint8 type; /* Type of key (for sort) */
- uint8 language;
uint8 null_bit; /* bitmask to test for NULL */
uint8 bit_start,bit_end; /* if bit field */
uint8 bit_length; /* Length of bit part */
diff --git a/include/my_libwrap.h b/include/my_libwrap.h
index 9a8579475fb..8235c00d8f3 100644
--- a/include/my_libwrap.h
+++ b/include/my_libwrap.h
@@ -1,3 +1,6 @@
+#ifndef MY_LIBWRAP_INCLUDED
+#define MY_LIBWRAP_INCLUDED
+
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -25,3 +28,4 @@ extern int my_hosts_access(struct request_info *req);
extern char *my_eval_client(struct request_info *req);
#endif /* HAVE_LIBWRAP */
+#endif /* MY_LIBWRAP_INCLUDED */
diff --git a/include/my_md5.h b/include/my_md5.h
index 6458f27c5cc..782bef8a27a 100644
--- a/include/my_md5.h
+++ b/include/my_md5.h
@@ -1,3 +1,6 @@
+#ifndef MY_MD5_INCLUDED
+#define MY_MD5_INCLUDED
+
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -52,3 +55,5 @@ do { \
my_MD5Update (&ctx, buf, len); \
my_MD5Final (digest, &ctx); \
} while (0)
+
+#endif /* MY_MD__INCLUDED */
diff --git a/include/my_net.h b/include/my_net.h
index 3af79ea3db5..8617f180431 100644
--- a/include/my_net.h
+++ b/include/my_net.h
@@ -24,6 +24,9 @@
#ifndef _my_net_h
#define _my_net_h
+
+#include "my_global.h" /* C_MODE_START, C_MODE_END */
+
C_MODE_START
#include <errno.h>
@@ -43,7 +46,7 @@ C_MODE_START
#include <sys/ioctl.h>
#endif
-#if !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__) && !defined(__NETWARE__)
+#if !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__NETWARE__)
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
@@ -73,11 +76,6 @@ C_MODE_START
#define in_addr_t uint32
#endif
-/* On some operating systems (e.g. Solaris) INADDR_NONE is not defined */
-#ifndef INADDR_NONE
-#define INADDR_NONE -1 /* Error value from inet_addr */
-#endif
-
/* Thread safe or portable version of some functions */
void my_inet_ntoa(struct in_addr in, char *buf);
@@ -86,9 +84,6 @@ void my_inet_ntoa(struct in_addr in, char *buf);
Handling of gethostbyname_r()
*/
-#if !defined(HPUX10)
-struct hostent;
-#endif /* HPUX */
#if !defined(HAVE_GETHOSTBYNAME_R)
struct hostent *my_gethostbyname_r(const char *name,
struct hostent *result, char *buffer,
@@ -118,11 +113,5 @@ struct hostent *my_gethostbyname_r(const char *name,
#define GETHOSTBYNAME_BUFF_SIZE 2048
#endif
-/* On SCO you get a link error when refering to h_errno */
-#ifdef SCO
-#undef h_errno
-#define h_errno errno
-#endif
-
C_MODE_END
#endif
diff --git a/include/my_no_pthread.h b/include/my_no_pthread.h
index 511fac407d5..a805a9151f8 100644
--- a/include/my_no_pthread.h
+++ b/include/my_no_pthread.h
@@ -1,4 +1,7 @@
-/* Copyright (C) 2000 MySQL AB
+#ifndef MY_NO_PTHREAD_INCLUDED
+#define MY_NO_PTHREAD_INCLUDED
+
+/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
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
@@ -14,9 +17,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#if !defined(_my_no_pthread_h) && !defined(THREAD)
-#define _my_no_pthread_h
-
+#ifndef THREAD
/*
This block is to access some thread-related type definitions
@@ -47,6 +48,17 @@
#define rw_unlock(A)
#define rwlock_destroy(A)
+#define mysql_mutex_init(A, B, C) do {} while (0)
+#define mysql_mutex_lock(A) do {} while (0)
+#define mysql_mutex_unlock(A) do {} while (0)
+#define mysql_mutex_destroy(A) do {} while (0)
+
+#define mysql_rwlock_init(A, B, C) do {} while (0)
+#define mysql_rwlock_rdlock(A) do {} while (0)
+#define mysql_rwlock_wrlock(A) do {} while (0)
+#define mysql_rwlock_unlock(A) do {} while (0)
+#define mysql_rwlock_destroy(A) do {} while (0)
+
typedef int my_pthread_once_t;
#define MY_PTHREAD_ONCE_INIT 0
#define MY_PTHREAD_ONCE_DONE 1
@@ -56,3 +68,4 @@ typedef int my_pthread_once_t;
} while(0)
#endif
+#endif /* MY_NO_PTHREAD_INCLUDED */
diff --git a/include/my_pthread.h b/include/my_pthread.h
index e9256610ea7..e41abba950e 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
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
@@ -18,6 +18,8 @@
#ifndef _my_pthread_h
#define _my_pthread_h
+#include "my_global.h" /* myf */
+
#ifndef ETIME
#define ETIME ETIMEDOUT /* For FreeBSD */
#endif
@@ -31,11 +33,10 @@ extern "C" {
#if defined(__WIN__)
typedef CRITICAL_SECTION pthread_mutex_t;
-typedef HANDLE pthread_t;
+typedef DWORD pthread_t;
typedef struct thread_attr {
DWORD dwStackSize ;
DWORD dwCreatingFlag ;
- int priority ;
} pthread_attr_t ;
typedef struct { int dummy; } pthread_condattr_t;
@@ -64,8 +65,7 @@ typedef struct {
typedef int pthread_mutexattr_t;
-#define win_pthread_self my_thread_var->pthread_self
-#define pthread_self() win_pthread_self
+#define pthread_self() GetCurrentThreadId()
#define pthread_handler_t EXTERNC void * __cdecl
typedef void * (__cdecl *pthread_handler)(void *);
@@ -104,10 +104,22 @@ struct timespec {
(ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
}
-void win_pthread_init(void);
-int win_pthread_setspecific(void *A,void *B,uint length);
+/**
+ Compare two timespec structs.
+
+ @retval 1 If TS1 ends after TS2.
+
+ @retval 0 If TS1 is equal to TS2.
+
+ @retval -1 If TS1 ends before TS2.
+*/
+#define cmp_timespec(TS1, TS2) \
+ ((TS1.tv.i64 > TS2.tv.i64) ? 1 : \
+ ((TS1.tv.i64 < TS2.tv.i64) ? -1 : 0))
+
+
int win_pthread_mutex_trylock(pthread_mutex_t *mutex);
-int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *);
+int pthread_create(pthread_t *, const pthread_attr_t *, pthread_handler, void *);
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
@@ -117,69 +129,50 @@ int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_attr_init(pthread_attr_t *connect_att);
int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack);
-int pthread_attr_setprio(pthread_attr_t *connect_att,int priority);
int pthread_attr_destroy(pthread_attr_t *connect_att);
int my_pthread_once(my_pthread_once_t *once_control,void (*init_routine)(void));
struct tm *localtime_r(const time_t *timep,struct tm *tmp);
struct tm *gmtime_r(const time_t *timep,struct tm *tmp);
+void pthread_exit(void *a);
+int pthread_join(pthread_t thread, void **value_ptr);
+int pthread_cancel(pthread_t thread);
-void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
-
+#ifndef ETIMEDOUT
#define ETIMEDOUT 145 /* Win32 doesn't have this */
-#define getpid() GetCurrentThreadId()
+#endif
#define HAVE_LOCALTIME_R 1
#define _REENTRANT 1
#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
-/*
- Windows has two ways to use thread local storage. The most efficient
- is using __declspec(thread), but that does not work properly when
- used in a .dll that is loaded at runtime, after program load. So for
- libmysql.dll and libmysqld.dll we define USE_TLS in order to use the
- TlsXxx() API instead, which works in all cases.
-*/
-#ifdef USE_TLS /* For LIBMYSQL.DLL */
+
#undef SAFE_MUTEX /* This will cause conflicts */
#define pthread_key(T,V) DWORD V
#define pthread_key_create(A,B) ((*A=TlsAlloc())==0xFFFFFFFF)
#define pthread_key_delete(A) TlsFree(A)
+#define my_pthread_setspecific_ptr(T,V) (!TlsSetValue((T),(V)))
+#define pthread_setspecific(A,B) (!TlsSetValue((A),(B)))
#define pthread_getspecific(A) (TlsGetValue(A))
#define my_pthread_getspecific(T,A) ((T) TlsGetValue(A))
#define my_pthread_getspecific_ptr(T,V) ((T) TlsGetValue(V))
-#define my_pthread_setspecific_ptr(T,V) (!TlsSetValue((T),(V)))
-#define pthread_setspecific(A,B) (!TlsSetValue((A),(B)))
-#else
-#define pthread_key(T,V) __declspec(thread) T V
-#define pthread_key_create(A,B) pthread_dummy(0)
-#define pthread_key_delete(A) pthread_dummy(0)
-#define pthread_getspecific(A) (&(A))
-#define my_pthread_getspecific(T,A) (&(A))
-#define my_pthread_getspecific_ptr(T,V) (V)
-#define my_pthread_setspecific_ptr(T,V) ((T)=(V),0)
-#define pthread_setspecific(A,B) win_pthread_setspecific(&(A),(B),sizeof(A))
-#endif /* USE_TLS */
#define pthread_equal(A,B) ((A) == (B))
#define pthread_mutex_init(A,B) (InitializeCriticalSection(A),0)
#define pthread_mutex_lock(A) (EnterCriticalSection(A),0)
#define pthread_mutex_trylock(A) win_pthread_mutex_trylock((A))
-#define pthread_mutex_unlock(A) LeaveCriticalSection(A)
-#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
-#define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B))
+#define pthread_mutex_unlock(A) (LeaveCriticalSection(A), 0)
+#define pthread_mutex_destroy(A) (DeleteCriticalSection(A), 0)
#define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH)
-#define pthread_join(A,B) (WaitForSingleObject((A), INFINITE) != WAIT_OBJECT_0)
/* Dummy defines for easier code */
#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
-#define my_pthread_attr_setprio(A,B) pthread_attr_setprio(A,B)
#define pthread_attr_setscope(A,B)
#define pthread_detach_this_thread()
#define pthread_condattr_init(A)
#define pthread_condattr_destroy(A)
-
-#define my_pthread_getprio(thread_id) pthread_dummy(0)
+#define pthread_yield() SwitchToThread()
+#define my_sigset(A,B) signal(A,B)
#else /* Normal threads */
@@ -207,8 +200,6 @@ void my_pthread_exit(void *status);
#define pthread_exit(A) my_pthread_exit(A)
#endif
-extern int my_pthread_getprio(pthread_t thread_id);
-
#define pthread_key(T,V) pthread_key_t V
#define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,(V))
#define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,(void*) (V))
@@ -284,26 +275,6 @@ int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */
#define my_sigset(A,B) signal((A),(B))
#endif
-#ifndef my_pthread_setprio
-#if defined(HAVE_PTHREAD_SETPRIO_NP) /* FSU threads */
-#define my_pthread_setprio(A,B) pthread_setprio_np((A),(B))
-#elif defined(HAVE_PTHREAD_SETPRIO)
-#define my_pthread_setprio(A,B) pthread_setprio((A),(B))
-#elif defined(HAVE_PTHREAD_SETSCHEDPRIO)
-#define my_pthread_setprio(A,B) pthread_setschedprio((A),(B))
-#else
-extern void my_pthread_setprio(pthread_t thread_id,int prior);
-#endif
-#endif
-
-#ifndef my_pthread_attr_setprio
-#ifdef HAVE_PTHREAD_ATTR_SETPRIO
-#define my_pthread_attr_setprio(A,B) pthread_attr_setprio((A),(B))
-#else
-extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority);
-#endif
-#endif
-
#if !defined(HAVE_PTHREAD_ATTR_SETSCOPE) || defined(HAVE_DEC_3_2_THREADS)
#define pthread_attr_setscope(A,B)
#undef HAVE_GETHOSTBYADDR_R /* No definition */
@@ -409,6 +380,17 @@ void my_pthread_attr_getstacksize(pthread_attr_t *attrib, size_t *size);
int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
#endif
+#if !defined(HAVE_PTHREAD_YIELD_ONE_ARG) && !defined(HAVE_PTHREAD_YIELD_ZERO_ARG)
+/* no pthread_yield() available */
+#ifdef HAVE_SCHED_YIELD
+#define pthread_yield() sched_yield()
+#elif defined(HAVE_PTHREAD_YIELD_NP) /* can be Mac OS X */
+#define pthread_yield() pthread_yield_np()
+#elif defined(HAVE_THR_YIELD)
+#define pthread_yield() thr_yield()
+#endif
+#endif
+
/*
The defines set_timespec and set_timespec_nsec should be used
for calculating an absolute time at which
@@ -450,6 +432,33 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
#endif /* !set_timespec_nsec */
#endif /* HAVE_TIMESPEC_TS_SEC */
+/**
+ Compare two timespec structs.
+
+ @retval 1 If TS1 ends after TS2.
+
+ @retval 0 If TS1 is equal to TS2.
+
+ @retval -1 If TS1 ends before TS2.
+*/
+#ifdef HAVE_TIMESPEC_TS_SEC
+#ifndef cmp_timespec
+#define cmp_timespec(TS1, TS2) \
+ ((TS1.ts_sec > TS2.ts_sec || \
+ (TS1.ts_sec == TS2.ts_sec && TS1.ts_nsec > TS2.ts_nsec)) ? 1 : \
+ ((TS1.ts_sec < TS2.ts_sec || \
+ (TS1.ts_sec == TS2.ts_sec && TS1.ts_nsec < TS2.ts_nsec)) ? -1 : 0))
+#endif /* !cmp_timespec */
+#else
+#ifndef cmp_timespec
+#define cmp_timespec(TS1, TS2) \
+ ((TS1.tv_sec > TS2.tv_sec || \
+ (TS1.tv_sec == TS2.tv_sec && TS1.tv_nsec > TS2.tv_nsec)) ? 1 : \
+ ((TS1.tv_sec < TS2.tv_sec || \
+ (TS1.tv_sec == TS2.tv_sec && TS1.tv_nsec < TS2.tv_nsec)) ? -1 : 0))
+#endif /* !cmp_timespec */
+#endif /* HAVE_TIMESPEC_TS_SEC */
+
/* safe_mutex adds checking to mutex for easier debugging */
#if defined(__NETWARE__) && !defined(SAFE_MUTEX_DETECT_DESTROY)
@@ -593,30 +602,76 @@ int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp);
#define my_rwlock_init(A,B) rwlock_init((A),USYNC_THREAD,0)
#else
/* Use our own version of read/write locks */
-typedef struct _my_rw_lock_t {
- pthread_mutex_t lock; /* lock for structure */
- pthread_cond_t readers; /* waiting readers */
- pthread_cond_t writers; /* waiting writers */
- int state; /* -1:writer,0:free,>0:readers */
- int waiters; /* number of waiting writers */
-} my_rw_lock_t;
-
+#define NEED_MY_RW_LOCK 1
#define rw_lock_t my_rw_lock_t
+#define my_rwlock_init(A,B) my_rw_init((A), 0)
#define rw_rdlock(A) my_rw_rdlock((A))
#define rw_wrlock(A) my_rw_wrlock((A))
#define rw_tryrdlock(A) my_rw_tryrdlock((A))
#define rw_trywrlock(A) my_rw_trywrlock((A))
#define rw_unlock(A) my_rw_unlock((A))
-#define rwlock_destroy(A) my_rwlock_destroy((A))
+#define rwlock_destroy(A) my_rw_destroy((A))
+#endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */
+
+
+/*
+ Portable read-write locks which prefer readers.
+
+ Required by some algorithms in order to provide correctness.
+*/
+
+#if defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP)
+/*
+ On systems which have a way to specify that readers should
+ be preferred through attribute mechanism (e.g. Linux) we use
+ system implementation of read/write locks.
+*/
+#define rw_pr_lock_t pthread_rwlock_t
+extern int rw_pr_init(rw_pr_lock_t *);
+#define rw_pr_rdlock(A) pthread_rwlock_rdlock(A)
+#define rw_pr_wrlock(A) pthread_rwlock_wrlock(A)
+#define rw_pr_tryrdlock(A) pthread_rwlock_tryrdlock(A)
+#define rw_pr_trywrlock(A) pthread_rwlock_trywrlock(A)
+#define rw_pr_unlock(A) pthread_rwlock_unlock(A)
+#define rw_pr_destroy(A) pthread_rwlock_destroy(A)
+#else
+/* Otherwise we have to use our own implementation of read/write locks. */
+#define NEED_MY_RW_LOCK 1
+struct st_my_rw_lock_t;
+#define rw_pr_lock_t my_rw_lock_t
+extern int rw_pr_init(struct st_my_rw_lock_t *);
+#define rw_pr_rdlock(A) my_rw_rdlock((A))
+#define rw_pr_wrlock(A) my_rw_wrlock((A))
+#define rw_pr_tryrdlock(A) my_rw_tryrdlock((A))
+#define rw_pr_trywrlock(A) my_rw_trywrlock((A))
+#define rw_pr_unlock(A) my_rw_unlock((A))
+#define rw_pr_destroy(A) my_rw_destroy((A))
+#endif /* defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP) */
+
+
+#ifdef NEED_MY_RW_LOCK
+/*
+ On systems which don't support native read/write locks, or don't support
+ read/write locks which prefer readers we have to use own implementation.
+*/
+typedef struct st_my_rw_lock_t {
+ pthread_mutex_t lock; /* lock for structure */
+ pthread_cond_t readers; /* waiting readers */
+ pthread_cond_t writers; /* waiting writers */
+ int state; /* -1:writer,0:free,>0:readers */
+ int waiters; /* number of waiting writers */
+ my_bool prefer_readers;
+} my_rw_lock_t;
-extern int my_rwlock_init(my_rw_lock_t *, void *);
-extern int my_rwlock_destroy(my_rw_lock_t *);
+extern int my_rw_init(my_rw_lock_t *, my_bool *);
+extern int my_rw_destroy(my_rw_lock_t *);
extern int my_rw_rdlock(my_rw_lock_t *);
extern int my_rw_wrlock(my_rw_lock_t *);
extern int my_rw_unlock(my_rw_lock_t *);
extern int my_rw_tryrdlock(my_rw_lock_t *);
extern int my_rw_trywrlock(my_rw_lock_t *);
-#endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */
+#endif /* NEED_MY_RW_LOCK */
+
#define GETHOSTBYADDR_BUFF_SIZE 2048
@@ -650,6 +705,8 @@ extern pthread_mutexattr_t my_errorcheck_mutexattr;
typedef ulong my_thread_id;
extern my_bool my_thread_global_init(void);
+extern my_bool my_thread_basic_global_init(void);
+extern void my_thread_basic_global_reinit(void);
extern void my_thread_global_end(void);
extern my_bool my_thread_init(void);
extern void my_thread_end(void);
@@ -673,13 +730,17 @@ extern int pthread_dummy(int);
#endif
#endif
+#include <mysql/psi/mysql_thread.h>
+
+#define INSTRUMENT_ME 0
+
struct st_my_thread_var
{
int thr_errno;
- pthread_cond_t suspend;
- pthread_mutex_t mutex;
- pthread_mutex_t * volatile current_mutex;
- pthread_cond_t * volatile current_cond;
+ mysql_cond_t suspend;
+ mysql_mutex_t mutex;
+ mysql_mutex_t * volatile current_mutex;
+ mysql_cond_t * volatile current_cond;
pthread_t pthread_self;
my_thread_id id;
int cmp_length;
@@ -687,6 +748,7 @@ struct st_my_thread_var
my_bool init;
struct st_my_thread_var *next,**prev;
void *opt_info;
+ void *stack_ends_here;
#ifndef DBUG_OFF
void *dbug;
char name[THREAD_NAME_SIZE+1];
@@ -694,6 +756,7 @@ struct st_my_thread_var
};
extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
+extern void **my_thread_var_dbug();
extern uint my_thread_end_wait_time;
#define my_thread_var (_my_thread_var())
#define my_errno my_thread_var->thr_errno
@@ -722,23 +785,30 @@ extern uint thd_lib_detected;
Warning:
When compiling without threads, this file is not included.
See the *other* declarations of thread_safe_xxx in include/my_global.h
-
- Second warning:
- See include/config-win.h, for yet another implementation.
*/
#ifdef THREAD
#ifndef thread_safe_increment
+#ifdef _WIN32
+#define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V))
+#define thread_safe_decrement(V,L) InterlockedDecrement((long*) &(V))
+#else
#define thread_safe_increment(V,L) \
- (pthread_mutex_lock((L)), (V)++, pthread_mutex_unlock((L)))
+ (mysql_mutex_lock((L)), (V)++, mysql_mutex_unlock((L)))
#define thread_safe_decrement(V,L) \
- (pthread_mutex_lock((L)), (V)--, pthread_mutex_unlock((L)))
+ (mysql_mutex_lock((L)), (V)--, mysql_mutex_unlock((L)))
+#endif
#endif
#ifndef thread_safe_add
+#ifdef _WIN32
+#define thread_safe_add(V,C,L) InterlockedExchangeAdd((long*) &(V),(C))
+#define thread_safe_sub(V,C,L) InterlockedExchangeAdd((long*) &(V),-(long) (C))
+#else
#define thread_safe_add(V,C,L) \
- (pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L)))
+ (mysql_mutex_lock((L)), (V)+=(C), mysql_mutex_unlock((L)))
#define thread_safe_sub(V,C,L) \
- (pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L)))
+ (mysql_mutex_lock((L)), (V)-=(C), mysql_mutex_unlock((L)))
+#endif
#endif
#endif
diff --git a/include/my_rdtsc.h b/include/my_rdtsc.h
new file mode 100644
index 00000000000..81bc1aafb58
--- /dev/null
+++ b/include/my_rdtsc.h
@@ -0,0 +1,129 @@
+/* Copyright (C) 2008, 2009 Sun Microsystems, Inc
+
+ 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 */
+
+/*
+ rdtsc3 -- multi-platform timer code
+ pgulutzan@mysql.com, 2005-08-29
+ modified 2008-11-02
+*/
+
+#ifndef MY_RDTSC_H
+#define MY_RDTSC_H
+
+/**
+ Characteristics of a timer.
+*/
+struct my_timer_unit_info
+{
+ /** Routine used for the timer. */
+ ulonglong routine;
+ /** Overhead of the timer. */
+ ulonglong overhead;
+ /** Frequency of the timer. */
+ ulonglong frequency;
+ /** Resolution of the timer. */
+ ulonglong resolution;
+};
+
+/**
+ Characteristics of all the supported timers.
+ @sa my_timer_init().
+*/
+struct my_timer_info
+{
+ /** Characteristics of the cycle timer. */
+ struct my_timer_unit_info cycles;
+ /** Characteristics of the nanosecond timer. */
+ struct my_timer_unit_info nanoseconds;
+ /** Characteristics of the microsecond timer. */
+ struct my_timer_unit_info microseconds;
+ /** Characteristics of the millisecond timer. */
+ struct my_timer_unit_info milliseconds;
+ /** Characteristics of the tick timer. */
+ struct my_timer_unit_info ticks;
+};
+
+typedef struct my_timer_info MY_TIMER_INFO;
+
+C_MODE_START
+
+/**
+ A cycle timer.
+ @return the current timer value, in cycles.
+*/
+ulonglong my_timer_cycles(void);
+
+/**
+ A namoseconds timer.
+ @return the current timer value, in nanoseconds.
+*/
+ulonglong my_timer_nanoseconds(void);
+
+/**
+ A microseconds timer.
+ @return the current timer value, in microseconds.
+*/
+ulonglong my_timer_microseconds(void);
+
+/**
+ A millisecond timer.
+ @return the current timer value, in milliseconds.
+*/
+ulonglong my_timer_milliseconds(void);
+
+/**
+ A ticks timer.
+ @return the current timer value, in ticks.
+*/
+ulonglong my_timer_ticks(void);
+
+/**
+ Timer initialization function.
+ @param [out] mti the timer characteristics.
+*/
+void my_timer_init(MY_TIMER_INFO *mti);
+
+C_MODE_END
+
+#define MY_TIMER_ROUTINE_ASM_X86 1
+#define MY_TIMER_ROUTINE_ASM_X86_64 2
+#define MY_TIMER_ROUTINE_RDTSCLL 3
+#define MY_TIMER_ROUTINE_ASM_X86_WIN 4
+#define MY_TIMER_ROUTINE_RDTSC 5
+#define MY_TIMER_ROUTINE_ASM_IA64 6
+#define MY_TIMER_ROUTINE_ASM_PPC 7
+#define MY_TIMER_ROUTINE_SGI_CYCLE 8
+#define MY_TIMER_ROUTINE_GETHRTIME 9
+#define MY_TIMER_ROUTINE_READ_REAL_TIME 10
+#define MY_TIMER_ROUTINE_CLOCK_GETTIME 11
+#define MY_TIMER_ROUTINE_NXGETTIME 12
+#define MY_TIMER_ROUTINE_GETTIMEOFDAY 13
+#define MY_TIMER_ROUTINE_QUERYPERFORMANCECOUNTER 14
+#define MY_TIMER_ROUTINE_GETTICKCOUNT 15
+#define MY_TIMER_ROUTINE_TIME 16
+#define MY_TIMER_ROUTINE_TIMES 17
+#define MY_TIMER_ROUTINE_FTIME 18
+#define MY_TIMER_ROUTINE_ASM_PPC64 19
+#define MY_TIMER_ROUTINE_ASM_SUNPRO_SPARC64 20
+#define MY_TIMER_ROUTINE_ASM_SUNPRO_SPARC32 21
+#define MY_TIMER_ROUTINE_ASM_SUNPRO_I386 22
+#define MY_TIMER_ROUTINE_ASM_GCC_SPARC64 23
+#define MY_TIMER_ROUTINE_ASM_GCC_SPARC32 24
+#define MY_TIMER_ROUTINE_MACH_ABSOLUTE_TIME 25
+#define MY_TIMER_ROUTINE_GETSYSTEMTIMEASFILETIME 26
+#define MY_TIMER_ROUTINE_ASM_SUNPRO_X86_64 27
+
+#endif
+
diff --git a/include/my_sys.h b/include/my_sys.h
index 59b44307b6f..ac10628f943 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc
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
@@ -15,6 +15,9 @@
#ifndef _my_sys_h
#define _my_sys_h
+
+#include "my_global.h" /* C_MODE_START, C_MODE_END */
+
C_MODE_START
#ifdef HAVE_AIOWAIT
@@ -34,11 +37,25 @@ extern int NEAR my_errno; /* Last error in mysys */
#include <m_ctype.h> /* for CHARSET_INFO */
#include <stdarg.h>
#include <typelib.h>
+#ifdef _WIN32
+#include <malloc.h> /*for alloca*/
+#endif
#define MYSYS_PROGRAM_USES_CURSES() { error_handler_hook = my_message_curses; mysys_uses_curses=1; }
#define MYSYS_PROGRAM_DONT_USE_CURSES() { error_handler_hook = my_message_no_curses; mysys_uses_curses=0;}
#define MY_INIT(name); { my_progname= name; my_init(); }
+/**
+ Max length of an error message generated by mysys utilities.
+ Some mysys functions produce error messages. These mostly go
+ to stderr.
+ This constant defines the size of the buffer used to format
+ the message. It should be kept in sync with MYSQL_ERRMSG_SIZE,
+ since sometimes mysys errors are stored in the server diagnostics
+ area, and we would like to avoid unexpected truncation.
+*/
+#define MYSYS_ERRMSG_SIZE (512)
+
#define MY_FILE_ERROR ((size_t) -1)
/* General bitmaps for my_func's */
@@ -49,7 +66,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_WME 16 /* Write message on error */
#define MY_WAIT_IF_FULL 32 /* Wait and try again if disk full error */
#define MY_IGNORE_BADFD 32 /* my_sync: ignore 'bad descriptor' errors */
-#define MY_SYNC_DIR 1024 /* my_create/delete/rename: sync directory */
+#define MY_SYNC_DIR 8192 /* my_create/delete/rename: sync directory */
#define MY_RAID 64 /* Support for RAID */
#define MY_FULL_IO 512 /* For my_read - loop intil I/O is complete */
#define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */
@@ -90,8 +107,6 @@ extern int NEAR my_errno; /* Last error in mysys */
#define ME_COLOUR2 ((2 << ME_HIGHBYTE))
#define ME_COLOUR3 ((3 << ME_HIGHBYTE))
#define ME_FATALERROR 1024 /* Fatal statement error */
-#define ME_NO_WARNING_FOR_ERROR 2048 /* Don't push a warning for error */
-#define ME_NO_SP_HANDLER 4096 /* Don't call stored routine error handlers */
/* Bits in last argument to fn_format */
#define MY_REPLACE_DIR 1 /* replace dir in name with 'dir' */
@@ -220,20 +235,24 @@ extern int errno; /* declare errno */
extern char *home_dir; /* Home directory for user */
extern const char *my_progname; /* program-name (printed in errors) */
extern char NEAR curr_dir[]; /* Current directory for user */
-extern int (*error_handler_hook)(uint my_err, const char *str,myf MyFlags);
-extern int (*fatal_error_handler_hook)(uint my_err, const char *str,
+extern void (*error_handler_hook)(uint my_err, const char *str,myf MyFlags);
+extern void (*fatal_error_handler_hook)(uint my_err, const char *str,
myf MyFlags);
extern uint my_file_limit;
extern ulong my_thread_stack_size;
+extern const char *(*proc_info_hook)(void *, const char *, const char *,
+ const char *, const unsigned int);
+
#ifdef HAVE_LARGE_PAGES
extern my_bool my_use_large_pages;
extern uint my_large_page_size;
#endif
/* charsets */
+#define MY_ALL_CHARSETS_SIZE 2048
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *default_charset_info;
-extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *all_charsets[256];
+extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *all_charsets[MY_ALL_CHARSETS_SIZE];
extern CHARSET_INFO compiled_charsets[];
/* statistics */
@@ -321,10 +340,14 @@ enum file_type
struct st_my_file_info
{
- char * name;
- enum file_type type;
-#if defined(THREAD) && !defined(HAVE_PREAD)
- pthread_mutex_t mutex;
+ char *name;
+#ifdef _WIN32
+ HANDLE fhandle; /* win32 file handle */
+ int oflag; /* open flags, e.g O_APPEND */
+#endif
+ enum file_type type;
+#if defined(THREAD) && !defined(HAVE_PREAD) && !defined(_WIN32)
+ mysql_mutex_t mutex;
#endif
};
@@ -344,7 +367,7 @@ typedef struct st_my_tmpdir
char **list;
uint cur, max;
#ifdef THREAD
- pthread_mutex_t mutex;
+ mysql_mutex_t mutex;
#endif
} MY_TMPDIR;
@@ -360,9 +383,9 @@ typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*);
#ifdef THREAD
typedef struct st_io_cache_share
{
- pthread_mutex_t mutex; /* To sync on reads into buffer. */
- pthread_cond_t cond; /* To wait for signals. */
- pthread_cond_t cond_writer; /* For a synchronized writer. */
+ mysql_mutex_t mutex; /* To sync on reads into buffer. */
+ mysql_cond_t cond; /* To wait for signals. */
+ mysql_cond_t cond_writer; /* For a synchronized writer. */
/* Offset in file corresponding to the first byte of buffer. */
my_off_t pos_in_file;
/* If a synchronized write cache is the source of the data. */
@@ -423,7 +446,7 @@ typedef struct st_io_cache /* Used when cacheing files */
The lock is for append buffer used in SEQ_READ_APPEND cache
need mutex copying from append buffer to read buffer.
*/
- pthread_mutex_t append_buffer_lock;
+ mysql_mutex_t append_buffer_lock;
/*
The following is used when several threads are reading the
same file in parallel. They are synchronized on disk
@@ -628,43 +651,56 @@ extern void *my_memmem(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen);
-#ifdef __WIN__
-extern int my_access(const char *path, int amode);
-extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
+#ifdef _WIN32
+extern int my_access(const char *path, int amode);
#else
#define my_access access
#endif
+
extern int check_if_legal_filename(const char *path);
extern int check_if_legal_tablename(const char *path);
-#if defined(__WIN__) && defined(__NT__)
+#ifdef _WIN32
extern int nt_share_delete(const char *name,myf MyFlags);
#define my_delete_allow_opened(fname,flags) nt_share_delete((fname),(flags))
#else
#define my_delete_allow_opened(fname,flags) my_delete((fname),(flags))
#endif
+#ifdef _WIN32
+/* Windows-only functions (CRT equivalents)*/
+extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
+extern HANDLE my_get_osfhandle(File fd);
+extern void my_osmaperr(unsigned long last_error);
+#endif
+
#ifndef TERMINATE
extern void TERMINATE(FILE *file, uint flag);
#endif
extern void init_glob_errs(void);
+extern const char** get_global_errmsgs();
extern void wait_for_free_space(const char *filename, int errors);
extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags);
extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
extern int my_fclose(FILE *fd,myf MyFlags);
+extern File my_fileno(FILE *fd);
extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
extern int my_sync(File fd, myf my_flags);
extern int my_sync_dir(const char *dir_name, myf my_flags);
extern int my_sync_dir_by_file(const char *file_name, myf my_flags);
-extern int my_error _VARARGS((int nr,myf MyFlags, ...));
-extern int my_printf_error _VARARGS((uint my_err, const char *format,
- myf MyFlags, ...))
- ATTRIBUTE_FORMAT(printf, 2, 4);
-extern int my_error_register(const char **errmsgs, int first, int last);
+extern void my_error _VARARGS((int nr,myf MyFlags, ...));
+extern void my_printf_error _VARARGS((uint my_err, const char *format,
+ myf MyFlags, ...))
+ ATTRIBUTE_FORMAT(printf, 2, 4);
+extern void my_printv_error(uint error, const char *format, myf MyFlags,
+ va_list ap);
+extern int my_error_register(const char** (*get_errmsgs) (),
+ int first, int last);
extern const char **my_error_unregister(int first, int last);
-extern int my_message(uint my_err, const char *str,myf MyFlags);
-extern int my_message_no_curses(uint my_err, const char *str,myf MyFlags);
-extern int my_message_curses(uint my_err, const char *str,myf MyFlags);
+extern void my_message(uint my_err, const char *str,myf MyFlags);
+extern void my_message_no_curses(uint my_err, const char *str,myf MyFlags);
+extern void my_message_curses(uint my_err, const char *str,myf MyFlags);
+extern my_bool my_basic_init(void);
extern my_bool my_init(void);
extern void my_end(int infoflag);
extern int my_redel(const char *from, const char *to, int MyFlags);
@@ -853,6 +889,7 @@ extern void *memdup_root(MEM_ROOT *root,const void *str, size_t len);
extern int get_defaults_options(int argc, char **argv,
char **defaults, char **extra_defaults,
char **group_suffix);
+extern const char *args_separator;
extern int my_load_defaults(const char *conf_file, const char **groups,
int *argc, char ***argv, const char ***);
extern int load_defaults(const char *conf_file, const char **groups,
@@ -990,5 +1027,15 @@ void netware_reg_user(const char *ip, const char *user,
const char *application);
#endif
+#include <mysql/psi/psi.h>
+
+#ifdef HAVE_PSI_INTERFACE
+extern MYSQL_PLUGIN_IMPORT struct PSI_bootstrap *PSI_hook;
+void my_init_mysys_psi_keys(void);
+#endif
+
+struct st_mysql_file;
+extern struct st_mysql_file *mysql_stdin;
+
C_MODE_END
#endif /* _my_sys_h */
diff --git a/include/my_time.h b/include/my_time.h
index 58995f1bf62..829cb706bb6 100644
--- a/include/my_time.h
+++ b/include/my_time.h
@@ -74,12 +74,12 @@ typedef long my_time_t;
TIME_MAX_MINUTE * 60L + TIME_MAX_SECOND)
my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
- ulong flags, int *was_cut);
+ ulonglong flags, int *was_cut);
enum enum_mysql_timestamp_type
str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
- uint flags, int *was_cut);
+ ulonglong flags, int *was_cut);
longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
- uint flags, int *was_cut);
+ ulonglong flags, int *was_cut);
ulonglong TIME_to_ulonglong_datetime(const MYSQL_TIME *);
ulonglong TIME_to_ulonglong_date(const MYSQL_TIME *);
ulonglong TIME_to_ulonglong_time(const MYSQL_TIME *);
diff --git a/include/my_tree.h b/include/my_tree.h
index 24bbdd54019..0958a37fb4c 100644
--- a/include/my_tree.h
+++ b/include/my_tree.h
@@ -20,6 +20,7 @@ extern "C" {
#endif
#include "my_base.h" /* get 'enum ha_rkey_function' */
+#include "my_alloc.h" /* MEM_ROOT */
/* Worst case tree is half full. This gives use 2^(MAX_TREE_HEIGHT/2) leafs */
#define MAX_TREE_HEIGHT 64
diff --git a/include/my_uctype.h b/include/my_uctype.h
index 9aaf478810c..580eb646e11 100644
--- a/include/my_uctype.h
+++ b/include/my_uctype.h
@@ -1,3 +1,6 @@
+#ifndef MY_UCTYPE_INCLUDED
+#define MY_UCTYPE_INCLUDED
+
/* Copyright (C) 2006 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -1477,3 +1480,4 @@ MY_UNI_CTYPE my_uni_ctype[256]={
};
+#endif /* MY_UCTYPE_INCLUDED */
diff --git a/include/myisam.h b/include/myisam.h
index 5334fd6afc4..d590a29c1b3 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
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
@@ -162,7 +162,7 @@ typedef struct st_mi_create_info
ulonglong data_file_length;
ulonglong key_file_length;
uint old_options;
- uint8 language;
+ uint16 language;
my_bool with_auto_increment;
} MI_CREATE_INFO;
@@ -251,7 +251,7 @@ typedef struct st_columndef /* column information */
extern char * myisam_log_filename; /* Name of logfile */
extern ulong myisam_block_size;
-extern ulong myisam_concurrent_insert;
+extern uint myisam_concurrent_insert;
extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user;
extern my_off_t myisam_max_temp_length;
extern ulong myisam_bulk_insert_tree_size, myisam_data_pointer_size;
@@ -260,7 +260,7 @@ extern ulong myisam_bulk_insert_tree_size, myisam_data_pointer_size;
/* which is normally forbidden */
extern int (*myisam_test_invalid_symlink)(const char *filename);
extern ulonglong myisam_mmap_size, myisam_mmap_used;
-extern pthread_mutex_t THR_LOCK_myisam_mmap;
+extern mysql_mutex_t THR_LOCK_myisam_mmap;
/* Prototypes for myisam-functions */
@@ -413,7 +413,7 @@ typedef struct st_mi_check_param
uint out_flag,warning_printed,error_printed,verbose;
uint opt_sort_key,total_files,max_level;
uint testflag, key_cache_block_size;
- uint8 language;
+ uint16 language;
my_bool using_global_keycache, opt_lock_memory, opt_follow_links;
my_bool retry_repair, force_sort;
char temp_filename[FN_REFLEN],*isam_file_name;
@@ -436,7 +436,7 @@ typedef struct st_mi_check_param
const char *op_name;
enum_mi_stats_method stats_method;
#ifdef THREAD
- pthread_mutex_t print_msg_mutex;
+ mysql_mutex_t print_msg_mutex;
my_bool need_print_msg_lock;
#endif
} MI_CHECK;
@@ -463,8 +463,8 @@ typedef struct st_sort_info
/* sync things */
uint got_error, threads_running;
#ifdef THREAD
- pthread_mutex_t mutex;
- pthread_cond_t cond;
+ mysql_mutex_t mutex;
+ mysql_cond_t cond;
#endif
} SORT_INFO;
diff --git a/include/myisammrg.h b/include/myisammrg.h
index 31ce3fa47b8..3277510705b 100644
--- a/include/myisammrg.h
+++ b/include/myisammrg.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
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
@@ -75,7 +75,7 @@ typedef struct st_myrg_info
LIST open_list;
QUEUE by_key;
ulong *rec_per_key_part; /* for sql optimizing */
- pthread_mutex_t mutex;
+ mysql_mutex_t mutex;
} MYRG_INFO;
diff --git a/include/myisampack.h b/include/myisampack.h
index 7d4871bd1cb..ecf35520a88 100644
--- a/include/myisampack.h
+++ b/include/myisampack.h
@@ -1,3 +1,6 @@
+#ifndef MYISAMPACK_INCLUDED
+#define MYISAMPACK_INCLUDED
+
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -236,3 +239,4 @@
mi_int4store(((T) + 4), A); }}
#define mi_sizekorr(T) mi_uint4korr((uchar*) (T) + 4)
#endif
+#endif /* MYISAMPACK_INCLUDED */
diff --git a/include/mysql.h b/include/mysql.h
index d114afb6c93..452b4374cf7 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -86,9 +86,11 @@ extern char *mysql_unix_port;
#define IS_PRI_KEY(n) ((n) & PRI_KEY_FLAG)
#define IS_NOT_NULL(n) ((n) & NOT_NULL_FLAG)
#define IS_BLOB(n) ((n) & BLOB_FLAG)
-#define IS_NUM(t) ((t) <= MYSQL_TYPE_INT24 || (t) == MYSQL_TYPE_YEAR || (t) == MYSQL_TYPE_NEWDECIMAL)
-#define IS_NUM_FIELD(f) ((f)->flags & NUM_FLAG)
-#define INTERNAL_NUM_FIELD(f) (((f)->type <= MYSQL_TYPE_INT24 && ((f)->type != MYSQL_TYPE_TIMESTAMP || (f)->length == 14 || (f)->length == 8)) || (f)->type == MYSQL_TYPE_YEAR)
+/**
+ Returns true if the value is a number which does not need quotes for
+ the sql_lex.cc parser to parse correctly.
+*/
+#define IS_NUM(t) (((t) <= MYSQL_TYPE_INT24 && (t) != MYSQL_TYPE_TIMESTAMP) || (t) == MYSQL_TYPE_YEAR || (t) == MYSQL_TYPE_NEWDECIMAL)
#define IS_LONGDATA(t) ((t) >= MYSQL_TYPE_TINY_BLOB && (t) <= MYSQL_TYPE_STRING)
@@ -186,24 +188,10 @@ struct st_mysql_options {
unsigned long max_allowed_packet;
my_bool use_ssl; /* if to use SSL or not */
my_bool compress,named_pipe;
- /*
- On connect, find out the replication role of the server, and
- establish connections to all the peers
- */
- my_bool rpl_probe;
- /*
- Each call to mysql_real_query() will parse it to tell if it is a read
- or a write, and direct it to the slave or the master
- */
- my_bool rpl_parse;
- /*
- If set, never read from a master, only from slave, when doing
- a read that is replication-aware
- */
- my_bool no_master_reads;
-#if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY)
- my_bool separate_thread;
-#endif
+ my_bool unused1;
+ my_bool unused2;
+ my_bool unused3;
+ my_bool unused4;
enum mysql_option methods_to_use;
char *client_ip;
/* Refuse client connecting to server if it uses old (pre-4.1.1) protocol */
@@ -230,15 +218,6 @@ enum mysql_protocol_type
MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET,
MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY
};
-/*
- There are three types of queries - the ones that have to go to
- the master, the ones that go to a slave, and the adminstrative
- type which must happen on the pivot connectioin
-*/
-enum mysql_rpl_type
-{
- MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN
-};
typedef struct character_set
{
@@ -283,21 +262,8 @@ typedef struct st_mysql
/* session-wide random string */
char scramble[SCRAMBLE_LENGTH+1];
-
- /*
- Set if this is the original connection, not a master or a slave we have
- added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave()
- */
- my_bool rpl_pivot;
- /*
- Pointers to the master, and the next slave connections, points to
- itself if lone connection.
- */
- struct st_mysql* master, *next_slave;
-
- struct st_mysql* last_used_slave; /* needed for round-robin slave pick */
- /* needed for send/read/store/use result to work correctly with replication */
- struct st_mysql* last_used_con;
+ my_bool unused1;
+ void *unused2, *unused3, *unused4, *unused5;
LIST *stmts; /* list of all statements */
const struct st_mysql_methods *methods;
@@ -331,35 +297,12 @@ typedef struct st_mysql_res {
void *extension;
} MYSQL_RES;
-#define MAX_MYSQL_MANAGER_ERR 256
-#define MAX_MYSQL_MANAGER_MSG 256
-
-#define MANAGER_OK 200
-#define MANAGER_INFO 250
-#define MANAGER_ACCESS 401
-#define MANAGER_CLIENT_ERR 450
-#define MANAGER_INTERNAL_ERR 500
#if !defined(MYSQL_SERVER) && !defined(MYSQL_CLIENT)
#define MYSQL_CLIENT
#endif
-typedef struct st_mysql_manager
-{
- NET net;
- char *host, *user, *passwd;
- char *net_buf, *net_buf_pos, *net_data_end;
- unsigned int port;
- int cmd_status;
- int last_errno;
- int net_buf_size;
- my_bool free_me;
- my_bool eof;
- char last_error[MAX_MYSQL_MANAGER_ERR];
- void *extension;
-} MYSQL_MANAGER;
-
typedef struct st_mysql_parameters
{
unsigned long *p_max_allowed_packet;
@@ -452,16 +395,6 @@ int STDCALL mysql_real_query(MYSQL *mysql, const char *q,
MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql);
MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql);
-/* perform query on master */
-my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q,
- unsigned long length);
-my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q,
- unsigned long length);
-/* perform query on slave */
-my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q,
- unsigned long length);
-my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q,
- unsigned long length);
void STDCALL mysql_get_character_set_info(MYSQL *mysql,
MY_CHARSET_INFO *charset);
@@ -483,37 +416,6 @@ mysql_set_local_infile_handler(MYSQL *mysql,
void
mysql_set_local_infile_default(MYSQL *mysql);
-
-/*
- enable/disable parsing of all queries to decide if they go on master or
- slave
-*/
-void STDCALL mysql_enable_rpl_parse(MYSQL* mysql);
-void STDCALL mysql_disable_rpl_parse(MYSQL* mysql);
-/* get the value of the parse flag */
-int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql);
-
-/* enable/disable reads from master */
-void STDCALL mysql_enable_reads_from_master(MYSQL* mysql);
-void STDCALL mysql_disable_reads_from_master(MYSQL* mysql);
-/* get the value of the master read flag */
-my_bool STDCALL mysql_reads_from_master_enabled(MYSQL* mysql);
-
-enum mysql_rpl_type STDCALL mysql_rpl_query_type(const char* q, int len);
-
-/* discover the master and its slaves */
-my_bool STDCALL mysql_rpl_probe(MYSQL* mysql);
-
-/* set the master, close/free the old one, if it is not a pivot */
-int STDCALL mysql_set_master(MYSQL* mysql, const char* host,
- unsigned int port,
- const char* user,
- const char* passwd);
-int STDCALL mysql_add_slave(MYSQL* mysql, const char* host,
- unsigned int port,
- const char* user,
- const char* passwd);
-
int STDCALL mysql_shutdown(MYSQL *mysql,
enum mysql_enum_shutdown_level
shutdown_level);
@@ -560,18 +462,6 @@ void STDCALL mysql_debug(const char *debug);
void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
unsigned int STDCALL mysql_thread_safe(void);
my_bool STDCALL mysql_embedded(void);
-MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con);
-MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con,
- const char* host,
- const char* user,
- const char* passwd,
- unsigned int port);
-void STDCALL mysql_manager_close(MYSQL_MANAGER* con);
-int STDCALL mysql_manager_command(MYSQL_MANAGER* con,
- const char* cmd, int cmd_len);
-int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con,
- char* res_buf,
- int res_buf_size);
my_bool STDCALL mysql_read_query_result(MYSQL *mysql);
@@ -766,7 +656,7 @@ typedef struct st_mysql_methods
MYSQL_RES * (*use_result)(MYSQL *mysql);
void (*fetch_lengths)(unsigned long *to,
MYSQL_ROW column, unsigned int field_count);
- void (*flush_use_result)(MYSQL *mysql);
+ void (*flush_use_result)(MYSQL *mysql, my_bool flush_all_results);
#if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY)
MYSQL_FIELD * (*list_fields)(MYSQL *mysql);
my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
@@ -826,6 +716,7 @@ my_bool STDCALL mysql_rollback(MYSQL * mysql);
my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode);
my_bool STDCALL mysql_more_results(MYSQL *mysql);
int STDCALL mysql_next_result(MYSQL *mysql);
+int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt);
void STDCALL mysql_close(MYSQL *sock);
@@ -840,7 +731,6 @@ MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host,
const char *user, const char *passwd);
int STDCALL mysql_create_db(MYSQL *mysql, const char *DB);
int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
-#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT)
#endif
#define HAVE_MYSQL_REAL_CONNECT
diff --git a/include/mysql.h.pp b/include/mysql.h.pp
index 633cde41130..4fef9e9ec0b 100644
--- a/include/mysql.h.pp
+++ b/include/mysql.h.pp
@@ -28,15 +28,15 @@ typedef struct st_net {
unsigned int *return_status;
unsigned char reading_or_writing;
char save_char;
- my_bool unused0;
- my_bool unused;
- my_bool compress;
my_bool unused1;
- unsigned char *query_cache_query;
+ my_bool unused2;
+ my_bool compress;
+ my_bool unused3;
+ unsigned char *unused;
unsigned int last_errno;
unsigned char error;
- my_bool unused2;
- my_bool return_errno;
+ my_bool unused4;
+ my_bool unused5;
char last_error[512];
char sqlstate[5 +1];
void *extension;
@@ -233,6 +233,10 @@ extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
extern const char *get_type(TYPELIB *typelib,unsigned int nr);
extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from);
extern TYPELIB sql_protocol_typelib;
+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);
typedef struct st_mysql_rows {
struct st_mysql_rows *next;
MYSQL_ROW data;
@@ -277,10 +281,10 @@ struct st_mysql_options {
unsigned long max_allowed_packet;
my_bool use_ssl;
my_bool compress,named_pipe;
- my_bool rpl_probe;
- my_bool rpl_parse;
- my_bool no_master_reads;
- my_bool separate_thread;
+ my_bool unused1;
+ my_bool unused2;
+ my_bool unused3;
+ my_bool unused4;
enum mysql_option methods_to_use;
char *client_ip;
my_bool secure_auth;
@@ -301,10 +305,6 @@ enum mysql_protocol_type
MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET,
MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY
};
-enum mysql_rpl_type
-{
- MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN
-};
typedef struct character_set
{
unsigned int number;
@@ -344,10 +344,8 @@ typedef struct st_mysql
my_bool free_me;
my_bool reconnect;
char scramble[20 +1];
- my_bool rpl_pivot;
- struct st_mysql* master, *next_slave;
- struct st_mysql* last_used_slave;
- struct st_mysql* last_used_con;
+ my_bool unused1;
+ void *unused2, *unused3, *unused4, *unused5;
LIST *stmts;
const struct st_mysql_methods *methods;
void *thd;
@@ -371,20 +369,6 @@ typedef struct st_mysql_res {
my_bool unbuffered_fetch_cancelled;
void *extension;
} MYSQL_RES;
-typedef struct st_mysql_manager
-{
- NET net;
- char *host, *user, *passwd;
- char *net_buf, *net_buf_pos, *net_data_end;
- unsigned int port;
- int cmd_status;
- int last_errno;
- int net_buf_size;
- my_bool free_me;
- my_bool eof;
- char last_error[256];
- void *extension;
-} MYSQL_MANAGER;
typedef struct st_mysql_parameters
{
unsigned long *p_max_allowed_packet;
@@ -437,14 +421,6 @@ int mysql_real_query(MYSQL *mysql, const char *q,
unsigned long length);
MYSQL_RES * mysql_store_result(MYSQL *mysql);
MYSQL_RES * mysql_use_result(MYSQL *mysql);
-my_bool mysql_master_query(MYSQL *mysql, const char *q,
- unsigned long length);
-my_bool mysql_master_send_query(MYSQL *mysql, const char *q,
- unsigned long length);
-my_bool mysql_slave_query(MYSQL *mysql, const char *q,
- unsigned long length);
-my_bool mysql_slave_send_query(MYSQL *mysql, const char *q,
- unsigned long length);
void mysql_get_character_set_info(MYSQL *mysql,
MY_CHARSET_INFO *charset);
void
@@ -459,22 +435,6 @@ mysql_set_local_infile_handler(MYSQL *mysql,
void *);
void
mysql_set_local_infile_default(MYSQL *mysql);
-void mysql_enable_rpl_parse(MYSQL* mysql);
-void mysql_disable_rpl_parse(MYSQL* mysql);
-int mysql_rpl_parse_enabled(MYSQL* mysql);
-void mysql_enable_reads_from_master(MYSQL* mysql);
-void mysql_disable_reads_from_master(MYSQL* mysql);
-my_bool mysql_reads_from_master_enabled(MYSQL* mysql);
-enum mysql_rpl_type mysql_rpl_query_type(const char* q, int len);
-my_bool mysql_rpl_probe(MYSQL* mysql);
-int mysql_set_master(MYSQL* mysql, const char* host,
- unsigned int port,
- const char* user,
- const char* passwd);
-int mysql_add_slave(MYSQL* mysql, const char* host,
- unsigned int port,
- const char* user,
- const char* passwd);
int mysql_shutdown(MYSQL *mysql,
enum mysql_enum_shutdown_level
shutdown_level);
@@ -521,18 +481,6 @@ void mysql_debug(const char *debug);
void myodbc_remove_escape(MYSQL *mysql,char *name);
unsigned int mysql_thread_safe(void);
my_bool mysql_embedded(void);
-MYSQL_MANAGER* mysql_manager_init(MYSQL_MANAGER* con);
-MYSQL_MANAGER* mysql_manager_connect(MYSQL_MANAGER* con,
- const char* host,
- const char* user,
- const char* passwd,
- unsigned int port);
-void mysql_manager_close(MYSQL_MANAGER* con);
-int mysql_manager_command(MYSQL_MANAGER* con,
- const char* cmd, int cmd_len);
-int mysql_manager_fetch_line(MYSQL_MANAGER* con,
- char* res_buf,
- int res_buf_size);
my_bool mysql_read_query_result(MYSQL *mysql);
enum enum_mysql_stmt_state
{
@@ -616,7 +564,7 @@ typedef struct st_mysql_methods
MYSQL_RES * (*use_result)(MYSQL *mysql);
void (*fetch_lengths)(unsigned long *to,
MYSQL_ROW column, unsigned int field_count);
- void (*flush_use_result)(MYSQL *mysql);
+ void (*flush_use_result)(MYSQL *mysql, my_bool flush_all_results);
MYSQL_FIELD * (*list_fields)(MYSQL *mysql);
my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
int (*stmt_execute)(MYSQL_STMT *stmt);
@@ -671,4 +619,5 @@ my_bool mysql_rollback(MYSQL * mysql);
my_bool mysql_autocommit(MYSQL * mysql, my_bool auto_mode);
my_bool mysql_more_results(MYSQL *mysql);
int mysql_next_result(MYSQL *mysql);
+int mysql_stmt_next_result(MYSQL_STMT *stmt);
void mysql_close(MYSQL *sock);
diff --git a/include/mysql/innodb_priv.h b/include/mysql/innodb_priv.h
new file mode 100644
index 00000000000..993dad7cf99
--- /dev/null
+++ b/include/mysql/innodb_priv.h
@@ -0,0 +1,37 @@
+/* Copyright (c) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef INNODB_PRIV_INCLUDED
+#define INNODB_PRIV_INCLUDED
+
+/** @file Declaring server-internal functions that are used by InnoDB. */
+
+#include <sql_priv.h>
+
+class THD;
+
+uint filename_to_tablename(const char *from, char *to, uint to_length);
+int get_quote_char_for_identifier(THD *thd, const char *name, uint length);
+bool schema_table_store_record(THD *thd, TABLE *table);
+void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
+bool check_global_access(THD *thd, ulong want_access);
+uint strconvert(CHARSET_INFO *from_cs, const char *from,
+ CHARSET_INFO *to_cs, char *to, uint to_length,
+ uint *errors);
+void sql_print_error(const char *format, ...);
+
+
+
+#endif /* INNODB_PRIV_INCLUDED */
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
index 55ef6070f85..19cf0ed050d 100644
--- a/include/mysql/plugin.h
+++ b/include/mysql/plugin.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 MySQL AB
+/* Copyright (C) 2005 MySQL AB, 2009 Sun Microsystems, Inc.
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
@@ -16,13 +16,27 @@
#ifndef _my_plugin_h
#define _my_plugin_h
-
/*
On Windows, exports from DLL need to be declared
-*/
-#if (defined(_WIN32) && defined(MYSQL_DYNAMIC_PLUGIN))
-#define MYSQL_PLUGIN_EXPORT extern "C" __declspec(dllexport)
-#else
+ Also, plugin needs to be declared as extern "C" because MSVC
+ unlike other compilers, uses C++ mangling for variables not only
+ for functions.
+*/
+#if defined(_MSC_VER)
+#if defined(MYSQL_DYNAMIC_PLUGIN)
+ #ifdef __cplusplus
+ #define MYSQL_PLUGIN_EXPORT extern "C" __declspec(dllexport)
+ #else
+ #define MYSQL_PLUGIN_EXPORT __declspec(dllexport)
+ #endif
+#else /* MYSQL_DYNAMIC_PLUGIN */
+ #ifdef __cplusplus
+ #define MYSQL_PLUGIN_EXPORT extern "C"
+ #else
+ #define MYSQL_PLUGIN_EXPORT
+ #endif
+#endif /*MYSQL_DYNAMIC_PLUGIN */
+#else /*_MSC_VER */
#define MYSQL_PLUGIN_EXPORT
#endif
@@ -34,15 +48,7 @@ class Item;
#define MYSQL_THD void*
#endif
-#ifndef _m_string_h
-/* This definition must match the one given in m_string.h */
-struct st_mysql_lex_string
-{
- char *str;
- unsigned int length;
-};
-#endif /* _m_string_h */
-typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
+#include <mysql/services.h>
#define MYSQL_XIDDATASIZE 128
/**
@@ -65,7 +71,7 @@ typedef struct st_mysql_xid MYSQL_XID;
Plugin API. Common for all plugin types.
*/
-#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0100
+#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0101
/*
The allowable types of plugins
@@ -75,7 +81,9 @@ typedef struct st_mysql_xid MYSQL_XID;
#define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */
#define MYSQL_DAEMON_PLUGIN 3 /* The daemon/raw plugin type */
#define MYSQL_INFORMATION_SCHEMA_PLUGIN 4 /* The I_S plugin type */
-#define MYSQL_MAX_PLUGIN_TYPE_NUM 5 /* The number of plugin types */
+#define MYSQL_AUDIT_PLUGIN 5 /* The Audit plugin type */
+#define MYSQL_REPLICATION_PLUGIN 6 /* The replication plugin type */
+#define MYSQL_MAX_PLUGIN_TYPE_NUM 7 /* The number of plugin types */
/* We use the following strings to define licenses for plugins */
#define PLUGIN_LICENSE_PROPRIETARY 0
@@ -95,9 +103,9 @@ typedef struct st_mysql_xid MYSQL_XID;
#ifndef MYSQL_DYNAMIC_PLUGIN
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
-int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION; \
-int PSIZE= sizeof(struct st_mysql_plugin); \
-struct st_mysql_plugin DECLS[]= {
+MYSQL_PLUGIN_EXPORT int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION; \
+MYSQL_PLUGIN_EXPORT int PSIZE= sizeof(struct st_mysql_plugin); \
+MYSQL_PLUGIN_EXPORT struct st_mysql_plugin DECLS[]= {
#else
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
@@ -120,7 +128,8 @@ enum enum_mysql_show_type
{
SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
- SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE
+ SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
+ SHOW_always_last
};
struct st_mysql_show_var {
@@ -410,205 +419,43 @@ struct st_mysql_plugin
/*************************************************************************
API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
*/
+#include "plugin_ftparser.h"
-#define MYSQL_FTPARSER_INTERFACE_VERSION 0x0100
-
-/* Parsing modes. Set in MYSQL_FTPARSER_PARAM::mode */
-enum enum_ftparser_mode
-{
-/*
- Fast and simple mode. This mode is used for indexing, and natural
- language queries.
-
- The parser is expected to return only those words that go into the
- index. Stopwords or too short/long words should not be returned. The
- 'boolean_info' argument of mysql_add_word() does not have to be set.
-*/
- MYSQL_FTPARSER_SIMPLE_MODE= 0,
-
-/*
- Parse with stopwords mode. This mode is used in boolean searches for
- "phrase matching."
-
- The parser is not allowed to ignore words in this mode. Every word
- should be returned, including stopwords and words that are too short
- or long. The 'boolean_info' argument of mysql_add_word() does not
- have to be set.
+/*************************************************************************
+ API for Storage Engine plugin. (MYSQL_DAEMON_PLUGIN)
*/
- MYSQL_FTPARSER_WITH_STOPWORDS= 1,
-/*
- Parse in boolean mode. This mode is used to parse a boolean query string.
-
- The parser should provide a valid MYSQL_FTPARSER_BOOLEAN_INFO
- structure in the 'boolean_info' argument to mysql_add_word().
- Usually that means that the parser should recognize boolean operators
- in the parsing stream and set appropriate fields in
- MYSQL_FTPARSER_BOOLEAN_INFO structure accordingly. As for
- MYSQL_FTPARSER_WITH_STOPWORDS mode, no word should be ignored.
- Instead, use FT_TOKEN_STOPWORD for the token type of such a word.
-*/
- MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
-};
+/* handlertons of different MySQL releases are incompatible */
+#define MYSQL_DAEMON_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
/*
- Token types for boolean mode searching (used for the type member of
- MYSQL_FTPARSER_BOOLEAN_INFO struct)
-
- FT_TOKEN_EOF: End of data.
- FT_TOKEN_WORD: Regular word.
- FT_TOKEN_LEFT_PAREN: Left parenthesis (start of group/sub-expression).
- FT_TOKEN_RIGHT_PAREN: Right parenthesis (end of group/sub-expression).
- FT_TOKEN_STOPWORD: Stopword.
+ Here we define only the descriptor structure, that is referred from
+ st_mysql_plugin.
*/
-enum enum_ft_token_type
+struct st_mysql_daemon
{
- FT_TOKEN_EOF= 0,
- FT_TOKEN_WORD= 1,
- FT_TOKEN_LEFT_PAREN= 2,
- FT_TOKEN_RIGHT_PAREN= 3,
- FT_TOKEN_STOPWORD= 4
+ int interface_version;
};
-/*
- This structure is used in boolean search mode only. It conveys
- boolean-mode metadata to the MySQL search engine for every word in
- the search query. A valid instance of this structure must be filled
- in by the plugin parser and passed as an argument in the call to
- mysql_add_word (the callback function in the MYSQL_FTPARSER_PARAM
- structure) when a query is parsed in boolean mode.
-
- type: The token type. Should be one of the enum_ft_token_type values.
-
- yesno: Whether the word must be present for a match to occur:
- >0 Must be present
- <0 Must not be present
- 0 Neither; the word is optional but its presence increases the relevance
- With the default settings of the ft_boolean_syntax system variable,
- >0 corresponds to the '+' operator, <0 corrresponds to the '-' operator,
- and 0 means neither operator was used.
-
- weight_adjust: A weighting factor that determines how much a match
- for the word counts. Positive values increase, negative - decrease the
- relative word's importance in the query.
-
- wasign: The sign of the word's weight in the query. If it's non-negative
- the match for the word will increase document relevance, if it's
- negative - decrease (the word becomes a "noise word", the less of it the
- better).
-
- trunc: Corresponds to the '*' operator in the default setting of the
- ft_boolean_syntax system variable.
-*/
-typedef struct st_mysql_ftparser_boolean_info
-{
- enum enum_ft_token_type type;
- int yesno;
- int weight_adjust;
- char wasign;
- char trunc;
- /* These are parser state and must be removed. */
- char prev;
- char *quot;
-} MYSQL_FTPARSER_BOOLEAN_INFO;
-
-/*
- The following flag means that buffer with a string (document, word)
- may be overwritten by the caller before the end of the parsing (that is
- before st_mysql_ftparser::deinit() call). If one needs the string
- to survive between two successive calls of the parsing function, she
- needs to save a copy of it. The flag may be set by MySQL before calling
- st_mysql_ftparser::parse(), or it may be set by a plugin before calling
- st_mysql_ftparser_param::mysql_parse() or
- st_mysql_ftparser_param::mysql_add_word().
-*/
-#define MYSQL_FTFLAGS_NEED_COPY 1
-
-/*
- An argument of the full-text parser plugin. This structure is
- filled in by MySQL server and passed to the parsing function of the
- plugin as an in/out parameter.
-
- mysql_parse: A pointer to the built-in parser implementation of the
- server. It's set by the server and can be used by the parser plugin
- to invoke the MySQL default parser. If plugin's role is to extract
- textual data from .doc, .pdf or .xml content, it might extract
- plaintext from the content, and then pass the text to the default
- MySQL parser to be parsed.
-
- mysql_add_word: A server callback to add a new word. When parsing
- a document, the server sets this to point at a function that adds
- the word to MySQL full-text index. When parsing a search query,
- this function will add the new word to the list of words to search
- for. The boolean_info argument can be NULL for all cases except
- when mode is MYSQL_FTPARSER_FULL_BOOLEAN_INFO.
-
- ftparser_state: A generic pointer. The plugin can set it to point
- to information to be used internally for its own purposes.
-
- mysql_ftparam: This is set by the server. It is used by MySQL functions
- called via mysql_parse() and mysql_add_word() callback. The plugin
- should not modify it.
-
- cs: Information about the character set of the document or query string.
-
- doc: A pointer to the document or query string to be parsed.
-
- length: Length of the document or query string, in bytes.
-
- flags: See MYSQL_FTFLAGS_* constants above.
-
- mode: The parsing mode. With boolean operators, with stopwords, or
- nothing. See enum_ftparser_mode above.
+/*************************************************************************
+ API for I_S plugin. (MYSQL_INFORMATION_SCHEMA_PLUGIN)
*/
-typedef struct st_mysql_ftparser_param
-{
- int (*mysql_parse)(struct st_mysql_ftparser_param *,
- char *doc, int doc_len);
- int (*mysql_add_word)(struct st_mysql_ftparser_param *,
- char *word, int word_len,
- MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
- void *ftparser_state;
- void *mysql_ftparam;
- struct charset_info_st *cs;
- char *doc;
- int length;
- int flags;
- enum enum_ftparser_mode mode;
-} MYSQL_FTPARSER_PARAM;
+/* handlertons of different MySQL releases are incompatible */
+#define MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
/*
- Full-text parser descriptor.
-
- interface_version is, e.g., MYSQL_FTPARSER_INTERFACE_VERSION.
- The parsing, initialization, and deinitialization functions are
- invoked per SQL statement for which the parser is used.
+ Here we define only the descriptor structure, that is referred from
+ st_mysql_plugin.
*/
-struct st_mysql_ftparser
+struct st_mysql_information_schema
{
int interface_version;
- int (*parse)(MYSQL_FTPARSER_PARAM *param);
- int (*init)(MYSQL_FTPARSER_PARAM *param);
- int (*deinit)(MYSQL_FTPARSER_PARAM *param);
};
-/*************************************************************************
- API for Storage Engine plugin. (MYSQL_DAEMON_PLUGIN)
-*/
-
-/* handlertons of different MySQL releases are incompatible */
-#define MYSQL_DAEMON_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
-
-/*************************************************************************
- API for I_S plugin. (MYSQL_INFORMATION_SCHEMA_PLUGIN)
-*/
-
-/* handlertons of different MySQL releases are incompatible */
-#define MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
/*************************************************************************
API for Storage Engine plugin. (MYSQL_STORAGE_ENGINE_PLUGIN)
@@ -630,28 +477,20 @@ struct st_mysql_storage_engine
struct handlerton;
-/*
- Here we define only the descriptor structure, that is referred from
- st_mysql_plugin.
-*/
-
-struct st_mysql_daemon
-{
- int interface_version;
-};
/*
- Here we define only the descriptor structure, that is referred from
- st_mysql_plugin.
+ API for Replication plugin. (MYSQL_REPLICATION_PLUGIN)
*/
+ #define MYSQL_REPLICATION_INTERFACE_VERSION 0x0100
+
+ /**
+ Replication plugin descriptor
+ */
+ struct Mysql_replication {
+ int interface_version;
+ };
-struct st_mysql_information_schema
-{
- int interface_version;
-};
-
-
-/*
+/*************************************************************************
st_mysql_value struct for reading values from mysqld.
Used by server variables framework to parse user-provided values.
Will be used for arguments when implementing UDFs.
@@ -671,6 +510,7 @@ struct st_mysql_value
const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
int (*val_real)(struct st_mysql_value *, double *realbuf);
int (*val_int)(struct st_mysql_value *, long long *intbuf);
+ int (*is_unsigned)(struct st_mysql_value *);
};
@@ -733,54 +573,6 @@ int thd_killed(const MYSQL_THD thd);
*/
unsigned long thd_get_thread_id(const MYSQL_THD thd);
-
-/**
- Allocate memory in the connection's local memory pool
-
- @details
- When properly used in place of @c my_malloc(), this can significantly
- improve concurrency. Don't use this or related functions to allocate
- large chunks of memory. Use for temporary storage only. The memory
- will be freed automatically at the end of the statement; no explicit
- code is required to prevent memory leaks.
-
- @see alloc_root()
-*/
-void *thd_alloc(MYSQL_THD thd, unsigned int size);
-/**
- @see thd_alloc()
-*/
-void *thd_calloc(MYSQL_THD thd, unsigned int size);
-/**
- @see thd_alloc()
-*/
-char *thd_strdup(MYSQL_THD thd, const char *str);
-/**
- @see thd_alloc()
-*/
-char *thd_strmake(MYSQL_THD thd, const char *str, unsigned int size);
-/**
- @see thd_alloc()
-*/
-void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int size);
-
-/**
- Create a LEX_STRING in this connection's local memory pool
-
- @param thd user thread connection handle
- @param lex_str pointer to LEX_STRING object to be initialized
- @param str initializer to be copied into lex_str
- @param size length of str, in bytes
- @param allocate_lex_string flag: if TRUE, allocate new LEX_STRING object,
- instead of using lex_str value
- @return NULL on failure, or pointer to the LEX_STRING object
-
- @see thd_alloc()
-*/
-MYSQL_LEX_STRING *thd_make_lex_string(MYSQL_THD thd, MYSQL_LEX_STRING *lex_str,
- const char *str, unsigned int size,
- int allocate_lex_string);
-
/**
Get the XID for this connection's transaction
diff --git a/include/mysql/plugin.h.pp b/include/mysql/plugin.h.pp
index e4906ea6547..3a1b03742da 100644
--- a/include/mysql/plugin.h.pp
+++ b/include/mysql/plugin.h.pp
@@ -1,9 +1,38 @@
+#include <mysql/services.h>
+#include <mysql/service_my_snprintf.h>
+#include <stdarg.h>
+#include <stdlib.h>
+extern struct my_snprintf_service_st {
+ size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
+ size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
+} *my_snprintf_service;
+size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
+size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
+#include <mysql/service_thd_alloc.h>
+#include <stdlib.h>
struct st_mysql_lex_string
{
char *str;
- unsigned int length;
+ size_t length;
};
typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
+extern struct thd_alloc_service_st {
+ void *(*thd_alloc_func)(void*, unsigned int);
+ void *(*thd_calloc_func)(void*, unsigned int);
+ char *(*thd_strdup_func)(void*, const char *);
+ char *(*thd_strmake_func)(void*, const char *, unsigned int);
+ void *(*thd_memdup_func)(void*, const void*, unsigned int);
+ MYSQL_LEX_STRING *(*thd_make_lex_string_func)(void*, MYSQL_LEX_STRING *,
+ const char *, unsigned int, int);
+} *thd_alloc_service;
+void *thd_alloc(void* thd, unsigned int size);
+void *thd_calloc(void* thd, unsigned int size);
+char *thd_strdup(void* thd, const char *str);
+char *thd_strmake(void* thd, const char *str, unsigned int size);
+void *thd_memdup(void* thd, const void* str, unsigned int size);
+MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
+ const char *str, unsigned int size,
+ int allocate_lex_string);
struct st_mysql_xid {
long formatID;
long gtrid_length;
@@ -15,7 +44,8 @@ enum enum_mysql_show_type
{
SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
- SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE
+ SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
+ SHOW_always_last
};
struct st_mysql_show_var {
const char *name;
@@ -46,6 +76,8 @@ struct st_mysql_plugin
struct st_mysql_sys_var **system_vars;
void * __reserved1;
};
+#include "plugin_ftparser.h"
+#include "plugin.h"
enum enum_ftparser_mode
{
MYSQL_FTPARSER_SIMPLE_MODE= 0,
@@ -92,25 +124,29 @@ struct st_mysql_ftparser
int (*init)(MYSQL_FTPARSER_PARAM *param);
int (*deinit)(MYSQL_FTPARSER_PARAM *param);
};
-struct st_mysql_storage_engine
+struct st_mysql_daemon
{
int interface_version;
};
-struct handlerton;
-struct st_mysql_daemon
+struct st_mysql_information_schema
{
int interface_version;
};
-struct st_mysql_information_schema
+struct st_mysql_storage_engine
{
int interface_version;
};
+struct handlerton;
+ struct Mysql_replication {
+ int interface_version;
+ };
struct st_mysql_value
{
int (*value_type)(struct st_mysql_value *);
const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
int (*val_real)(struct st_mysql_value *, double *realbuf);
int (*val_int)(struct st_mysql_value *, long long *intbuf);
+ int (*is_unsigned)(struct st_mysql_value *);
};
int thd_in_lock_tables(const void* thd);
int thd_tablespace_op(const void* thd);
@@ -125,14 +161,6 @@ void thd_inc_row_count(void* thd);
int mysql_tmpfile(const char *prefix);
int thd_killed(const void* thd);
unsigned long thd_get_thread_id(const void* thd);
-void *thd_alloc(void* thd, unsigned int size);
-void *thd_calloc(void* thd, unsigned int size);
-char *thd_strdup(void* thd, const char *str);
-char *thd_strmake(void* thd, const char *str, unsigned int size);
-void *thd_memdup(void* thd, const void* str, unsigned int size);
-MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
- const char *str, unsigned int size,
- int allocate_lex_string);
void thd_get_xid(const void* thd, MYSQL_XID *xid);
void mysql_query_cache_invalidate4(void* thd,
const char *key, unsigned int key_length,
diff --git a/include/mysql/plugin_audit.h b/include/mysql/plugin_audit.h
new file mode 100644
index 00000000000..41505da64af
--- /dev/null
+++ b/include/mysql/plugin_audit.h
@@ -0,0 +1,98 @@
+/* Copyright (C) 2007 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 */
+
+#ifndef _my_audit_h
+#define _my_audit_h
+
+/*************************************************************************
+ API for Audit plugin. (MYSQL_AUDIT_PLUGIN)
+*/
+
+#include "plugin.h"
+
+#define MYSQL_AUDIT_CLASS_MASK_SIZE 1
+
+#define MYSQL_AUDIT_INTERFACE_VERSION 0x0200
+
+/*
+ The first word in every event class struct indicates the specific
+ class of the event.
+*/
+struct mysql_event
+{
+ unsigned int event_class;
+};
+
+
+/*************************************************************************
+ AUDIT CLASS : GENERAL
+
+ LOG events occurs before emitting to the general query log.
+ ERROR events occur before transmitting errors to the user.
+ RESULT events occur after transmitting a resultset to the user.
+*/
+
+#define MYSQL_AUDIT_GENERAL_CLASS 0
+#define MYSQL_AUDIT_GENERAL_CLASSMASK (1 << MYSQL_AUDIT_GENERAL_CLASS)
+#define MYSQL_AUDIT_GENERAL_LOG 0
+#define MYSQL_AUDIT_GENERAL_ERROR 1
+#define MYSQL_AUDIT_GENERAL_RESULT 2
+
+struct mysql_event_general
+{
+ unsigned int event_class;
+ unsigned int event_subclass;
+ int general_error_code;
+ unsigned long general_thread_id;
+ const char *general_user;
+ unsigned int general_user_length;
+ const char *general_command;
+ unsigned int general_command_length;
+ const char *general_query;
+ unsigned int general_query_length;
+ struct charset_info_st *general_charset;
+ unsigned long long general_time;
+ unsigned long long general_rows;
+};
+
+
+/*************************************************************************
+ Here we define the descriptor structure, that is referred from
+ st_mysql_plugin.
+
+ release_thd() event occurs when the event class consumer is to be
+ disassociated from the specified THD. This would typically occur
+ before some operation which may require sleeping - such as when
+ waiting for the next query from the client.
+
+ event_notify() is invoked whenever an event occurs which is of any
+ class for which the plugin has interest. The first word of the
+ mysql_event argument indicates the specific event class and the
+ remainder of the structure is as required for that class.
+
+ class_mask is an array of bits used to indicate what event classes
+ that this plugin wants to receive.
+*/
+
+struct st_mysql_audit
+{
+ int interface_version;
+ void (*release_thd)(MYSQL_THD);
+ void (*event_notify)(MYSQL_THD, const struct mysql_event *);
+ unsigned long class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
+};
+
+
+#endif
diff --git a/include/mysql/plugin_ftparser.h b/include/mysql/plugin_ftparser.h
new file mode 100644
index 00000000000..7f9bde3a6a0
--- /dev/null
+++ b/include/mysql/plugin_ftparser.h
@@ -0,0 +1,211 @@
+/* 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 */
+
+#ifndef _my_plugin_ftparser_h
+#define _my_plugin_ftparser_h
+#include "plugin.h"
+
+/*************************************************************************
+ API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
+*/
+
+#define MYSQL_FTPARSER_INTERFACE_VERSION 0x0100
+
+/* Parsing modes. Set in MYSQL_FTPARSER_PARAM::mode */
+enum enum_ftparser_mode
+{
+/*
+ Fast and simple mode. This mode is used for indexing, and natural
+ language queries.
+
+ The parser is expected to return only those words that go into the
+ index. Stopwords or too short/long words should not be returned. The
+ 'boolean_info' argument of mysql_add_word() does not have to be set.
+*/
+ MYSQL_FTPARSER_SIMPLE_MODE= 0,
+
+/*
+ Parse with stopwords mode. This mode is used in boolean searches for
+ "phrase matching."
+
+ The parser is not allowed to ignore words in this mode. Every word
+ should be returned, including stopwords and words that are too short
+ or long. The 'boolean_info' argument of mysql_add_word() does not
+ have to be set.
+*/
+ MYSQL_FTPARSER_WITH_STOPWORDS= 1,
+
+/*
+ Parse in boolean mode. This mode is used to parse a boolean query string.
+
+ The parser should provide a valid MYSQL_FTPARSER_BOOLEAN_INFO
+ structure in the 'boolean_info' argument to mysql_add_word().
+ Usually that means that the parser should recognize boolean operators
+ in the parsing stream and set appropriate fields in
+ MYSQL_FTPARSER_BOOLEAN_INFO structure accordingly. As for
+ MYSQL_FTPARSER_WITH_STOPWORDS mode, no word should be ignored.
+ Instead, use FT_TOKEN_STOPWORD for the token type of such a word.
+*/
+ MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
+};
+
+/*
+ Token types for boolean mode searching (used for the type member of
+ MYSQL_FTPARSER_BOOLEAN_INFO struct)
+
+ FT_TOKEN_EOF: End of data.
+ FT_TOKEN_WORD: Regular word.
+ FT_TOKEN_LEFT_PAREN: Left parenthesis (start of group/sub-expression).
+ FT_TOKEN_RIGHT_PAREN: Right parenthesis (end of group/sub-expression).
+ FT_TOKEN_STOPWORD: Stopword.
+*/
+
+enum enum_ft_token_type
+{
+ FT_TOKEN_EOF= 0,
+ FT_TOKEN_WORD= 1,
+ FT_TOKEN_LEFT_PAREN= 2,
+ FT_TOKEN_RIGHT_PAREN= 3,
+ FT_TOKEN_STOPWORD= 4
+};
+
+/*
+ This structure is used in boolean search mode only. It conveys
+ boolean-mode metadata to the MySQL search engine for every word in
+ the search query. A valid instance of this structure must be filled
+ in by the plugin parser and passed as an argument in the call to
+ mysql_add_word (the callback function in the MYSQL_FTPARSER_PARAM
+ structure) when a query is parsed in boolean mode.
+
+ type: The token type. Should be one of the enum_ft_token_type values.
+
+ yesno: Whether the word must be present for a match to occur:
+ >0 Must be present
+ <0 Must not be present
+ 0 Neither; the word is optional but its presence increases the relevance
+ With the default settings of the ft_boolean_syntax system variable,
+ >0 corresponds to the '+' operator, <0 corrresponds to the '-' operator,
+ and 0 means neither operator was used.
+
+ weight_adjust: A weighting factor that determines how much a match
+ for the word counts. Positive values increase, negative - decrease the
+ relative word's importance in the query.
+
+ wasign: The sign of the word's weight in the query. If it's non-negative
+ the match for the word will increase document relevance, if it's
+ negative - decrease (the word becomes a "noise word", the less of it the
+ better).
+
+ trunc: Corresponds to the '*' operator in the default setting of the
+ ft_boolean_syntax system variable.
+*/
+
+typedef struct st_mysql_ftparser_boolean_info
+{
+ enum enum_ft_token_type type;
+ int yesno;
+ int weight_adjust;
+ char wasign;
+ char trunc;
+ /* These are parser state and must be removed. */
+ char prev;
+ char *quot;
+} MYSQL_FTPARSER_BOOLEAN_INFO;
+
+/*
+ The following flag means that buffer with a string (document, word)
+ may be overwritten by the caller before the end of the parsing (that is
+ before st_mysql_ftparser::deinit() call). If one needs the string
+ to survive between two successive calls of the parsing function, she
+ needs to save a copy of it. The flag may be set by MySQL before calling
+ st_mysql_ftparser::parse(), or it may be set by a plugin before calling
+ st_mysql_ftparser_param::mysql_parse() or
+ st_mysql_ftparser_param::mysql_add_word().
+*/
+#define MYSQL_FTFLAGS_NEED_COPY 1
+
+/*
+ An argument of the full-text parser plugin. This structure is
+ filled in by MySQL server and passed to the parsing function of the
+ plugin as an in/out parameter.
+
+ mysql_parse: A pointer to the built-in parser implementation of the
+ server. It's set by the server and can be used by the parser plugin
+ to invoke the MySQL default parser. If plugin's role is to extract
+ textual data from .doc, .pdf or .xml content, it might extract
+ plaintext from the content, and then pass the text to the default
+ MySQL parser to be parsed.
+
+ mysql_add_word: A server callback to add a new word. When parsing
+ a document, the server sets this to point at a function that adds
+ the word to MySQL full-text index. When parsing a search query,
+ this function will add the new word to the list of words to search
+ for. The boolean_info argument can be NULL for all cases except
+ when mode is MYSQL_FTPARSER_FULL_BOOLEAN_INFO.
+
+ ftparser_state: A generic pointer. The plugin can set it to point
+ to information to be used internally for its own purposes.
+
+ mysql_ftparam: This is set by the server. It is used by MySQL functions
+ called via mysql_parse() and mysql_add_word() callback. The plugin
+ should not modify it.
+
+ cs: Information about the character set of the document or query string.
+
+ doc: A pointer to the document or query string to be parsed.
+
+ length: Length of the document or query string, in bytes.
+
+ flags: See MYSQL_FTFLAGS_* constants above.
+
+ mode: The parsing mode. With boolean operators, with stopwords, or
+ nothing. See enum_ftparser_mode above.
+*/
+
+typedef struct st_mysql_ftparser_param
+{
+ int (*mysql_parse)(struct st_mysql_ftparser_param *,
+ char *doc, int doc_len);
+ int (*mysql_add_word)(struct st_mysql_ftparser_param *,
+ char *word, int word_len,
+ MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
+ void *ftparser_state;
+ void *mysql_ftparam;
+ struct charset_info_st *cs;
+ char *doc;
+ int length;
+ int flags;
+ enum enum_ftparser_mode mode;
+} MYSQL_FTPARSER_PARAM;
+
+/*
+ Full-text parser descriptor.
+
+ interface_version is, e.g., MYSQL_FTPARSER_INTERFACE_VERSION.
+ The parsing, initialization, and deinitialization functions are
+ invoked per SQL statement for which the parser is used.
+*/
+
+struct st_mysql_ftparser
+{
+ int interface_version;
+ int (*parse)(MYSQL_FTPARSER_PARAM *param);
+ int (*init)(MYSQL_FTPARSER_PARAM *param);
+ int (*deinit)(MYSQL_FTPARSER_PARAM *param);
+};
+
+
+#endif
+
diff --git a/include/mysql/psi/mysql_file.h b/include/mysql/psi/mysql_file.h
new file mode 100644
index 00000000000..0a998aaa76c
--- /dev/null
+++ b/include/mysql/psi/mysql_file.h
@@ -0,0 +1,1400 @@
+/* Copyright (C) 2008-2009 Sun Microsystems, Inc
+
+ 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 */
+
+#ifndef MYSQL_FILE_H
+#define MYSQL_FILE_H
+
+/* For strlen() */
+#include <string.h>
+/* For MY_STAT */
+#include <my_dir.h>
+/* For my_chsize */
+#include <my_sys.h>
+
+/**
+ @file mysql/psi/mysql_file.h
+ Instrumentation helpers for mysys file io.
+ This header file provides the necessary declarations
+ to use the mysys file API with the performance schema instrumentation.
+ In some compilers (SunStudio), 'static inline' functions, when declared
+ but not used, are not optimized away (because they are unused) by default,
+ so that including a static inline function from a header file does
+ create unwanted dependencies, causing unresolved symbols at link time.
+ Other compilers, like gcc, optimize these dependencies by default.
+
+ Since the instrumented APIs declared here are wrapper on top
+ of mysys file io APIs, including mysql/psi/mysql_file.h assumes that
+ the dependency on my_sys already exists.
+*/
+
+#include "mysql/psi/psi.h"
+
+/**
+ @defgroup File_instrumentation File Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ @def mysql_file_fgets(P1, P2, F)
+ Instrumented fgets.
+ @c mysql_file_fgets is a replacement for @c fgets.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fgets(P1, P2, F) \
+ inline_mysql_file_fgets(__FILE__, __LINE__, P1, P2, F)
+#else
+ #define mysql_file_fgets(P1, P2, F) \
+ inline_mysql_file_fgets(P1, P2, F)
+#endif
+
+/**
+ @def mysql_file_fgetc(F)
+ Instrumented fgetc.
+ @c mysql_file_fgetc is a replacement for @c fgetc.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fgetc(F) inline_mysql_file_fgetc(__FILE__, __LINE__, F)
+#else
+ #define mysql_file_fgetc(F) inline_mysql_file_fgetc(F)
+#endif
+
+/**
+ @def mysql_file_fputs(P1, F)
+ Instrumented fputs.
+ @c mysql_file_fputs is a replacement for @c fputs.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fputs(P1, F) \
+ inline_mysql_file_fputs(__FILE__, __LINE__, P1, F)
+#else
+ #define mysql_file_fputs(P1, F)\
+ inline_mysql_file_fputs(P1, F)
+#endif
+
+/**
+ @def mysql_file_fputc(P1, F)
+ Instrumented fputc.
+ @c mysql_file_fputc is a replacement for @c fputc.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fputc(P1, F) \
+ inline_mysql_file_fputc(__FILE__, __LINE__, P1, F)
+#else
+ #define mysql_file_fputc(P1, F) \
+ inline_mysql_file_fputc(P1, F)
+#endif
+
+/**
+ @def mysql_file_fprintf
+ Instrumented fprintf.
+ @c mysql_file_fprintf is a replacement for @c fprintf.
+*/
+#define mysql_file_fprintf inline_mysql_file_fprintf
+
+/**
+ @def mysql_file_vfprintf(F, P1, P2)
+ Instrumented vfprintf.
+ @c mysql_file_vfprintf is a replacement for @c vfprintf.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_vfprintf(F, P1, P2) \
+ inline_mysql_file_vfprintf(__FILE__, __LINE__, F, P1, P2)
+#else
+ #define mysql_file_vfprintf(F, P1, P2) \
+ inline_mysql_file_vfprintf(F, P1, P2)
+#endif
+
+/**
+ @def mysql_file_fflush(F, P1, P2)
+ Instrumented fflush.
+ @c mysql_file_fflush is a replacement for @c fflush.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fflush(F) \
+ inline_mysql_file_fflush(__FILE__, __LINE__, F)
+#else
+ #define mysql_file_fflush(F) \
+ inline_mysql_file_fflush(F)
+#endif
+
+/**
+ @def mysql_file_feof(F)
+ Instrumented feof.
+ @c mysql_file_feof is a replacement for @c feof.
+*/
+#define mysql_file_feof(F) inline_mysql_file_feof(F)
+
+/**
+ @def mysql_file_fstat(FN, S, FL)
+ Instrumented fstat.
+ @c mysql_file_fstat is a replacement for @c my_fstat.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fstat(FN, S, FL) \
+ inline_mysql_file_fstat(__FILE__, __LINE__, FN, S, FL)
+#else
+ #define mysql_file_fstat(FN, S, FL) \
+ inline_mysql_file_fstat(FN, S, FL)
+#endif
+
+/**
+ @def mysql_file_stat(K, FN, S, FL)
+ Instrumented stat.
+ @c mysql_file_stat is a replacement for @c my_stat.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_stat(K, FN, S, FL) \
+ inline_mysql_file_stat(K, __FILE__, __LINE__, FN, S, FL)
+#else
+ #define mysql_file_stat(K, FN, S, FL) \
+ inline_mysql_file_stat(FN, S, FL)
+#endif
+
+/**
+ @def mysql_file_chsize(F, P1, P2, P3)
+ Instrumented chsize.
+ @c mysql_file_chsize is a replacement for @c my_chsize.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_chsize(F, P1, P2, P3) \
+ inline_mysql_file_chsize(__FILE__, __LINE__, F, P1, P2, P3)
+#else
+ #define mysql_file_chsize(F, P1, P2, P3) \
+ inline_mysql_file_chsize(F, P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_fopen(K, N, F1, F2)
+ Instrumented fopen.
+ @c mysql_file_fopen is a replacement for @c my_fopen.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fopen(K, N, F1, F2) \
+ inline_mysql_file_fopen(K, __FILE__, __LINE__, N, F1, F2)
+#else
+ #define mysql_file_fopen(K, N, F1, F2) \
+ inline_mysql_file_fopen(N, F1, F2)
+#endif
+
+/**
+ @def mysql_file_fclose(FD, FL)
+ Instrumented fclose.
+ @c mysql_file_fclose is a replacement for @c my_fclose.
+ Without the instrumentation, this call will have the same behavior as the
+ undocumented and possibly platform specific my_fclose(NULL, ...) behavior.
+ With the instrumentation, mysql_fclose(NULL, ...) will safely return 0,
+ which is an extension compared to my_fclose and is therefore compliant.
+ mysql_fclose is on purpose *not* implementing
+ @code DBUG_ASSERT(file != NULL) @endcode,
+ since doing so could introduce regressions.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fclose(FD, FL) \
+ inline_mysql_file_fclose(__FILE__, __LINE__, FD, FL)
+#else
+ #define mysql_file_fclose(FD, FL) \
+ inline_mysql_file_fclose(FD, FL)
+#endif
+
+/**
+ @def mysql_file_fread(FD, P1, P2, P3)
+ Instrumented fread.
+ @c mysql_file_fread is a replacement for @c my_fread.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fread(FD, P1, P2, P3) \
+ inline_mysql_file_fread(__FILE__, __LINE__, FD, P1, P2, P3)
+#else
+ #define mysql_file_fread(FD, P1, P2, P3) \
+ inline_mysql_file_fread(FD, P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_fwrite(FD, P1, P2, P3)
+ Instrumented fwrite.
+ @c mysql_file_fwrite is a replacement for @c my_fwrite.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fwrite(FD, P1, P2, P3) \
+ inline_mysql_file_fwrite(__FILE__, __LINE__, FD, P1, P2, P3)
+#else
+ #define mysql_file_fwrite(FD, P1, P2, P3) \
+ inline_mysql_file_fwrite(FD, P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_fseek(FD, P, W, F)
+ Instrumented fseek.
+ @c mysql_file_fseek is a replacement for @c my_fseek.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fseek(FD, P, W, F) \
+ inline_mysql_file_fseek(__FILE__, __LINE__, FD, P, W, F)
+#else
+ #define mysql_file_fseek(FD, P, W, F) \
+ inline_mysql_file_fseek(FD, P, W, F)
+#endif
+
+/**
+ @def mysql_file_ftell(FD, F)
+ Instrumented ftell.
+ @c mysql_file_ftell is a replacement for @c my_ftell.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_ftell(FD, F) \
+ inline_mysql_file_ftell(__FILE__, __LINE__, FD, F)
+#else
+ #define mysql_file_ftell(FD, F) \
+ inline_mysql_file_ftell(FD, F)
+#endif
+
+/**
+ @def mysql_file_create(K, N, F1, F2, F3)
+ Instrumented create.
+ @c mysql_file_create is a replacement for @c my_create.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_create(K, N, F1, F2, F3) \
+ inline_mysql_file_create(K, __FILE__, __LINE__, N, F1, F2, F3)
+#else
+ #define mysql_file_create(K, N, F1, F2, F3) \
+ inline_mysql_file_create(N, F1, F2, F3)
+#endif
+
+/**
+ @def mysql_file_create_temp(K, T, D, P, M, F)
+ Instrumented create_temp_file.
+ @c mysql_file_create_temp is a replacement for @c create_temp_file.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_create_temp(K, T, D, P, M, F) \
+ inline_mysql_file_create_temp(K, T, D, P, M, F)
+#else
+ #define mysql_file_create_temp(K, T, D, P, M, F) \
+ inline_mysql_file_create_temp(T, D, P, M, F)
+#endif
+
+/**
+ @def mysql_file_open(K, N, F1, F2)
+ Instrumented open.
+ @c mysql_file_open is a replacement for @c my_open.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_open(K, N, F1, F2) \
+ inline_mysql_file_open(K, __FILE__, __LINE__, N, F1, F2)
+#else
+ #define mysql_file_open(K, N, F1, F2) \
+ inline_mysql_file_open(N, F1, F2)
+#endif
+
+/**
+ @def mysql_file_close(FD, F)
+ Instrumented close.
+ @c mysql_file_close is a replacement for @c my_close.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_close(FD, F) \
+ inline_mysql_file_close(__FILE__, __LINE__, FD, F)
+#else
+ #define mysql_file_close(FD, F) \
+ inline_mysql_file_close(FD, F)
+#endif
+
+/**
+ @def mysql_file_read(FD, B, S, F)
+ Instrumented read.
+ @c mysql_read is a replacement for @c my_read.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_read(FD, B, S, F) \
+ inline_mysql_file_read(__FILE__, __LINE__, FD, B, S, F)
+#else
+ #define mysql_file_read(FD, B, S, F) \
+ inline_mysql_file_read(FD, B, S, F)
+#endif
+
+/**
+ @def mysql_file_write(FD, B, S, F)
+ Instrumented write.
+ @c mysql_file_write is a replacement for @c my_write.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_write(FD, B, S, F) \
+ inline_mysql_file_write(__FILE__, __LINE__, FD, B, S, F)
+#else
+ #define mysql_file_write(FD, B, S, F) \
+ inline_mysql_file_write(FD, B, S, F)
+#endif
+
+/**
+ @def mysql_file_pread(FD, B, S, O, F)
+ Instrumented pread.
+ @c mysql_pread is a replacement for @c my_pread.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_pread(FD, B, S, O, F) \
+ inline_mysql_file_pread(__FILE__, __LINE__, FD, B, S, O, F)
+#else
+ #define mysql_file_pread(FD, B, S, O, F) \
+ inline_mysql_file_pread(FD, B, S, O, F)
+#endif
+
+/**
+ @def mysql_file_pwrite(FD, B, S, O, F)
+ Instrumented pwrite.
+ @c mysql_file_pwrite is a replacement for @c my_pwrite.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_pwrite(FD, B, S, O, F) \
+ inline_mysql_file_pwrite(__FILE__, __LINE__, FD, B, S, O, F)
+#else
+ #define mysql_file_pwrite(FD, B, S, O, F) \
+ inline_mysql_file_pwrite(FD, B, S, O, F)
+#endif
+
+/**
+ @def mysql_file_seek(FD, P, W, F)
+ Instrumented seek.
+ @c mysql_file_seek is a replacement for @c my_seek.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_seek(FD, P, W, F) \
+ inline_mysql_file_seek(__FILE__, __LINE__, FD, P, W, F)
+#else
+ #define mysql_file_seek(FD, P, W, F) \
+ inline_mysql_file_seek(FD, P, W, F)
+#endif
+
+/**
+ @def mysql_file_tell(FD, F)
+ Instrumented tell.
+ @c mysql_file_tell is a replacement for @c my_tell.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_tell(FD, F) \
+ inline_mysql_file_tell(__FILE__, __LINE__, FD, F)
+#else
+ #define mysql_file_tell(FD, F) \
+ inline_mysql_file_tell(FD, F)
+#endif
+
+/**
+ @def mysql_file_delete(K, P1, P2)
+ Instrumented delete.
+ @c mysql_file_delete is a replacement for @c my_delete.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_delete(K, P1, P2) \
+ inline_mysql_file_delete(K, __FILE__, __LINE__, P1, P2)
+#else
+ #define mysql_file_delete(K, P1, P2) \
+ inline_mysql_file_delete(P1, P2)
+#endif
+
+/**
+ @def mysql_file_rename(K, P1, P2, P3)
+ Instrumented rename.
+ @c mysql_file_rename is a replacement for @c my_rename.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_rename(K, P1, P2, P3) \
+ inline_mysql_file_rename(K, __FILE__, __LINE__, P1, P2, P3)
+#else
+ #define mysql_file_rename(K, P1, P2, P3) \
+ inline_mysql_file_rename(P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_create_with_symlink(K, P1, P2, P3, P4, P5)
+ Instrumented create with symbolic link.
+ @c mysql_file_create_with_symlink is a replacement
+ for @c my_create_with_symlink.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_create_with_symlink(K, P1, P2, P3, P4, P5) \
+ inline_mysql_file_create_with_symlink(K, __FILE__, __LINE__, \
+ P1, P2, P3, P4, P5)
+#else
+ #define mysql_file_create_with_symlink(K, P1, P2, P3, P4, P5) \
+ inline_mysql_file_create_with_symlink(P1, P2, P3, P4, P5)
+#endif
+
+/**
+ @def mysql_file_delete_with_symlink(K, P1, P2)
+ Instrumented delete with symbolic link.
+ @c mysql_file_delete_with_symlink is a replacement
+ for @c my_delete_with_symlink.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_delete_with_symlink(K, P1, P2) \
+ inline_mysql_file_delete_with_symlink(K, __FILE__, __LINE__, P1, P2)
+#else
+ #define mysql_file_delete_with_symlink(K, P1, P2) \
+ inline_mysql_file_delete_with_symlink(P1, P2)
+#endif
+
+/**
+ @def mysql_file_rename_with_symlink(K, P1, P2, P3)
+ Instrumented rename with symbolic link.
+ @c mysql_file_rename_with_symlink is a replacement
+ for @c my_rename_with_symlink.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_rename_with_symlink(K, P1, P2, P3) \
+ inline_mysql_file_rename_with_symlink(K, __FILE__, __LINE__, P1, P2, P3)
+#else
+ #define mysql_file_rename_with_symlink(K, P1, P2, P3) \
+ inline_mysql_file_rename_with_symlink(P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_sync(P1, P2)
+ Instrumented file sync.
+ @c mysql_file_sync is a replacement for @c my_sync.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_sync(P1, P2) \
+ inline_mysql_file_sync(__FILE__, __LINE__, P1, P2)
+#else
+ #define mysql_file_sync(P1, P2) \
+ inline_mysql_file_sync(P1, P2)
+#endif
+
+/**
+ An instrumented FILE structure.
+ @sa MYSQL_FILE
+*/
+struct st_mysql_file
+{
+ /** The real file. */
+ FILE *m_file;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c MYSQL_FILE interface.
+ */
+ struct PSI_file *m_psi;
+};
+
+/**
+ Type of an instrumented file.
+ @c MYSQL_FILE is a drop-in replacement for @c FILE.
+ @sa mysql_file_open
+*/
+typedef struct st_mysql_file MYSQL_FILE;
+
+static inline char *
+inline_mysql_file_fgets(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ char *str, int size, MYSQL_FILE *file)
+{
+ char *result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_READ);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) size, src_file, src_line);
+ }
+#endif
+ result= fgets(str, size, file->m_file);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, result ? strlen(result) : 0);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_fgetc(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_READ);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 1, src_file, src_line);
+ }
+#endif
+ result= fgetc(file->m_file);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 1);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_fputs(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ const char *str, MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ size_t bytes= 0;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ {
+ bytes= str ? strlen(str) : 0;
+ PSI_server->start_file_wait(locker, bytes, src_file, src_line);
+ }
+ }
+#endif
+ result= fputs(str, file->m_file);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, bytes);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_fputc(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ char c, MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 1, src_file, src_line);
+ }
+#endif
+ result= fputc(c, file->m_file);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 1);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_fprintf(MYSQL_FILE *file, const char *format, ...)
+{
+ /*
+ TODO: figure out how to pass src_file and src_line from the caller.
+ */
+ int result;
+ va_list args;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, __FILE__, __LINE__);
+ }
+#endif
+ va_start(args, format);
+ result= vfprintf(file->m_file, format, args);
+ va_end(args);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) result);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_vfprintf(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, const char *format, va_list args)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= vfprintf(file->m_file, format, args);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) result);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_fflush(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_FLUSH);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= fflush(file->m_file);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline int inline_mysql_file_feof(MYSQL_FILE *file)
+{
+ /* Not instrumented, there is no wait involved */
+ return feof(file->m_file);
+}
+
+static inline int
+inline_mysql_file_fstat(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ int filenr, MY_STAT *stat_area, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(filenr,
+ PSI_FILE_FSTAT);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_fstat(filenr, stat_area, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline MY_STAT *
+inline_mysql_file_stat(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *path, MY_STAT *stat_area, myf flags)
+{
+ MY_STAT *result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_STAT,
+ path, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_open_wait(locker, src_file, src_line);
+ }
+#endif
+ result= my_stat(path, stat_area, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_chsize(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, my_off_t newlength, int filler, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file,
+ PSI_FILE_CHSIZE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) newlength, src_file,
+ src_line);
+ }
+#endif
+ result= my_chsize(file, newlength, filler, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) newlength);
+#endif
+ return result;
+}
+
+static inline MYSQL_FILE*
+inline_mysql_file_fopen(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *filename, int flags, myf myFlags)
+{
+ MYSQL_FILE *that;
+ that= (MYSQL_FILE*) my_malloc(sizeof(MYSQL_FILE), MYF(MY_WME));
+ if (likely(that != NULL))
+ {
+ that->m_psi= NULL;
+ {
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker
+ (key, PSI_FILE_STREAM_OPEN, filename, that);
+ if (likely(locker != NULL))
+ that->m_psi= PSI_server->start_file_open_wait(locker, src_file,
+ src_line);
+ }
+#endif
+ that->m_file= my_fopen(filename, flags, myFlags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_open_wait(locker);
+#endif
+ if (unlikely(that->m_file == NULL))
+ {
+ my_free(that, MYF(0));
+ return NULL;
+ }
+ }
+ }
+ return that;
+}
+
+static inline int
+inline_mysql_file_fclose(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, myf flags)
+{
+ int result= 0;
+ if (likely(file != NULL))
+ {
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ DBUG_ASSERT(file != NULL);
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_STREAM_CLOSE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_fclose(file->m_file, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ my_free(file, MYF(0));
+ }
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_fread(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, uchar *buffer, size_t count, myf flags)
+{
+ size_t result= 0;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_READ);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, count, src_file, src_line);
+ }
+#endif
+ result= my_fread(file->m_file, buffer, count, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ {
+ size_t bytes_read;
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_read= (result == 0) ? count : 0;
+ else
+ bytes_read= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_server->end_file_wait(locker, bytes_read);
+ }
+#endif
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_fwrite(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, const uchar *buffer, size_t count, myf flags)
+{
+ size_t result= 0;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, count, src_file, src_line);
+ }
+#endif
+ result= my_fwrite(file->m_file, buffer, count, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ {
+ size_t bytes_written;
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_written= (result == 0) ? count : 0;
+ else
+ bytes_written= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_server->end_file_wait(locker, bytes_written);
+ }
+#endif
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_fseek(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, my_off_t pos, int whence, myf flags)
+{
+ my_off_t result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_SEEK);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_fseek(file->m_file, pos, whence, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_ftell(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, myf flags)
+{
+ my_off_t result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_TELL);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_ftell(file->m_file, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline File
+inline_mysql_file_create(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *filename, int create_flags, int access_flags, myf myFlags)
+{
+ File file;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_CREATE,
+ filename, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_open_wait(locker, src_file, src_line);
+ }
+#endif
+ file= my_create(filename, create_flags, access_flags, myFlags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_open_wait_and_bind_to_descriptor(locker, file);
+#endif
+ return file;
+}
+
+static inline File
+inline_mysql_file_create_temp(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key,
+#endif
+ char *to, const char *dir, const char *pfx, int mode, myf myFlags)
+{
+ File file;
+ /*
+ TODO: This event is instrumented, but not timed.
+ The problem is that the file name is now known
+ before the create_temp_file call.
+ */
+ file= create_temp_file(to, dir, pfx, mode, myFlags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(PSI_server != NULL))
+ PSI_server->create_file(key, to, file);
+#endif
+ return file;
+}
+
+static inline File
+inline_mysql_file_open(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *filename, int flags, myf myFlags)
+{
+ File file;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_OPEN,
+ filename, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_open_wait(locker, src_file, src_line);
+ }
+#endif
+ file= my_open(filename, flags, myFlags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_open_wait_and_bind_to_descriptor(locker, file);
+#endif
+ return file;
+}
+
+static inline int
+inline_mysql_file_close(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file,
+ PSI_FILE_CLOSE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_close(file, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_read(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, uchar *buffer, size_t count, myf flags)
+{
+ size_t result= 0;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file,
+ PSI_FILE_READ);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, count, src_file, src_line);
+ }
+#endif
+ result= my_read(file, buffer, count, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ {
+ size_t bytes_read;
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_read= (result == 0) ? count : 0;
+ else
+ bytes_read= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_server->end_file_wait(locker, bytes_read);
+ }
+#endif
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_write(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, const uchar *buffer, size_t count, myf flags)
+{
+ size_t result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file,
+ PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, count, src_file, src_line);
+ }
+#endif
+ result= my_write(file, buffer, count, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ {
+ size_t bytes_written;
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_written= (result == 0) ? count : 0;
+ else
+ bytes_written= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_server->end_file_wait(locker, bytes_written);
+ }
+#endif
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_pread(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, uchar *buffer, size_t count, my_off_t offset, myf flags)
+{
+ size_t result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file, PSI_FILE_READ);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, count, src_file, src_line);
+ }
+#endif
+ result= my_pread(file, buffer, count, offset, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ {
+ size_t bytes_read;
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_read= (result == 0) ? count : 0;
+ else
+ bytes_read= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_server->end_file_wait(locker, bytes_read);
+ }
+#endif
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_pwrite(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, const uchar *buffer, size_t count, my_off_t offset, myf flags)
+{
+ size_t result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file,
+ PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, count, src_file, src_line);
+ }
+#endif
+ result= my_pwrite(file, buffer, count, offset, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ {
+ size_t bytes_written;
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_written= (result == 0) ? count : 0;
+ else
+ bytes_written= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_server->end_file_wait(locker, bytes_written);
+ }
+#endif
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_seek(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, my_off_t pos, int whence, myf flags)
+{
+ my_off_t result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file, PSI_FILE_SEEK);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_seek(file, pos, whence, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_tell(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, myf flags)
+{
+ my_off_t result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file, PSI_FILE_TELL);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_tell(file, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_delete(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *name, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_DELETE,
+ name, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_delete(name, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_rename(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *from, const char *to, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_RENAME,
+ to, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_rename(from, to, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline File
+inline_mysql_file_create_with_symlink(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *linkname, const char *filename, int create_flags,
+ int access_flags, myf flags)
+{
+ File file;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_CREATE,
+ filename, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_open_wait(locker, src_file, src_line);
+ }
+#endif
+ file= my_create_with_symlink(linkname, filename, create_flags, access_flags,
+ flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_open_wait_and_bind_to_descriptor(locker, file);
+#endif
+ return file;
+}
+
+static inline int
+inline_mysql_file_delete_with_symlink(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *name, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_DELETE,
+ name, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_delete_with_symlink(name, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_rename_with_symlink(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *from, const char *to, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_RENAME,
+ to, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_rename_with_symlink(from, to, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_sync(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File fd, myf flags)
+{
+ int result= 0;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(fd, PSI_FILE_SYNC);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_sync(fd, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+/** @} (end of group File_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_thread.h b/include/mysql/psi/mysql_thread.h
new file mode 100644
index 00000000000..4e839c7cf6a
--- /dev/null
+++ b/include/mysql/psi/mysql_thread.h
@@ -0,0 +1,1164 @@
+/* Copyright (C) 2008-2009 Sun Microsystems, Inc
+
+ 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 */
+
+#ifndef MYSQL_THREAD_H
+#define MYSQL_THREAD_H
+
+/**
+ @file mysql/psi/mysql_thread.h
+ Instrumentation helpers for mysys threads, mutexes,
+ read write locks and conditions.
+ This header file provides the necessary declarations
+ to use the mysys thread API with the performance schema instrumentation.
+ In some compilers (SunStudio), 'static inline' functions, when declared
+ but not used, are not optimized away (because they are unused) by default,
+ so that including a static inline function from a header file does
+ create unwanted dependencies, causing unresolved symbols at link time.
+ Other compilers, like gcc, optimize these dependencies by default.
+
+ Since the instrumented APIs declared here are wrapper on top
+ of my_pthread / safemutex / etc APIs,
+ including mysql/psi/mysql_thread.h assumes that
+ the dependency on my_pthread and safemutex already exists.
+*/
+/*
+ Note: there are several orthogonal dimensions here.
+
+ Dimension 1: Instrumentation
+ HAVE_PSI_INTERFACE is defined when the instrumentation is compiled in.
+ This may happen both in debug or production builds.
+
+ Dimension 2: Debug
+ SAFE_MUTEX is defined when debug is compiled in.
+ This may happen both with and without instrumentation.
+
+ Dimension 3: Platform
+ Mutexes are implemented with one of:
+ - the pthread library
+ - fast mutexes
+ - window apis
+ This is implemented by various macro definitions in my_pthread.h
+
+ This causes complexity with '#ifdef'-ery that can't be avoided.
+*/
+
+#include "mysql/psi/psi.h"
+
+/**
+ @defgroup Thread_instrumentation Thread Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ An instrumented mutex structure.
+ @sa mysql_mutex_t
+*/
+struct st_mysql_mutex
+{
+ /** The real mutex. */
+ pthread_mutex_t m_mutex;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_mutex_t interface.
+ */
+ struct PSI_mutex *m_psi;
+};
+
+/**
+ Type of an instrumented mutex.
+ @c mysql_mutex_t is a drop-in replacement for @c pthread_mutex_t.
+ @sa mysql_mutex_assert_owner
+ @sa mysql_mutex_assert_not_owner
+ @sa mysql_mutex_init
+ @sa mysql_mutex_lock
+ @sa mysql_mutex_unlock
+ @sa mysql_mutex_destroy
+*/
+typedef struct st_mysql_mutex mysql_mutex_t;
+
+/**
+ An instrumented rwlock structure.
+ @sa mysql_rwlock_t
+*/
+struct st_mysql_rwlock
+{
+ /** The real rwlock */
+ rw_lock_t m_rwlock;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_rwlock_t interface.
+ */
+ struct PSI_rwlock *m_psi;
+};
+
+/**
+ An instrumented prlock structure.
+ @sa mysql_prlock_t
+*/
+struct st_mysql_prlock
+{
+ /** The real prlock */
+ rw_pr_lock_t m_prlock;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_rwlock_t interface.
+ */
+ struct PSI_rwlock *m_psi;
+};
+
+/**
+ Type of an instrumented rwlock.
+ @c mysql_rwlock_t is a drop-in replacement for @c pthread_rwlock_t.
+ @sa mysql_rwlock_init
+ @sa mysql_rwlock_rdlock
+ @sa mysql_rwlock_tryrdlock
+ @sa mysql_rwlock_wrlock
+ @sa mysql_rwlock_trywrlock
+ @sa mysql_rwlock_unlock
+ @sa mysql_rwlock_destroy
+*/
+typedef struct st_mysql_rwlock mysql_rwlock_t;
+
+/**
+ Type of an instrumented prlock.
+ A prlock is a read write lock that 'prefers readers' (pr).
+ @c mysql_prlock_t is a drop-in replacement for @c rw_pr_lock_t.
+ @sa mysql_prlock_init
+ @sa mysql_prlock_rdlock
+ @sa mysql_prlock_tryrdlock
+ @sa mysql_prlock_wrlock
+ @sa mysql_prlock_trywrlock
+ @sa mysql_prlock_unlock
+ @sa mysql_prlock_destroy
+*/
+typedef struct st_mysql_prlock mysql_prlock_t;
+
+/**
+ An instrumented cond structure.
+ @sa mysql_cond_t
+*/
+struct st_mysql_cond
+{
+ /** The real condition */
+ pthread_cond_t m_cond;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_cond_t interface.
+ */
+ struct PSI_cond *m_psi;
+};
+
+/**
+ Type of an instrumented condition.
+ @c mysql_cond_t is a drop-in replacement for @c pthread_cond_t.
+ @sa mysql_cond_init
+ @sa mysql_cond_wait
+ @sa mysql_cond_timedwait
+ @sa mysql_cond_signal
+ @sa mysql_cond_broadcast
+ @sa mysql_cond_destroy
+*/
+typedef struct st_mysql_cond mysql_cond_t;
+
+/*
+ Consider the following code:
+ static inline void foo() { bar(); }
+ when foo() is never called.
+
+ With gcc, foo() is a local static function, so the dependencies
+ are optimized away at compile time, and there is no dependency on bar().
+ With other compilers (HP, Sun Studio), the function foo() implementation
+ is compiled, and bar() needs to be present to link.
+
+ Due to the existing header dependencies in MySQL code, this header file
+ is sometime used when it is not needed, which in turn cause link failures
+ on some platforms.
+ The proper fix would be to cut these extra dependencies in the calling code.
+ DISABLE_MYSQL_THREAD_H is a work around to limit dependencies.
+ DISABLE_MYSQL_PRLOCK_H is similar, and is used to disable specifically
+ the prlock wrappers.
+*/
+#ifndef DISABLE_MYSQL_THREAD_H
+
+/**
+ @def mysql_mutex_assert_owner(M)
+ Wrapper, to use safe_mutex_assert_owner with instrumented mutexes.
+ @c mysql_mutex_assert_owner is a drop-in replacement
+ for @c safe_mutex_assert_owner.
+*/
+#define mysql_mutex_assert_owner(M) \
+ safe_mutex_assert_owner(&(M)->m_mutex)
+
+/**
+ @def mysql_mutex_assert_not_owner(M)
+ Wrapper, to use safe_mutex_assert_not_owner with instrumented mutexes.
+ @c mysql_mutex_assert_not_owner is a drop-in replacement
+ for @c safe_mutex_assert_not_owner.
+*/
+#define mysql_mutex_assert_not_owner(M) \
+ safe_mutex_assert_not_owner(&(M)->m_mutex)
+
+/**
+ @def mysql_mutex_init(K, M, A)
+ Instrumented mutex_init.
+ @c mysql_mutex_init is a replacement for @c pthread_mutex_init.
+ @param K The PSI_mutex_key for this instrumented mutex
+ @param M The mutex to initialize
+ @param A Mutex attributes
+*/
+
+#ifdef HAVE_PSI_INTERFACE
+ #ifdef SAFE_MUTEX
+ #define mysql_mutex_init(K, M, A) \
+ inline_mysql_mutex_init(K, M, A, __FILE__, __LINE__)
+ #else
+ #define mysql_mutex_init(K, M, A) \
+ inline_mysql_mutex_init(K, M, A)
+ #endif
+#else
+ #ifdef SAFE_MUTEX
+ #define mysql_mutex_init(K, M, A) \
+ inline_mysql_mutex_init(M, A, __FILE__, __LINE__)
+ #else
+ #define mysql_mutex_init(K, M, A) \
+ inline_mysql_mutex_init(M, A)
+ #endif
+#endif
+
+/**
+ @def mysql_mutex_destroy(M)
+ Instrumented mutex_destroy.
+ @c mysql_mutex_destroy is a drop-in replacement
+ for @c pthread_mutex_destroy.
+*/
+#ifdef SAFE_MUTEX
+ #define mysql_mutex_destroy(M) \
+ inline_mysql_mutex_destroy(M, __FILE__, __LINE__)
+#else
+ #define mysql_mutex_destroy(M) \
+ inline_mysql_mutex_destroy(M)
+#endif
+
+/**
+ @def mysql_mutex_lock(M)
+ Instrumented mutex_lock.
+ @c mysql_mutex_lock is a drop-in replacement for @c pthread_mutex_lock.
+ @param M The mutex to lock
+*/
+
+#if defined(SAFE_MUTEX) || defined (HAVE_PSI_INTERFACE)
+ #define mysql_mutex_lock(M) \
+ inline_mysql_mutex_lock(M, __FILE__, __LINE__)
+#else
+ #define mysql_mutex_lock(M) \
+ inline_mysql_mutex_lock(M)
+#endif
+
+/**
+ @def mysql_mutex_trylock(M)
+ Instrumented mutex_lock.
+ @c mysql_mutex_trylock is a drop-in replacement
+ for @c pthread_mutex_trylock.
+*/
+
+#if defined(SAFE_MUTEX) || defined (HAVE_PSI_INTERFACE)
+ #define mysql_mutex_trylock(M) \
+ inline_mysql_mutex_trylock(M, __FILE__, __LINE__)
+#else
+ #define mysql_mutex_trylock(M) \
+ inline_mysql_mutex_trylock(M)
+#endif
+
+/**
+ @def mysql_mutex_unlock(M)
+ Instrumented mutex_unlock.
+ @c mysql_mutex_unlock is a drop-in replacement for @c pthread_mutex_unlock.
+*/
+#ifdef SAFE_MUTEX
+ #define mysql_mutex_unlock(M) \
+ inline_mysql_mutex_unlock(M, __FILE__, __LINE__)
+#else
+ #define mysql_mutex_unlock(M) \
+ inline_mysql_mutex_unlock(M)
+#endif
+
+/**
+ @def mysql_rwlock_init(K, RW)
+ Instrumented rwlock_init.
+ @c mysql_rwlock_init is a replacement for @c pthread_rwlock_init.
+ Note that pthread_rwlockattr_t is not supported in MySQL.
+ @param K The PSI_rwlock_key for this instrumented rwlock
+ @param RW The rwlock to initialize
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_rwlock_init(K, RW) inline_mysql_rwlock_init(K, RW)
+#else
+ #define mysql_rwlock_init(K, RW) inline_mysql_rwlock_init(RW)
+#endif
+
+/**
+ @def mysql_prlock_init(K, RW)
+ Instrumented rw_pr_init.
+ @c mysql_prlock_init is a replacement for @c rw_pr_init.
+ @param K The PSI_rwlock_key for this instrumented prlock
+ @param RW The prlock to initialize
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_prlock_init(K, RW) inline_mysql_prlock_init(K, RW)
+#else
+ #define mysql_prlock_init(K, RW) inline_mysql_prlock_init(RW)
+#endif
+
+/**
+ @def mysql_rwlock_destroy(RW)
+ Instrumented rwlock_destroy.
+ @c mysql_rwlock_destroy is a drop-in replacement
+ for @c pthread_rwlock_destroy.
+*/
+#define mysql_rwlock_destroy(RW) inline_mysql_rwlock_destroy(RW)
+
+/**
+ @def mysql_prlock_destroy(RW)
+ Instrumented rw_pr_destroy.
+ @c mysql_prlock_destroy is a drop-in replacement
+ for @c rw_pr_destroy.
+*/
+#define mysql_prlock_destroy(RW) inline_mysql_prlock_destroy(RW)
+
+/**
+ @def mysql_rwlock_rdlock(RW)
+ Instrumented rwlock_rdlock.
+ @c mysql_rwlock_rdlock is a drop-in replacement
+ for @c pthread_rwlock_rdlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_rwlock_rdlock(RW) \
+ inline_mysql_rwlock_rdlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_rwlock_rdlock(RW) \
+ inline_mysql_rwlock_rdlock(RW)
+#endif
+
+/**
+ @def mysql_prlock_rdlock(RW)
+ Instrumented rw_pr_rdlock.
+ @c mysql_prlock_rdlock is a drop-in replacement
+ for @c rw_pr_rdlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_prlock_rdlock(RW) \
+ inline_mysql_prlock_rdlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_prlock_rdlock(RW) \
+ inline_mysql_prlock_rdlock(RW)
+#endif
+
+/**
+ @def mysql_rwlock_wrlock(RW)
+ Instrumented rwlock_wrlock.
+ @c mysql_rwlock_wrlock is a drop-in replacement
+ for @c pthread_rwlock_wrlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_rwlock_wrlock(RW) \
+ inline_mysql_rwlock_wrlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_rwlock_wrlock(RW) \
+ inline_mysql_rwlock_wrlock(RW)
+#endif
+
+/**
+ @def mysql_prlock_wrlock(RW)
+ Instrumented rw_pr_wrlock.
+ @c mysql_prlock_wrlock is a drop-in replacement
+ for @c rw_pr_wrlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_prlock_wrlock(RW) \
+ inline_mysql_prlock_wrlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_prlock_wrlock(RW) \
+ inline_mysql_prlock_wrlock(RW)
+#endif
+
+/**
+ @def mysql_rwlock_tryrdlock(RW)
+ Instrumented rwlock_tryrdlock.
+ @c mysql_rwlock_tryrdlock is a drop-in replacement
+ for @c pthread_rwlock_tryrdlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_rwlock_tryrdlock(RW) \
+ inline_mysql_rwlock_tryrdlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_rwlock_tryrdlock(RW) \
+ inline_mysql_rwlock_tryrdlock(RW)
+#endif
+
+/**
+ @def mysql_prlock_tryrdlock(RW)
+ Instrumented rw_pr_tryrdlock.
+ @c mysql_prlock_tryrdlock is a drop-in replacement
+ for @c rw_pr_tryrdlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_prlock_tryrdlock(RW) \
+ inline_mysql_prlock_tryrdlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_prlock_tryrdlock(RW) \
+ inline_mysql_prlock_tryrdlock(RW)
+#endif
+
+/**
+ @def mysql_rwlock_trywrlock(RW)
+ Instrumented rwlock_trywrlock.
+ @c mysql_rwlock_trywrlock is a drop-in replacement
+ for @c pthread_rwlock_trywrlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_rwlock_trywrlock(RW) \
+ inline_mysql_rwlock_trywrlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_rwlock_trywrlock(RW) \
+ inline_mysql_rwlock_trywrlock(RW)
+#endif
+
+/**
+ @def mysql_prlock_trywrlock(RW)
+ Instrumented rw_pr_trywrlock.
+ @c mysql_prlock_trywrlock is a drop-in replacement
+ for @c rw_pr_trywrlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_prlock_trywrlock(RW) \
+ inline_mysql_prlock_trywrlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_prlock_trywrlock(RW) \
+ inline_mysql_prlock_trywrlock(RW)
+#endif
+
+/**
+ @def mysql_rwlock_unlock(RW)
+ Instrumented rwlock_unlock.
+ @c mysql_rwlock_unlock is a drop-in replacement
+ for @c pthread_rwlock_unlock.
+*/
+#define mysql_rwlock_unlock(RW) inline_mysql_rwlock_unlock(RW)
+
+/**
+ @def mysql_prlock_unlock(RW)
+ Instrumented rw_pr_unlock.
+ @c mysql_prlock_unlock is a drop-in replacement
+ for @c rw_pr_unlock.
+*/
+#define mysql_prlock_unlock(RW) inline_mysql_prlock_unlock(RW)
+
+/**
+ @def mysql_cond_init(K, C, A)
+ Instrumented cond_init.
+ @c mysql_cond_init is a replacement for @c pthread_cond_init.
+ @param C The cond to initialize
+ @param K The PSI_cond_key for this instrumented cond
+ @param A Condition attributes
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_cond_init(K, C, A) inline_mysql_cond_init(K, C, A)
+#else
+ #define mysql_cond_init(K, C, A) inline_mysql_cond_init(C, A)
+#endif
+
+/**
+ @def mysql_cond_destroy(C)
+ Instrumented cond_destroy.
+ @c mysql_cond_destroy is a drop-in replacement for @c pthread_cond_destroy.
+*/
+#define mysql_cond_destroy(C) inline_mysql_cond_destroy(C)
+
+/**
+ @def mysql_cond_wait(C)
+ Instrumented cond_wait.
+ @c mysql_cond_wait is a drop-in replacement for @c pthread_cond_wait.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_cond_wait(C, M) \
+ inline_mysql_cond_wait(C, M, __FILE__, __LINE__)
+#else
+ #define mysql_cond_wait(C, M) \
+ inline_mysql_cond_wait(C, M)
+#endif
+
+/**
+ @def mysql_cond_timedwait(C, M, W)
+ Instrumented cond_timedwait.
+ @c mysql_cond_timedwait is a drop-in replacement
+ for @c pthread_cond_timedwait.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_cond_timedwait(C, M, W) \
+ inline_mysql_cond_timedwait(C, M, W, __FILE__, __LINE__)
+#else
+ #define mysql_cond_timedwait(C, M, W) \
+ inline_mysql_cond_timedwait(C, M, W)
+#endif
+
+/**
+ @def mysql_cond_signal(C)
+ Instrumented cond_signal.
+ @c mysql_cond_signal is a drop-in replacement for @c pthread_cond_signal.
+*/
+#define mysql_cond_signal(C) inline_mysql_cond_signal(C)
+
+/**
+ @def mysql_cond_broadcast(C)
+ Instrumented cond_broadcast.
+ @c mysql_cond_broadcast is a drop-in replacement
+ for @c pthread_cond_broadcast.
+*/
+#define mysql_cond_broadcast(C) inline_mysql_cond_broadcast(C)
+
+
+/**
+ @def mysql_thread_create(K, P1, P2, P3, P4)
+ Instrumented pthread_create.
+ This function creates both the thread instrumentation and a thread.
+ @c mysql_thread_create is a replacement for @c pthread_create.
+ The parameter P4 (or, if it is NULL, P1) will be used as the
+ instrumented thread "indentity".
+ Providing a P1 / P4 parameter with a different value for each call
+ will on average improve performances, since this thread identity value
+ is used internally to randomize access to data and prevent contention.
+ This is optional, and the improvement is not guaranteed, only statistical.
+ @param K The PSI_thread_key for this instrumented thread
+ @param P1 pthread_create parameter 1
+ @param P2 pthread_create parameter 2
+ @param P3 pthread_create parameter 3
+ @param P4 pthread_create parameter 4
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_thread_create(K, P1, P2, P3, P4) \
+ inline_mysql_thread_create(K, P1, P2, P3, P4)
+#else
+ #define mysql_thread_create(K, P1, P2, P3, P4) \
+ pthread_create(P1, P2, P3, P4)
+#endif
+
+/**
+ @def mysql_thread_set_psi_id(I)
+ Set the thread indentifier for the instrumentation.
+ @param I The thread identifier
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_thread_set_psi_id(I) inline_mysql_thread_set_psi_id(I)
+#else
+ #define mysql_thread_set_psi_id(I) do {} while (0)
+#endif
+
+static inline int inline_mysql_mutex_init(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_mutex_key key,
+#endif
+ mysql_mutex_t *that,
+ const pthread_mutexattr_t *attr
+#ifdef SAFE_MUTEX
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+#ifdef HAVE_PSI_INTERFACE
+ that->m_psi= PSI_server ? PSI_server->init_mutex(key, &that->m_mutex)
+ : NULL;
+#else
+ that->m_psi= NULL;
+#endif
+#ifdef SAFE_MUTEX
+ return safe_mutex_init(&that->m_mutex, attr, src_file, src_line);
+#else
+ return pthread_mutex_init(&that->m_mutex, attr);
+#endif
+}
+
+static inline int inline_mysql_mutex_destroy(
+ mysql_mutex_t *that
+#ifdef SAFE_MUTEX
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(PSI_server && that->m_psi))
+ {
+ PSI_server->destroy_mutex(that->m_psi);
+ that->m_psi= NULL;
+ }
+#endif
+#ifdef SAFE_MUTEX
+ return safe_mutex_destroy(&that->m_mutex, src_file, src_line);
+#else
+ return pthread_mutex_destroy(&that->m_mutex);
+#endif
+}
+
+static inline int inline_mysql_mutex_lock(
+ mysql_mutex_t *that
+#if defined(SAFE_MUTEX) || defined (HAVE_PSI_INTERFACE)
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_mutex_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_mutex_locker(that->m_psi, PSI_MUTEX_LOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_mutex_wait(locker, src_file, src_line);
+ }
+#endif
+#ifdef SAFE_MUTEX
+ result= safe_mutex_lock(&that->m_mutex, FALSE, src_file, src_line);
+#else
+ result= pthread_mutex_lock(&that->m_mutex);
+#endif
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_mutex_wait(locker, result);
+#endif
+ return result;
+}
+
+static inline int inline_mysql_mutex_trylock(
+ mysql_mutex_t *that
+#if defined(SAFE_MUTEX) || defined (HAVE_PSI_INTERFACE)
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_mutex_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_mutex_locker(that->m_psi, PSI_MUTEX_TRYLOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_mutex_wait(locker, src_file, src_line);
+ }
+#endif
+#ifdef SAFE_MUTEX
+ result= safe_mutex_lock(&that->m_mutex, TRUE, src_file, src_line);
+#else
+ result= pthread_mutex_trylock(&that->m_mutex);
+#endif
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_mutex_wait(locker, result);
+#endif
+ return result;
+}
+
+static inline int inline_mysql_mutex_unlock(
+ mysql_mutex_t *that
+#ifdef SAFE_MUTEX
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_thread *thread;
+ if (likely(PSI_server && that->m_psi))
+ {
+ thread= PSI_server->get_thread();
+ if (likely(thread != NULL))
+ PSI_server->unlock_mutex(thread, that->m_psi);
+ }
+#endif
+#ifdef SAFE_MUTEX
+ result= safe_mutex_unlock(&that->m_mutex, src_file, src_line);
+#else
+ result= pthread_mutex_unlock(&that->m_mutex);
+#endif
+ return result;
+}
+
+static inline int inline_mysql_rwlock_init(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_rwlock_key key,
+#endif
+ mysql_rwlock_t *that)
+{
+#ifdef HAVE_PSI_INTERFACE
+ that->m_psi= (PSI_server ? PSI_server->init_rwlock(key, &that->m_rwlock)
+ : NULL);
+#else
+ that->m_psi= NULL;
+#endif
+ /*
+ pthread_rwlockattr_t is not used in MySQL.
+ */
+ return my_rwlock_init(&that->m_rwlock, NULL);
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_init(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_rwlock_key key,
+#endif
+ mysql_prlock_t *that)
+{
+#ifdef HAVE_PSI_INTERFACE
+ that->m_psi= (PSI_server ? PSI_server->init_rwlock(key, &that->m_prlock)
+ : NULL);
+#else
+ that->m_psi= NULL;
+#endif
+ return rw_pr_init(&that->m_prlock);
+}
+#endif
+
+static inline int inline_mysql_rwlock_destroy(
+ mysql_rwlock_t *that)
+{
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(PSI_server && that->m_psi))
+ {
+ PSI_server->destroy_rwlock(that->m_psi);
+ that->m_psi= NULL;
+ }
+#endif
+ return rwlock_destroy(&that->m_rwlock);
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_destroy(
+ mysql_prlock_t *that)
+{
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(PSI_server && that->m_psi))
+ {
+ PSI_server->destroy_rwlock(that->m_psi);
+ that->m_psi= NULL;
+ }
+#endif
+ return rw_pr_destroy(&that->m_prlock);
+}
+#endif
+
+static inline int inline_mysql_rwlock_rdlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_READLOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_rdwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_rdlock(&that->m_rwlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_rdwait(locker, result);
+#endif
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_rdlock(
+ mysql_prlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_READLOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_rdwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_pr_rdlock(&that->m_prlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_rdwait(locker, result);
+#endif
+ return result;
+}
+#endif
+
+static inline int inline_mysql_rwlock_wrlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_WRITELOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_wrwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_wrlock(&that->m_rwlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_wrwait(locker, result);
+#endif
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_wrlock(
+ mysql_prlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_WRITELOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_wrwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_pr_wrlock(&that->m_prlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_wrwait(locker, result);
+#endif
+ return result;
+}
+#endif
+
+static inline int inline_mysql_rwlock_tryrdlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_TRYREADLOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_rdwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_tryrdlock(&that->m_rwlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_rdwait(locker, result);
+#endif
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_tryrdlock(
+ mysql_prlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_TRYREADLOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_rdwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_pr_tryrdlock(&that->m_prlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_rdwait(locker, result);
+#endif
+ return result;
+}
+#endif
+
+static inline int inline_mysql_rwlock_trywrlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_TRYWRITELOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_wrwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_trywrlock(&that->m_rwlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_wrwait(locker, result);
+#endif
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_trywrlock(
+ mysql_prlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_TRYWRITELOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_wrwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_pr_trywrlock(&that->m_prlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_wrwait(locker, result);
+#endif
+ return result;
+}
+#endif
+
+static inline int inline_mysql_rwlock_unlock(
+ mysql_rwlock_t *that)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_thread *thread;
+ if (likely(PSI_server && that->m_psi))
+ {
+ thread= PSI_server->get_thread();
+ if (likely(thread != NULL))
+ PSI_server->unlock_rwlock(thread, that->m_psi);
+ }
+#endif
+ result= rw_unlock(&that->m_rwlock);
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_unlock(
+ mysql_prlock_t *that)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_thread *thread;
+ if (likely(PSI_server && that->m_psi))
+ {
+ thread= PSI_server->get_thread();
+ if (likely(thread != NULL))
+ PSI_server->unlock_rwlock(thread, that->m_psi);
+ }
+#endif
+ result= rw_pr_unlock(&that->m_prlock);
+ return result;
+}
+#endif
+
+static inline int inline_mysql_cond_init(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_cond_key key,
+#endif
+ mysql_cond_t *that,
+ const pthread_condattr_t *attr)
+{
+#ifdef HAVE_PSI_INTERFACE
+ that->m_psi= (PSI_server ? PSI_server->init_cond(key, &that->m_cond)
+ : NULL);
+#else
+ that->m_psi= NULL;
+#endif
+ return pthread_cond_init(&that->m_cond, attr);
+}
+
+static inline int inline_mysql_cond_destroy(
+ mysql_cond_t *that)
+{
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(PSI_server && that->m_psi))
+ {
+ PSI_server->destroy_cond(that->m_psi);
+ that->m_psi= NULL;
+ }
+#endif
+ return pthread_cond_destroy(&that->m_cond);
+}
+
+static inline int inline_mysql_cond_wait(
+ mysql_cond_t *that,
+ mysql_mutex_t *mutex
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_cond_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_cond_locker(that->m_psi, mutex->m_psi,
+ PSI_COND_WAIT);
+ if (likely(locker != NULL))
+ PSI_server->start_cond_wait(locker, src_file, src_line);
+ }
+#endif
+ result= pthread_cond_wait(&that->m_cond, &mutex->m_mutex);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_cond_wait(locker, result);
+#endif
+ return result;
+}
+
+static inline int inline_mysql_cond_timedwait(
+ mysql_cond_t *that,
+ mysql_mutex_t *mutex,
+ struct timespec *abstime
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_cond_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_cond_locker(that->m_psi, mutex->m_psi,
+ PSI_COND_TIMEDWAIT);
+ if (likely(locker != NULL))
+ PSI_server->start_cond_wait(locker, src_file, src_line);
+ }
+#endif
+ result= pthread_cond_timedwait(&that->m_cond, &mutex->m_mutex, abstime);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_cond_wait(locker, result);
+#endif
+ return result;
+}
+
+static inline int inline_mysql_cond_signal(
+ mysql_cond_t *that)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_thread *thread;
+ if (likely(PSI_server && that->m_psi))
+ {
+ thread= PSI_server->get_thread();
+ if (likely(thread != NULL))
+ PSI_server->signal_cond(thread, that->m_psi);
+ }
+#endif
+ result= pthread_cond_signal(&that->m_cond);
+ return result;
+}
+
+static inline int inline_mysql_cond_broadcast(
+ mysql_cond_t *that)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_thread *thread;
+ if (likely(PSI_server && that->m_psi))
+ {
+ thread= PSI_server->get_thread();
+ if (likely(thread != NULL))
+ PSI_server->broadcast_cond(thread, that->m_psi);
+ }
+#endif
+ result= pthread_cond_broadcast(&that->m_cond);
+ return result;
+}
+
+#ifdef HAVE_PSI_INTERFACE
+static inline int inline_mysql_thread_create(
+ PSI_thread_key key,
+ pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void*), void *arg)
+{
+ int result;
+ if (likely(PSI_server != NULL))
+ result= PSI_server->spawn_thread(key, thread, attr, start_routine, arg);
+ else
+ result= pthread_create(thread, attr, start_routine, arg);
+ return result;
+}
+
+static inline void inline_mysql_thread_set_psi_id(ulong id)
+{
+ if (likely(PSI_server != NULL))
+ {
+ struct PSI_thread *psi= PSI_server->get_thread();
+ if (likely(psi != NULL))
+ PSI_server->set_thread_id(psi, id);
+ }
+}
+#endif
+
+#endif /* DISABLE_MYSQL_THREAD_H */
+
+/** @} (end of group Thread_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/psi.h b/include/mysql/psi/psi.h
new file mode 100644
index 00000000000..51446fa83a5
--- /dev/null
+++ b/include/mysql/psi/psi.h
@@ -0,0 +1,1091 @@
+/* Copyright (C) 2008-2010 Sun Microsystems, Inc
+
+ 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 */
+
+#ifndef MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H
+#define MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H
+
+#ifndef _global_h
+/*
+ Make sure a .c or .cc file contains an include to my_global.h first.
+ When this include is missing, all the #ifdef HAVE_XXX have no effect,
+ and the resulting binary won't build, or won't link,
+ or will crash at runtime
+ since various structures will have different binary definitions.
+*/
+#error "You must include my_global.h in the code for the build to be correct."
+#endif
+
+C_MODE_START
+
+/**
+ @file mysql/psi/psi.h
+ Performance schema instrumentation interface.
+
+ @defgroup Instrumentation_interface Instrumentation Interface
+ @ingroup Performance_schema
+ @{
+*/
+
+/**
+ Interface for an instrumented mutex.
+ This is an opaque structure.
+*/
+struct PSI_mutex;
+
+/**
+ Interface for an instrumented rwlock.
+ This is an opaque structure.
+*/
+struct PSI_rwlock;
+
+/**
+ Interface for an instrumented condition.
+ This is an opaque structure.
+*/
+struct PSI_cond;
+
+/**
+ Interface for an instrumented table share.
+ This is an opaque structure.
+*/
+struct PSI_table_share;
+
+/**
+ Interface for an instrumented table handle.
+ This is an opaque structure.
+*/
+struct PSI_table;
+
+/**
+ Interface for an instrumented thread.
+ This is an opaque structure.
+*/
+struct PSI_thread;
+
+/**
+ Interface for an instrumented file handle.
+ This is an opaque structure.
+*/
+struct PSI_file;
+
+/** Entry point for the performance schema interface. */
+struct PSI_bootstrap
+{
+ /**
+ ABI interface finder.
+ Calling this method with an interface version number returns either
+ an instance of the ABI for this version, or NULL.
+ @param version the interface version number to find
+ @return a versioned interface (PSI_v1, PSI_v2 or PSI)
+ @sa PSI_VERSION_1
+ @sa PSI_v1
+ @sa PSI_VERSION_2
+ @sa PSI_v2
+ @sa PSI_CURRENT_VERSION
+ @sa PSI
+ */
+ void* (*get_interface)(int version);
+};
+
+#ifdef HAVE_PSI_INTERFACE
+
+/**
+ @def PSI_VERSION_1
+ Performance Schema Interface number for version 1.
+ This version is supported.
+*/
+#define PSI_VERSION_1 1
+
+/**
+ @def PSI_VERSION_2
+ Performance Schema Interface number for version 2.
+ This version is not implemented, it's a placeholder.
+*/
+#define PSI_VERSION_2 2
+
+/**
+ @def PSI_CURRENT_VERSION
+ Performance Schema Interface number for the most recent version.
+ The most current version is @c PSI_VERSION_1
+*/
+#define PSI_CURRENT_VERSION 1
+
+#ifndef USE_PSI_2
+#ifndef USE_PSI_1
+#define USE_PSI_1
+#endif
+#endif
+
+/**
+ Interface for an instrumented mutex operation.
+ This is an opaque structure.
+*/
+struct PSI_mutex_locker;
+
+/**
+ Interface for an instrumented rwlock operation.
+ This is an opaque structure.
+*/
+
+struct PSI_rwlock_locker;
+/**
+ Interface for an instrumented condition operation.
+ This is an opaque structure.
+*/
+
+struct PSI_cond_locker;
+
+/**
+ Interface for an instrumented file operation.
+ This is an opaque structure.
+*/
+struct PSI_file_locker;
+
+/** Operation performed on an instrumented mutex. */
+enum PSI_mutex_operation
+{
+ /** Lock. */
+ PSI_MUTEX_LOCK= 0,
+ /** Lock attempt. */
+ PSI_MUTEX_TRYLOCK= 1
+};
+
+/** Operation performed on an instrumented rwlock. */
+enum PSI_rwlock_operation
+{
+ /** Read lock. */
+ PSI_RWLOCK_READLOCK= 0,
+ /** Write lock. */
+ PSI_RWLOCK_WRITELOCK= 1,
+ /** Read lock attempt. */
+ PSI_RWLOCK_TRYREADLOCK= 2,
+ /** Write lock attempt. */
+ PSI_RWLOCK_TRYWRITELOCK= 3
+};
+
+/** Operation performed on an instrumented condition. */
+enum PSI_cond_operation
+{
+ /** Wait. */
+ PSI_COND_WAIT= 0,
+ /** Wait, with timeout. */
+ PSI_COND_TIMEDWAIT= 1
+};
+
+/** Operation performed on an instrumented file. */
+enum PSI_file_operation
+{
+ /** File creation, as in @c create(). */
+ PSI_FILE_CREATE= 0,
+ /** Temporary file creation, as in @c create_temp_file(). */
+ PSI_FILE_CREATE_TMP= 1,
+ /** File open, as in @c open(). */
+ PSI_FILE_OPEN= 2,
+ /** File open, as in @c fopen(). */
+ PSI_FILE_STREAM_OPEN= 3,
+ /** File close, as in @c close(). */
+ PSI_FILE_CLOSE= 4,
+ /** File close, as in @c fclose(). */
+ PSI_FILE_STREAM_CLOSE= 5,
+ /**
+ Generic file read, such as @c fgets(), @c fgetc(), @c fread(), @c read(),
+ @c pread().
+ */
+ PSI_FILE_READ= 6,
+ /**
+ Generic file write, such as @c fputs(), @c fputc(), @c fprintf(),
+ @c vfprintf(), @c fwrite(), @c write(), @c pwrite().
+ */
+ PSI_FILE_WRITE= 7,
+ /** Generic file seek, such as @c fseek() or @c seek(). */
+ PSI_FILE_SEEK= 8,
+ /** Generic file tell, such as @c ftell() or @c tell(). */
+ PSI_FILE_TELL= 9,
+ /** File flush, as in @c fflush(). */
+ PSI_FILE_FLUSH= 10,
+ /** File stat, as in @c stat(). */
+ PSI_FILE_STAT= 11,
+ /** File stat, as in @c fstat(). */
+ PSI_FILE_FSTAT= 12,
+ /** File chsize, as in @c my_chsize(). */
+ PSI_FILE_CHSIZE= 13,
+ /** File delete, such as @c my_delete() or @c my_delete_with_symlink(). */
+ PSI_FILE_DELETE= 14,
+ /** File rename, such as @c my_rename() or @c my_rename_with_symlink(). */
+ PSI_FILE_RENAME= 15,
+ /** File sync, as in @c fsync() or @c my_sync(). */
+ PSI_FILE_SYNC= 16
+};
+
+/**
+ Interface for an instrumented table operation.
+ This is an opaque structure.
+*/
+struct PSI_table_locker;
+
+/**
+ Instrumented mutex key.
+ To instrument a mutex, a mutex key must be obtained using @c register_mutex.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_mutex_key;
+
+/**
+ Instrumented rwlock key.
+ To instrument a rwlock, a rwlock key must be obtained
+ using @c register_rwlock.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_rwlock_key;
+
+/**
+ Instrumented cond key.
+ To instrument a condition, a condition key must be obtained
+ using @c register_cond.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_cond_key;
+
+/**
+ Instrumented thread key.
+ To instrument a thread, a thread key must be obtained
+ using @c register_thread.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_thread_key;
+
+/**
+ Instrumented file key.
+ To instrument a file, a file key must be obtained using @c register_file.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_file_key;
+
+/**
+ @def USE_PSI_1
+ Define USE_PSI_1 to use the interface version 1.
+*/
+
+/**
+ @def USE_PSI_2
+ Define USE_PSI_2 to use the interface version 2.
+*/
+
+/**
+ @def HAVE_PSI_1
+ Define HAVE_PSI_1 if the interface version 1 needs to be compiled in.
+*/
+
+/**
+ @def HAVE_PSI_2
+ Define HAVE_PSI_2 if the interface version 2 needs to be compiled in.
+*/
+
+/**
+ Global flag.
+ This flag indicate that an instrumentation point is a global variable,
+ or a singleton.
+*/
+#define PSI_FLAG_GLOBAL (1 << 0)
+
+#ifdef USE_PSI_1
+#define HAVE_PSI_1
+#endif
+
+#ifdef HAVE_PSI_1
+
+/**
+ @defgroup Group_PSI_v1 Application Binary Interface, version 1
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ Mutex information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented mutex.
+*/
+struct PSI_mutex_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered mutex.
+ */
+ PSI_mutex_key *m_key;
+ /**
+ The name of the mutex to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the mutex to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+
+/**
+ Rwlock information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented rwlock.
+*/
+struct PSI_rwlock_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered rwlock.
+ */
+ PSI_rwlock_key *m_key;
+ /**
+ The name of the rwlock to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the rwlock to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+
+/**
+ Condition information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented cond.
+*/
+struct PSI_cond_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered cond.
+ */
+ PSI_cond_key *m_key;
+ /**
+ The name of the cond to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the cond to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+
+/**
+ Thread instrument information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented thread.
+*/
+struct PSI_thread_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered thread.
+ */
+ PSI_thread_key *m_key;
+ /**
+ The name of the thread instrument to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the thread to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+
+/**
+ File instrument information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented file.
+*/
+struct PSI_file_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered file.
+ */
+ PSI_file_key *m_key;
+ /**
+ The name of the file instrument to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the file instrument to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+
+/* Using typedef to make reuse between PSI_v1 and PSI_v2 easier later. */
+
+/**
+ Mutex registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of mutex info to register
+ @param count the size of the info array
+*/
+typedef void (*register_mutex_v1_t)
+ (const char *category, struct PSI_mutex_info_v1 *info, int count);
+
+/**
+ Rwlock registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of rwlock info to register
+ @param count the size of the info array
+*/
+typedef void (*register_rwlock_v1_t)
+ (const char *category, struct PSI_rwlock_info_v1 *info, int count);
+
+/**
+ Cond registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of cond info to register
+ @param count the size of the info array
+*/
+typedef void (*register_cond_v1_t)
+ (const char *category, struct PSI_cond_info_v1 *info, int count);
+
+/**
+ Thread registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of thread info to register
+ @param count the size of the info array
+*/
+typedef void (*register_thread_v1_t)
+ (const char *category, struct PSI_thread_info_v1 *info, int count);
+
+/**
+ File registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of file info to register
+ @param count the size of the info array
+*/
+typedef void (*register_file_v1_t)
+ (const char *category, struct PSI_file_info_v1 *info, int count);
+
+/**
+ Mutex instrumentation initialisation API.
+ @param key the registered mutex key
+ @param identity the address of the mutex itself
+ @return an instrumented mutex
+*/
+typedef struct PSI_mutex* (*init_mutex_v1_t)
+ (PSI_mutex_key key, const void *identity);
+
+/**
+ Mutex instrumentation destruction API.
+ @param mutex the mutex to destroy
+*/
+typedef void (*destroy_mutex_v1_t)(struct PSI_mutex *mutex);
+
+/**
+ Rwlock instrumentation initialisation API.
+ @param key the registered rwlock key
+ @param identity the address of the rwlock itself
+ @return an instrumented rwlock
+*/
+typedef struct PSI_rwlock* (*init_rwlock_v1_t)
+ (PSI_rwlock_key key, const void *identity);
+
+/**
+ Rwlock instrumentation destruction API.
+ @param rwlock the rwlock to destroy
+*/
+typedef void (*destroy_rwlock_v1_t)(struct PSI_rwlock *rwlock);
+
+/**
+ Cond instrumentation initialisation API.
+ @param key the registered key
+ @param identity the address of the rwlock itself
+ @return an instrumented cond
+*/
+typedef struct PSI_cond* (*init_cond_v1_t)
+ (PSI_cond_key key, const void *identity);
+
+/**
+ Cond instrumentation destruction API.
+ @param cond the rcond to destroy
+*/
+typedef void (*destroy_cond_v1_t)(struct PSI_cond *cond);
+
+/**
+ Acquire a table info by name.
+ @param schema_name name of the table schema
+ @param schema_name_length length of schema_name
+ @param table_name name of the table
+ @param table_name_length length of table_name
+ @param identity table identity pointer, typically the table share
+ @return a table info, or NULL if the table is not instrumented
+*/
+typedef struct PSI_table_share* (*get_table_share_v1_t)
+ (const char *schema_name, int schema_name_length, const char *table_name,
+ int table_name_length, const void *identity);
+
+/**
+ Release a table share.
+ @param info the table share to release
+*/
+typedef void (*release_table_share_v1_t)(struct PSI_table_share *share);
+
+/**
+ Open an instrumentation table handle.
+ @param share the table to open
+ @param identity table handle identity
+ @return a table handle, or NULL
+*/
+typedef struct PSI_table* (*open_table_v1_t)
+ (struct PSI_table_share *share, const void *identity);
+
+/**
+ Close an instrumentation table handle.
+ Note that the table handle is invalid after this call.
+ @param table the table handle to close
+*/
+typedef void (*close_table_v1_t)(struct PSI_table *table);
+
+/**
+ Create a file instrumentation for a created file.
+ This method does not create the file itself, but is used to notify the
+ instrumentation interface that a file was just created.
+ @param key the file instrumentation key for this file
+ @param name the file name
+ @param file the file handle
+*/
+typedef void (*create_file_v1_t)(PSI_file_key key, const char *name,
+ File file);
+
+/**
+ Spawn a thread.
+ This method creates a new thread, with instrumentation.
+ @param key the instrumentation key for this thread
+ @param thread the resulting thread
+ @param attr the thread attributes
+ @param start_routine the thread start routine
+ @param arg the thread start routine argument
+*/
+typedef int (*spawn_thread_v1_t)(PSI_thread_key key,
+ pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void*), void *arg);
+
+/**
+ Create instrumentation for a thread.
+ @param key the registered key
+ @param identity an address typical of the thread
+ @return an instrumented thread
+*/
+typedef struct PSI_thread* (*new_thread_v1_t)
+ (PSI_thread_key key, const void *identity, ulong thread_id);
+
+/**
+ Assign an id to an instrumented thread.
+ @param thread the instrumented thread
+ @param id the id to assign
+*/
+typedef void (*set_thread_id_v1_t)(struct PSI_thread *thread,
+ unsigned long id);
+
+/**
+ Get the instrumentation for the running thread.
+ For this function to return a result,
+ the thread instrumentation must have been attached to the
+ running thread using @c set_thread()
+ @return the instrumentation for the running thread
+*/
+typedef struct PSI_thread* (*get_thread_v1_t)(void);
+
+/**
+ Attach a thread instrumentation to the running thread.
+ In case of thread pools, this method should be called when
+ a worker thread picks a work item and runs it.
+ Also, this method should be called if the instrumented code does not
+ keep the pointer returned by @c new_thread() and relies on @c get_thread()
+ instead.
+ @param thread the thread instrumentation
+*/
+typedef void (*set_thread_v1_t)(struct PSI_thread *thread);
+
+/** Delete the current thread instrumentation. */
+typedef void (*delete_current_thread_v1_t)(void);
+
+/** Delete a thread instrumentation. */
+typedef void (*delete_thread_v1_t)(struct PSI_thread *thread);
+
+/**
+ Get a mutex instrumentation locker.
+ @param mutex the instrumented mutex to lock
+ @return a mutex locker, or NULL
+*/
+typedef struct PSI_mutex_locker* (*get_thread_mutex_locker_v1_t)
+ (struct PSI_mutex *mutex, enum PSI_mutex_operation op);
+
+/**
+ Get a rwlock instrumentation locker.
+ @param rwlock the instrumented rwlock to lock
+ @return a rwlock locker, or NULL
+*/
+typedef struct PSI_rwlock_locker* (*get_thread_rwlock_locker_v1_t)
+ (struct PSI_rwlock *rwlock, enum PSI_rwlock_operation op);
+
+/**
+ Get a cond instrumentation locker.
+ @param cond the instrumented condition to wait on
+ @param mutex the instrumented mutex associated with the condition
+ @return a condition locker, or NULL
+*/
+typedef struct PSI_cond_locker* (*get_thread_cond_locker_v1_t)
+ (struct PSI_cond *cond, struct PSI_mutex *mutex,
+ enum PSI_cond_operation op);
+
+/**
+ Get a table instrumentation locker.
+ @param table the instrumented table to lock
+ @return a table locker, or NULL
+*/
+typedef struct PSI_table_locker* (*get_thread_table_locker_v1_t)
+ (struct PSI_table *table);
+
+/**
+ Get a file instrumentation locker, for opening or creating a file.
+ @param key the file instrumentation key
+ @param op the operation to perform
+ @param name the file name
+ @param identity a pointer representative of this file.
+ @return a file locker, or NULL
+*/
+typedef struct PSI_file_locker* (*get_thread_file_name_locker_v1_t)
+ (PSI_file_key key, enum PSI_file_operation op, const char *name,
+ const void *identity);
+
+/**
+ Get a file stream instrumentation locker.
+ @param file the file stream to access
+ @param op the operation to perform
+ @return a file locker, or NULL
+*/
+typedef struct PSI_file_locker* (*get_thread_file_stream_locker_v1_t)
+ (struct PSI_file *file, enum PSI_file_operation op);
+
+/**
+ Get a file instrumentation locker.
+ @param file the file descriptor to access
+ @param op the operation to perform
+ @return a file locker, or NULL
+*/
+typedef struct PSI_file_locker* (*get_thread_file_descriptor_locker_v1_t)
+ (File file, enum PSI_file_operation op);
+
+/**
+ Record a mutex instrumentation unlock event.
+ @param thread the running thread instrumentation
+ @param mutex the mutex instrumentation
+*/
+typedef void (*unlock_mutex_v1_t)
+ (struct PSI_thread *thread, struct PSI_mutex *mutex);
+
+/**
+ Record a rwlock instrumentation unlock event.
+ @param thread the running thread instrumentation
+ @param rwlock the rwlock instrumentation
+*/
+typedef void (*unlock_rwlock_v1_t)
+ (struct PSI_thread *thread, struct PSI_rwlock *rwlock);
+
+/**
+ Record a condition instrumentation signal event.
+ @param thread the running thread instrumentation
+ @param cond the cond instrumentation
+*/
+typedef void (*signal_cond_v1_t)
+ (struct PSI_thread *thread, struct PSI_cond *cond);
+
+/**
+ Record a condition instrumentation broadcast event.
+ @param thread the running thread instrumentation
+ @param cond the cond instrumentation
+*/
+typedef void (*broadcast_cond_v1_t)
+ (struct PSI_thread *thread, struct PSI_cond *cond);
+
+/**
+ Record a mutex instrumentation wait start event.
+ @param locker a thread locker for the running thread
+*/
+typedef void (*start_mutex_wait_v1_t)
+ (struct PSI_mutex_locker *locker, const char *src_file, uint src_line);
+
+/**
+ Record a mutex instrumentation wait end event.
+ @param locker a thread locker for the running thread
+ @param rc the wait operation return code
+*/
+typedef void (*end_mutex_wait_v1_t)
+ (struct PSI_mutex_locker *locker, int rc);
+
+/**
+ Record a rwlock instrumentation read wait start event.
+ @param locker a thread locker for the running thread
+ @param must must block: 1 for lock, 0 for trylock
+*/
+typedef void (*start_rwlock_rdwait_v1_t)
+ (struct PSI_rwlock_locker *locker, const char *src_file, uint src_line);
+
+/**
+ Record a rwlock instrumentation read wait end event.
+ @param locker a thread locker for the running thread
+ @param rc the wait operation return code
+*/
+typedef void (*end_rwlock_rdwait_v1_t)
+ (struct PSI_rwlock_locker *locker, int rc);
+
+/**
+ Record a rwlock instrumentation write wait start event.
+ @param locker a thread locker for the running thread
+ @param must must block: 1 for lock, 0 for trylock
+*/
+typedef void (*start_rwlock_wrwait_v1_t)
+ (struct PSI_rwlock_locker *locker, const char *src_file, uint src_line);
+
+/**
+ Record a rwlock instrumentation write wait end event.
+ @param locker a thread locker for the running thread
+ @param rc the wait operation return code
+*/
+typedef void (*end_rwlock_wrwait_v1_t)
+ (struct PSI_rwlock_locker *locker, int rc);
+
+/**
+ Record a condition instrumentation wait start event.
+ @param locker a thread locker for the running thread
+ @param must must block: 1 for wait, 0 for timedwait
+*/
+typedef void (*start_cond_wait_v1_t)
+ (struct PSI_cond_locker *locker, const char *src_file, uint src_line);
+
+/**
+ Record a condition instrumentation wait end event.
+ @param locker a thread locker for the running thread
+ @param rc the wait operation return code
+*/
+typedef void (*end_cond_wait_v1_t)
+ (struct PSI_cond_locker *locker, int rc);
+
+/**
+ Record a table instrumentation wait start event.
+ @param locker a table locker for the running thread
+ @param file the source file name
+ @param line the source line number
+*/
+typedef void (*start_table_wait_v1_t)
+ (struct PSI_table_locker *locker, const char *src_file, uint src_line);
+
+/**
+ Record a table instrumentation wait end event.
+ @param locker a table locker for the running thread
+*/
+typedef void (*end_table_wait_v1_t)(struct PSI_table_locker *locker);
+
+/**
+ Start a file instrumentation open operation.
+ @param locker the file locker
+ @param op the operation to perform
+ @param src_file the source file name
+ @param src_line the source line number
+ @return an instrumented file handle
+*/
+typedef struct PSI_file* (*start_file_open_wait_v1_t)
+ (struct PSI_file_locker *locker, const char *src_file, uint src_line);
+
+/**
+ End a file instrumentation open operation, for file streams.
+ @param locker the file locker.
+*/
+typedef void (*end_file_open_wait_v1_t)(struct PSI_file_locker *locker);
+
+/**
+ End a file instrumentation open operation, for non stream files.
+ @param locker the file locker.
+ @param file the file number assigned by open() or create() for this file.
+*/
+typedef void (*end_file_open_wait_and_bind_to_descriptor_v1_t)
+ (struct PSI_file_locker *locker, File file);
+
+/**
+ Record a file instrumentation start event.
+ @param locker a file locker for the running thread
+ @param op file operation to be performed
+ @param count the number of bytes requested, or 0 if not applicable
+ @param src_file the source file name
+ @param src_line the source line number
+*/
+typedef void (*start_file_wait_v1_t)
+ (struct PSI_file_locker *locker, size_t count,
+ const char *src_file, uint src_line);
+
+/**
+ Record a file instrumentation end event.
+ Note that for file close operations, the instrumented file handle
+ associated with the file (which was provided to obtain a locker)
+ is invalid after this call.
+ @param locker a file locker for the running thread
+ @param count the number of bytes actually used in the operation,
+ or 0 if not applicable, or -1 if the operation failed
+ @sa get_thread_file_name_locker
+ @sa get_thread_file_stream_locker
+ @sa get_thread_file_descriptor_locker
+*/
+typedef void (*end_file_wait_v1_t)
+ (struct PSI_file_locker *locker, size_t count);
+
+/**
+ Performance Schema Interface, version 1.
+ @since PSI_VERSION_1
+*/
+struct PSI_v1
+{
+ /** @sa register_mutex_v1_t. */
+ register_mutex_v1_t register_mutex;
+ /** @sa register_rwlock_v1_t. */
+ register_rwlock_v1_t register_rwlock;
+ /** @sa register_cond_v1_t. */
+ register_cond_v1_t register_cond;
+ /** @sa register_thread_v1_t. */
+ register_thread_v1_t register_thread;
+ /** @sa register_file_v1_t. */
+ register_file_v1_t register_file;
+ /** @sa init_mutex_v1_t. */
+ init_mutex_v1_t init_mutex;
+ /** @sa destroy_mutex_v1_t. */
+ destroy_mutex_v1_t destroy_mutex;
+ /** @sa init_rwlock_v1_t. */
+ init_rwlock_v1_t init_rwlock;
+ /** @sa destroy_rwlock_v1_t. */
+ destroy_rwlock_v1_t destroy_rwlock;
+ /** @sa init_cond_v1_t. */
+ init_cond_v1_t init_cond;
+ /** @sa destroy_cond_v1_t. */
+ destroy_cond_v1_t destroy_cond;
+ /** @sa get_table_share_v1_t. */
+ get_table_share_v1_t get_table_share;
+ /** @sa release_table_share_v1_t. */
+ release_table_share_v1_t release_table_share;
+ /** @sa open_table_v1_t. */
+ open_table_v1_t open_table;
+ /** @sa close_table_v1_t. */
+ close_table_v1_t close_table;
+ /** @sa create_file_v1_t. */
+ create_file_v1_t create_file;
+ /** @sa spawn_thread_v1_t. */
+ spawn_thread_v1_t spawn_thread;
+ /** @sa new_thread_v1_t. */
+ new_thread_v1_t new_thread;
+ /** @sa set_thread_id_v1_t. */
+ set_thread_id_v1_t set_thread_id;
+ /** @sa get_thread_v1_t. */
+ get_thread_v1_t get_thread;
+ /** @sa set_thread_v1_t. */
+ set_thread_v1_t set_thread;
+ /** @sa delete_current_thread_v1_t. */
+ delete_current_thread_v1_t delete_current_thread;
+ /** @sa delete_thread_v1_t. */
+ delete_thread_v1_t delete_thread;
+ /** @sa get_thread_mutex_locker_v1_t. */
+ get_thread_mutex_locker_v1_t get_thread_mutex_locker;
+ /** @sa get_thread_rwlock_locker_v1_t. */
+ get_thread_rwlock_locker_v1_t get_thread_rwlock_locker;
+ /** @sa get_thread_cond_locker_v1_t. */
+ get_thread_cond_locker_v1_t get_thread_cond_locker;
+ /** @sa get_thread_table_locker_v1_t. */
+ get_thread_table_locker_v1_t get_thread_table_locker;
+ /** @sa get_thread_file_name_locker_v1_t. */
+ get_thread_file_name_locker_v1_t get_thread_file_name_locker;
+ /** @sa get_thread_file_stream_locker_v1_t. */
+ get_thread_file_stream_locker_v1_t get_thread_file_stream_locker;
+ /** @sa get_thread_file_descriptor_locker_v1_t. */
+ get_thread_file_descriptor_locker_v1_t get_thread_file_descriptor_locker;
+ /** @sa unlock_mutex_v1_t. */
+ unlock_mutex_v1_t unlock_mutex;
+ /** @sa unlock_rwlock_v1_t. */
+ unlock_rwlock_v1_t unlock_rwlock;
+ /** @sa signal_cond_v1_t. */
+ signal_cond_v1_t signal_cond;
+ /** @sa broadcast_cond_v1_t. */
+ broadcast_cond_v1_t broadcast_cond;
+ /** @sa start_mutex_wait_v1_t. */
+ start_mutex_wait_v1_t start_mutex_wait;
+ /** @sa end_mutex_wait_v1_t. */
+ end_mutex_wait_v1_t end_mutex_wait;
+ /** @sa start_rwlock_rdwait_v1_t. */
+ start_rwlock_rdwait_v1_t start_rwlock_rdwait;
+ /** @sa end_rwlock_rdwait_v1_t. */
+ end_rwlock_rdwait_v1_t end_rwlock_rdwait;
+ /** @sa start_rwlock_wrwait_v1_t. */
+ start_rwlock_wrwait_v1_t start_rwlock_wrwait;
+ /** @sa end_rwlock_wrwait_v1_t. */
+ end_rwlock_wrwait_v1_t end_rwlock_wrwait;
+ /** @sa start_cond_wait_v1_t. */
+ start_cond_wait_v1_t start_cond_wait;
+ /** @sa end_cond_wait_v1_t. */
+ end_cond_wait_v1_t end_cond_wait;
+ /** @sa start_table_wait_v1_t. */
+ start_table_wait_v1_t start_table_wait;
+ /** @sa end_table_wait_v1_t. */
+ end_table_wait_v1_t end_table_wait;
+ /** @sa start_file_open_wait_v1_t. */
+ start_file_open_wait_v1_t start_file_open_wait;
+ /** @sa end_file_open_wait_v1_t. */
+ end_file_open_wait_v1_t end_file_open_wait;
+ /** @sa end_file_open_wait_and_bind_to_descriptor_v1_t. */
+ end_file_open_wait_and_bind_to_descriptor_v1_t
+ end_file_open_wait_and_bind_to_descriptor;
+ /** @sa start_file_wait_v1_t. */
+ start_file_wait_v1_t start_file_wait;
+ /** @sa end_file_wait_v1_t. */
+ end_file_wait_v1_t end_file_wait;
+};
+
+/** @} (end of group Group_PSI_v1) */
+
+#endif /* HAVE_PSI_1 */
+
+#ifdef USE_PSI_2
+#define HAVE_PSI_2
+#endif
+
+#ifdef HAVE_PSI_2
+
+/**
+ @defgroup Group_PSI_v2 Application Binary Interface, version 2
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ Performance Schema Interface, version 2.
+ This is a placeholder, this interface is not defined yet.
+ @since PSI_VERSION_2
+*/
+struct PSI_v2
+{
+ /** Placeholder */
+ int placeholder;
+ /* ... extended interface ... */
+};
+
+/** Placeholder */
+struct PSI_mutex_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_rwlock_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_cond_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_thread_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_file_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** @} (end of group Group_PSI_v2) */
+
+#endif /* HAVE_PSI_2 */
+
+/**
+ @typedef PSI
+ The instrumentation interface for the current version.
+ @sa PSI_CURRENT_VERSION
+*/
+
+/**
+ @typedef PSI_mutex_info
+ The mutex information structure for the current version.
+*/
+
+/**
+ @typedef PSI_rwlock_info
+ The rwlock information structure for the current version.
+*/
+
+/**
+ @typedef PSI_cond_info
+ The cond information structure for the current version.
+*/
+
+/**
+ @typedef PSI_thread_info
+ The thread information structure for the current version.
+*/
+
+/**
+ @typedef PSI_file_info
+ The file information structure for the current version.
+*/
+
+/* Export the required version */
+#ifdef USE_PSI_1
+typedef struct PSI_v1 PSI;
+typedef struct PSI_mutex_info_v1 PSI_mutex_info;
+typedef struct PSI_rwlock_info_v1 PSI_rwlock_info;
+typedef struct PSI_cond_info_v1 PSI_cond_info;
+typedef struct PSI_thread_info_v1 PSI_thread_info;
+typedef struct PSI_file_info_v1 PSI_file_info;
+#endif
+
+#ifdef USE_PSI_2
+typedef struct PSI_v2 PSI;
+typedef struct PSI_mutex_info_v2 PSI_mutex_info;
+typedef struct PSI_rwlock_info_v2 PSI_rwlock_info;
+typedef struct PSI_cond_info_v2 PSI_cond_info;
+typedef struct PSI_thread_info_v2 PSI_thread_info;
+typedef struct PSI_file_info_v2 PSI_file_info;
+#endif
+
+#else /* HAVE_PSI_INTERFACE */
+
+/**
+ Dummy structure, used to declare PSI_server when no instrumentation
+ is available.
+ The content does not matter, since PSI_server will be NULL.
+*/
+struct PSI_none
+{
+ int opaque;
+};
+typedef struct PSI_none PSI;
+
+#endif /* HAVE_PSI_INTERFACE */
+
+extern MYSQL_PLUGIN_IMPORT PSI *PSI_server;
+
+/** @} */
+
+C_MODE_END
+#endif /* MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H */
+
diff --git a/include/mysql/psi/psi_abi_v1.h b/include/mysql/psi/psi_abi_v1.h
new file mode 100644
index 00000000000..c9dfd031668
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v1.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 2008-2009 Sun Microsystems, Inc
+
+ 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 */
+
+/**
+ @file mysql/psi/psi_abi_v1.h
+ ABI check for mysql/psi/psi.h, when using PSI_VERSION_1.
+ This file is only used to automate detection of changes between versions.
+ Do not include this file, include mysql/psi/psi.h instead.
+*/
+#define USE_PSI_1
+#define HAVE_PSI_INTERFACE
+#define _global_h
+#include "mysql/psi/psi.h"
+
diff --git a/include/mysql/psi/psi_abi_v1.h.pp b/include/mysql/psi/psi_abi_v1.h.pp
new file mode 100644
index 00000000000..6ecd0f3098d
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v1.h.pp
@@ -0,0 +1,244 @@
+#include "mysql/psi/psi.h"
+C_MODE_START
+struct PSI_mutex;
+struct PSI_rwlock;
+struct PSI_cond;
+struct PSI_table_share;
+struct PSI_table;
+struct PSI_thread;
+struct PSI_file;
+struct PSI_bootstrap
+{
+ void* (*get_interface)(int version);
+};
+struct PSI_mutex_locker;
+struct PSI_rwlock_locker;
+struct PSI_cond_locker;
+struct PSI_file_locker;
+enum PSI_mutex_operation
+{
+ PSI_MUTEX_LOCK= 0,
+ PSI_MUTEX_TRYLOCK= 1
+};
+enum PSI_rwlock_operation
+{
+ PSI_RWLOCK_READLOCK= 0,
+ PSI_RWLOCK_WRITELOCK= 1,
+ PSI_RWLOCK_TRYREADLOCK= 2,
+ PSI_RWLOCK_TRYWRITELOCK= 3
+};
+enum PSI_cond_operation
+{
+ PSI_COND_WAIT= 0,
+ PSI_COND_TIMEDWAIT= 1
+};
+enum PSI_file_operation
+{
+ PSI_FILE_CREATE= 0,
+ PSI_FILE_CREATE_TMP= 1,
+ PSI_FILE_OPEN= 2,
+ PSI_FILE_STREAM_OPEN= 3,
+ PSI_FILE_CLOSE= 4,
+ PSI_FILE_STREAM_CLOSE= 5,
+ PSI_FILE_READ= 6,
+ PSI_FILE_WRITE= 7,
+ PSI_FILE_SEEK= 8,
+ PSI_FILE_TELL= 9,
+ PSI_FILE_FLUSH= 10,
+ PSI_FILE_STAT= 11,
+ PSI_FILE_FSTAT= 12,
+ PSI_FILE_CHSIZE= 13,
+ PSI_FILE_DELETE= 14,
+ PSI_FILE_RENAME= 15,
+ PSI_FILE_SYNC= 16
+};
+struct PSI_table_locker;
+typedef unsigned int PSI_mutex_key;
+typedef unsigned int PSI_rwlock_key;
+typedef unsigned int PSI_cond_key;
+typedef unsigned int PSI_thread_key;
+typedef unsigned int PSI_file_key;
+struct PSI_mutex_info_v1
+{
+ PSI_mutex_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+struct PSI_rwlock_info_v1
+{
+ PSI_rwlock_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+struct PSI_cond_info_v1
+{
+ PSI_cond_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+struct PSI_thread_info_v1
+{
+ PSI_thread_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+struct PSI_file_info_v1
+{
+ PSI_file_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+typedef void (*register_mutex_v1_t)
+ (const char *category, struct PSI_mutex_info_v1 *info, int count);
+typedef void (*register_rwlock_v1_t)
+ (const char *category, struct PSI_rwlock_info_v1 *info, int count);
+typedef void (*register_cond_v1_t)
+ (const char *category, struct PSI_cond_info_v1 *info, int count);
+typedef void (*register_thread_v1_t)
+ (const char *category, struct PSI_thread_info_v1 *info, int count);
+typedef void (*register_file_v1_t)
+ (const char *category, struct PSI_file_info_v1 *info, int count);
+typedef struct PSI_mutex* (*init_mutex_v1_t)
+ (PSI_mutex_key key, const void *identity);
+typedef void (*destroy_mutex_v1_t)(struct PSI_mutex *mutex);
+typedef struct PSI_rwlock* (*init_rwlock_v1_t)
+ (PSI_rwlock_key key, const void *identity);
+typedef void (*destroy_rwlock_v1_t)(struct PSI_rwlock *rwlock);
+typedef struct PSI_cond* (*init_cond_v1_t)
+ (PSI_cond_key key, const void *identity);
+typedef void (*destroy_cond_v1_t)(struct PSI_cond *cond);
+typedef struct PSI_table_share* (*get_table_share_v1_t)
+ (const char *schema_name, int schema_name_length, const char *table_name,
+ int table_name_length, const void *identity);
+typedef void (*release_table_share_v1_t)(struct PSI_table_share *share);
+typedef struct PSI_table* (*open_table_v1_t)
+ (struct PSI_table_share *share, const void *identity);
+typedef void (*close_table_v1_t)(struct PSI_table *table);
+typedef void (*create_file_v1_t)(PSI_file_key key, const char *name,
+ File file);
+typedef int (*spawn_thread_v1_t)(PSI_thread_key key,
+ pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void*), void *arg);
+typedef struct PSI_thread* (*new_thread_v1_t)
+ (PSI_thread_key key, const void *identity, ulong thread_id);
+typedef void (*set_thread_id_v1_t)(struct PSI_thread *thread,
+ unsigned long id);
+typedef struct PSI_thread* (*get_thread_v1_t)(void);
+typedef void (*set_thread_v1_t)(struct PSI_thread *thread);
+typedef void (*delete_current_thread_v1_t)(void);
+typedef void (*delete_thread_v1_t)(struct PSI_thread *thread);
+typedef struct PSI_mutex_locker* (*get_thread_mutex_locker_v1_t)
+ (struct PSI_mutex *mutex, enum PSI_mutex_operation op);
+typedef struct PSI_rwlock_locker* (*get_thread_rwlock_locker_v1_t)
+ (struct PSI_rwlock *rwlock, enum PSI_rwlock_operation op);
+typedef struct PSI_cond_locker* (*get_thread_cond_locker_v1_t)
+ (struct PSI_cond *cond, struct PSI_mutex *mutex,
+ enum PSI_cond_operation op);
+typedef struct PSI_table_locker* (*get_thread_table_locker_v1_t)
+ (struct PSI_table *table);
+typedef struct PSI_file_locker* (*get_thread_file_name_locker_v1_t)
+ (PSI_file_key key, enum PSI_file_operation op, const char *name,
+ const void *identity);
+typedef struct PSI_file_locker* (*get_thread_file_stream_locker_v1_t)
+ (struct PSI_file *file, enum PSI_file_operation op);
+typedef struct PSI_file_locker* (*get_thread_file_descriptor_locker_v1_t)
+ (File file, enum PSI_file_operation op);
+typedef void (*unlock_mutex_v1_t)
+ (struct PSI_thread *thread, struct PSI_mutex *mutex);
+typedef void (*unlock_rwlock_v1_t)
+ (struct PSI_thread *thread, struct PSI_rwlock *rwlock);
+typedef void (*signal_cond_v1_t)
+ (struct PSI_thread *thread, struct PSI_cond *cond);
+typedef void (*broadcast_cond_v1_t)
+ (struct PSI_thread *thread, struct PSI_cond *cond);
+typedef void (*start_mutex_wait_v1_t)
+ (struct PSI_mutex_locker *locker, const char *src_file, uint src_line);
+typedef void (*end_mutex_wait_v1_t)
+ (struct PSI_mutex_locker *locker, int rc);
+typedef void (*start_rwlock_rdwait_v1_t)
+ (struct PSI_rwlock_locker *locker, const char *src_file, uint src_line);
+typedef void (*end_rwlock_rdwait_v1_t)
+ (struct PSI_rwlock_locker *locker, int rc);
+typedef void (*start_rwlock_wrwait_v1_t)
+ (struct PSI_rwlock_locker *locker, const char *src_file, uint src_line);
+typedef void (*end_rwlock_wrwait_v1_t)
+ (struct PSI_rwlock_locker *locker, int rc);
+typedef void (*start_cond_wait_v1_t)
+ (struct PSI_cond_locker *locker, const char *src_file, uint src_line);
+typedef void (*end_cond_wait_v1_t)
+ (struct PSI_cond_locker *locker, int rc);
+typedef void (*start_table_wait_v1_t)
+ (struct PSI_table_locker *locker, const char *src_file, uint src_line);
+typedef void (*end_table_wait_v1_t)(struct PSI_table_locker *locker);
+typedef struct PSI_file* (*start_file_open_wait_v1_t)
+ (struct PSI_file_locker *locker, const char *src_file, uint src_line);
+typedef void (*end_file_open_wait_v1_t)(struct PSI_file_locker *locker);
+typedef void (*end_file_open_wait_and_bind_to_descriptor_v1_t)
+ (struct PSI_file_locker *locker, File file);
+typedef void (*start_file_wait_v1_t)
+ (struct PSI_file_locker *locker, size_t count,
+ const char *src_file, uint src_line);
+typedef void (*end_file_wait_v1_t)
+ (struct PSI_file_locker *locker, size_t count);
+struct PSI_v1
+{
+ register_mutex_v1_t register_mutex;
+ register_rwlock_v1_t register_rwlock;
+ register_cond_v1_t register_cond;
+ register_thread_v1_t register_thread;
+ register_file_v1_t register_file;
+ init_mutex_v1_t init_mutex;
+ destroy_mutex_v1_t destroy_mutex;
+ init_rwlock_v1_t init_rwlock;
+ destroy_rwlock_v1_t destroy_rwlock;
+ init_cond_v1_t init_cond;
+ destroy_cond_v1_t destroy_cond;
+ get_table_share_v1_t get_table_share;
+ release_table_share_v1_t release_table_share;
+ open_table_v1_t open_table;
+ close_table_v1_t close_table;
+ create_file_v1_t create_file;
+ spawn_thread_v1_t spawn_thread;
+ new_thread_v1_t new_thread;
+ set_thread_id_v1_t set_thread_id;
+ get_thread_v1_t get_thread;
+ set_thread_v1_t set_thread;
+ delete_current_thread_v1_t delete_current_thread;
+ delete_thread_v1_t delete_thread;
+ get_thread_mutex_locker_v1_t get_thread_mutex_locker;
+ get_thread_rwlock_locker_v1_t get_thread_rwlock_locker;
+ get_thread_cond_locker_v1_t get_thread_cond_locker;
+ get_thread_table_locker_v1_t get_thread_table_locker;
+ get_thread_file_name_locker_v1_t get_thread_file_name_locker;
+ get_thread_file_stream_locker_v1_t get_thread_file_stream_locker;
+ get_thread_file_descriptor_locker_v1_t get_thread_file_descriptor_locker;
+ unlock_mutex_v1_t unlock_mutex;
+ unlock_rwlock_v1_t unlock_rwlock;
+ signal_cond_v1_t signal_cond;
+ broadcast_cond_v1_t broadcast_cond;
+ start_mutex_wait_v1_t start_mutex_wait;
+ end_mutex_wait_v1_t end_mutex_wait;
+ start_rwlock_rdwait_v1_t start_rwlock_rdwait;
+ end_rwlock_rdwait_v1_t end_rwlock_rdwait;
+ start_rwlock_wrwait_v1_t start_rwlock_wrwait;
+ end_rwlock_wrwait_v1_t end_rwlock_wrwait;
+ start_cond_wait_v1_t start_cond_wait;
+ end_cond_wait_v1_t end_cond_wait;
+ start_table_wait_v1_t start_table_wait;
+ end_table_wait_v1_t end_table_wait;
+ start_file_open_wait_v1_t start_file_open_wait;
+ end_file_open_wait_v1_t end_file_open_wait;
+ end_file_open_wait_and_bind_to_descriptor_v1_t
+ end_file_open_wait_and_bind_to_descriptor;
+ start_file_wait_v1_t start_file_wait;
+ end_file_wait_v1_t end_file_wait;
+};
+typedef struct PSI_v1 PSI;
+typedef struct PSI_mutex_info_v1 PSI_mutex_info;
+typedef struct PSI_rwlock_info_v1 PSI_rwlock_info;
+typedef struct PSI_cond_info_v1 PSI_cond_info;
+typedef struct PSI_thread_info_v1 PSI_thread_info;
+typedef struct PSI_file_info_v1 PSI_file_info;
+extern MYSQL_PLUGIN_IMPORT PSI *PSI_server;
+C_MODE_END
diff --git a/include/mysql/psi/psi_abi_v2.h b/include/mysql/psi/psi_abi_v2.h
new file mode 100644
index 00000000000..e720c4c2b7c
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v2.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 2008-2009 Sun Microsystems, Inc
+
+ 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 */
+
+/**
+ @file mysql/psi/psi_abi_v1.h
+ ABI check for mysql/psi/psi.h, when using PSI_VERSION_2.
+ This file is only used to automate detection of changes between versions.
+ Do not include this file, include mysql/psi/psi.h instead.
+*/
+#define USE_PSI_2
+#define HAVE_PSI_INTERFACE
+#define _global_h
+#include "mysql/psi/psi.h"
+
diff --git a/include/mysql/psi/psi_abi_v2.h.pp b/include/mysql/psi/psi_abi_v2.h.pp
new file mode 100644
index 00000000000..b32415a59b4
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v2.h.pp
@@ -0,0 +1,92 @@
+#include "mysql/psi/psi.h"
+C_MODE_START
+struct PSI_mutex;
+struct PSI_rwlock;
+struct PSI_cond;
+struct PSI_table_share;
+struct PSI_table;
+struct PSI_thread;
+struct PSI_file;
+struct PSI_bootstrap
+{
+ void* (*get_interface)(int version);
+};
+struct PSI_mutex_locker;
+struct PSI_rwlock_locker;
+struct PSI_cond_locker;
+struct PSI_file_locker;
+enum PSI_mutex_operation
+{
+ PSI_MUTEX_LOCK= 0,
+ PSI_MUTEX_TRYLOCK= 1
+};
+enum PSI_rwlock_operation
+{
+ PSI_RWLOCK_READLOCK= 0,
+ PSI_RWLOCK_WRITELOCK= 1,
+ PSI_RWLOCK_TRYREADLOCK= 2,
+ PSI_RWLOCK_TRYWRITELOCK= 3
+};
+enum PSI_cond_operation
+{
+ PSI_COND_WAIT= 0,
+ PSI_COND_TIMEDWAIT= 1
+};
+enum PSI_file_operation
+{
+ PSI_FILE_CREATE= 0,
+ PSI_FILE_CREATE_TMP= 1,
+ PSI_FILE_OPEN= 2,
+ PSI_FILE_STREAM_OPEN= 3,
+ PSI_FILE_CLOSE= 4,
+ PSI_FILE_STREAM_CLOSE= 5,
+ PSI_FILE_READ= 6,
+ PSI_FILE_WRITE= 7,
+ PSI_FILE_SEEK= 8,
+ PSI_FILE_TELL= 9,
+ PSI_FILE_FLUSH= 10,
+ PSI_FILE_STAT= 11,
+ PSI_FILE_FSTAT= 12,
+ PSI_FILE_CHSIZE= 13,
+ PSI_FILE_DELETE= 14,
+ PSI_FILE_RENAME= 15,
+ PSI_FILE_SYNC= 16
+};
+struct PSI_table_locker;
+typedef unsigned int PSI_mutex_key;
+typedef unsigned int PSI_rwlock_key;
+typedef unsigned int PSI_cond_key;
+typedef unsigned int PSI_thread_key;
+typedef unsigned int PSI_file_key;
+struct PSI_v2
+{
+ int placeholder;
+};
+struct PSI_mutex_info_v2
+{
+ int placeholder;
+};
+struct PSI_rwlock_info_v2
+{
+ int placeholder;
+};
+struct PSI_cond_info_v2
+{
+ int placeholder;
+};
+struct PSI_thread_info_v2
+{
+ int placeholder;
+};
+struct PSI_file_info_v2
+{
+ int placeholder;
+};
+typedef struct PSI_v2 PSI;
+typedef struct PSI_mutex_info_v2 PSI_mutex_info;
+typedef struct PSI_rwlock_info_v2 PSI_rwlock_info;
+typedef struct PSI_cond_info_v2 PSI_cond_info;
+typedef struct PSI_thread_info_v2 PSI_thread_info;
+typedef struct PSI_file_info_v2 PSI_file_info;
+extern MYSQL_PLUGIN_IMPORT PSI *PSI_server;
+C_MODE_END
diff --git a/include/mysql/service_my_snprintf.h b/include/mysql/service_my_snprintf.h
new file mode 100644
index 00000000000..9e5fe7f9c9f
--- /dev/null
+++ b/include/mysql/service_my_snprintf.h
@@ -0,0 +1,98 @@
+#ifndef MYSQL_SERVICE_MY_SNPRINTF_INCLUDED
+/* Copyright (C) 2009 Sun Microsystems, Inc.
+
+ 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 */
+
+/**
+ @file
+ my_snprintf service
+
+ Portable and limited vsnprintf() implementation.
+
+ This is a portable, limited vsnprintf() implementation, with some
+ extra features. "Portable" means that it'll produce identical result
+ on all platforms (for example, on Windows and Linux system printf %e
+ formats the exponent differently, on different systems %p either
+ prints leading 0x or not, %s may accept null pointer or crash on
+ it). "Limited" means that it does not support all the C89 features.
+ But it supports few extensions, not in any standard.
+
+ my_vsnprintf(to, n, fmt, ap)
+
+ @param[out] to A buffer to store the result in
+ @param[in] n Store up to n-1 characters, followed by an end 0
+ @param[in] fmt printf-like format string
+ @param[in] ap Arguments
+
+ @return a number of bytes written to a buffer *excluding* terminating '\0'
+
+ @post
+ The syntax of a format string is generally the same:
+ % <flag> <width> <precision> <length modifier> <format>
+ where everithing but the format is optional.
+
+ Three one-character flags are recognized:
+ '0' has the standard zero-padding semantics;
+ '-' is parsed, but silently ignored;
+ '`' (backtick) is only supported for strings (%s) and means that the
+ string will be quoted according to MySQL identifier quoting rules.
+
+ Both <width> and <precision> can be specified as numbers or '*'.
+
+ <length modifier> can be 'l', 'll', or 'z'.
+
+ Supported formats are 's' (null pointer is accepted, printed as
+ "(null)"), 'b' (extension, see below), 'c', 'd', 'u', 'x', 'o',
+ 'X', 'p' (works as 0x%x).
+
+ Standard syntax for positional arguments $n is supported.
+
+ Extensions:
+
+ Flag '`' (backtick): see above.
+
+ Format 'b': binary buffer, prints exactly <precision> bytes from the
+ argument, without stopping at '\0'.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdarg.h>
+#include <stdlib.h>
+extern struct my_snprintf_service_st {
+ size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
+ size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
+} *my_snprintf_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define my_vsnprintf my_snprintf_service->my_vsnprintf_type
+#define my_snprintf my_snprintf_service->my_snprintf_type
+
+#else
+
+size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
+size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_MY_SNPRINTF_INCLUDED
+#endif
+
diff --git a/include/mysql/service_thd_alloc.h b/include/mysql/service_thd_alloc.h
new file mode 100644
index 00000000000..86158ba1359
--- /dev/null
+++ b/include/mysql/service_thd_alloc.h
@@ -0,0 +1,128 @@
+#ifndef MYSQL_SERVICE_THD_ALLOC_INCLUDED
+/* Copyright (C) 2009 Sun Microsystems, Inc.
+
+ 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 */
+
+/**
+ @file
+ This service provdes functions to allocate memory in a connection local
+ memory pool. The memory allocated there will be automatically freed at the
+ end of the statement, don't use it for allocations that should live longer
+ than that. For short living allocations this is more efficient than
+ using my_malloc and friends, and automatic "garbage collection" allows not
+ to think about memory leaks.
+
+ The pool is best for small to medium objects, don't use it for large
+ allocations - they are better served with my_malloc.
+*/
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct st_mysql_lex_string
+{
+ char *str;
+ size_t length;
+};
+typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
+
+extern struct thd_alloc_service_st {
+ void *(*thd_alloc_func)(MYSQL_THD, unsigned int);
+ void *(*thd_calloc_func)(MYSQL_THD, unsigned int);
+ char *(*thd_strdup_func)(MYSQL_THD, const char *);
+ char *(*thd_strmake_func)(MYSQL_THD, const char *, unsigned int);
+ void *(*thd_memdup_func)(MYSQL_THD, const void*, unsigned int);
+ MYSQL_LEX_STRING *(*thd_make_lex_string_func)(MYSQL_THD, MYSQL_LEX_STRING *,
+ const char *, unsigned int, int);
+} *thd_alloc_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define thd_alloc(thd,size) (thd_alloc_service->thd_alloc_func((thd), (size)))
+
+#define thd_calloc(thd,size) (thd_alloc_service->thd_calloc_func((thd), (size)))
+
+#define thd_strdup(thd,str) (thd_alloc_service->thd_strdup_func((thd), (str)))
+
+#define thd_strmake(thd,str,size) \
+ (thd_alloc_service->thd_strmake_func((thd), (str), (size)))
+
+#define thd_memdup(thd,str,size) \
+ (thd_alloc_service->thd_memdup_func((thd), (str), (size)))
+
+#define thd_make_lex_string(thd, lex_str, str, size, allocate_lex_string) \
+ (thd_alloc_service->thd_make_lex_string_func((thd), (lex_str), (str), \
+ (size), (allocate_lex_string)))
+
+#else
+
+/**
+ Allocate memory in the connection's local memory pool
+
+ @details
+ When properly used in place of @c my_malloc(), this can significantly
+ improve concurrency. Don't use this or related functions to allocate
+ large chunks of memory. Use for temporary storage only. The memory
+ will be freed automatically at the end of the statement; no explicit
+ code is required to prevent memory leaks.
+
+ @see alloc_root()
+*/
+void *thd_alloc(MYSQL_THD thd, unsigned int size);
+/**
+ @see thd_alloc()
+*/
+void *thd_calloc(MYSQL_THD thd, unsigned int size);
+/**
+ @see thd_alloc()
+*/
+char *thd_strdup(MYSQL_THD thd, const char *str);
+/**
+ @see thd_alloc()
+*/
+char *thd_strmake(MYSQL_THD thd, const char *str, unsigned int size);
+/**
+ @see thd_alloc()
+*/
+void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int size);
+
+/**
+ Create a LEX_STRING in this connection's local memory pool
+
+ @param thd user thread connection handle
+ @param lex_str pointer to LEX_STRING object to be initialized
+ @param str initializer to be copied into lex_str
+ @param size length of str, in bytes
+ @param allocate_lex_string flag: if TRUE, allocate new LEX_STRING object,
+ instead of using lex_str value
+ @return NULL on failure, or pointer to the LEX_STRING object
+
+ @see thd_alloc()
+*/
+MYSQL_LEX_STRING *thd_make_lex_string(MYSQL_THD thd, MYSQL_LEX_STRING *lex_str,
+ const char *str, unsigned int size,
+ int allocate_lex_string);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_THD_ALLOC_INCLUDED
+#endif
+
diff --git a/include/mysql/services.h b/include/mysql/services.h
new file mode 100644
index 00000000000..19003e66b96
--- /dev/null
+++ b/include/mysql/services.h
@@ -0,0 +1,30 @@
+#ifndef MYSQL_SERVICES_INCLUDED
+/* Copyright (C) 2009 Sun Microsystems, Inc.
+
+ 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 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <mysql/service_my_snprintf.h>
+#include <mysql/service_thd_alloc.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICES_INCLUDED
+#endif
+
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 7d3dd3d4f34..e2baa06b160 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -27,10 +27,20 @@
#define NAME_LEN (NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN)
#define USERNAME_LENGTH (USERNAME_CHAR_LENGTH*SYSTEM_CHARSET_MBMAXLEN)
+#define MYSQL_AUTODETECT_CHARSET_NAME "auto"
+
#define SERVER_VERSION_LENGTH 60
#define SQLSTATE_LENGTH 5
/*
+ Maximum length of comments
+*/
+#define TABLE_COMMENT_INLINE_MAXLEN 180 /* pre 6.0: 60 characters */
+#define TABLE_COMMENT_MAXLEN 2048
+#define COLUMN_COMMENT_MAXLEN 1024
+#define INDEX_COMMENT_MAXLEN 1024
+
+/*
USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain
username and hostname parts of the user identifier with trailing zero in
MySQL standard format:
@@ -115,6 +125,12 @@ enum enum_server_command
thread */
#define REFRESH_MASTER 128 /* Remove all bin logs in the index
and truncate the index */
+#define REFRESH_ERROR_LOG 256 /* Rotate only the erorr log */
+#define REFRESH_ENGINE_LOG 512 /* Flush all storage engine logs */
+#define REFRESH_BINARY_LOG 1024 /* Flush the binary log */
+#define REFRESH_RELAY_LOG 2048 /* Flush the relay log */
+#define REFRESH_GENERAL_LOG 4096 /* Flush the general log */
+#define REFRESH_SLOW_LOG 8192 /* Flush the slow query log */
/* The following can't be set with mysql_refresh() */
#define REFRESH_READ_LOCK 16384 /* Lock tables for read */
@@ -144,6 +160,7 @@ enum enum_server_command
#define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */
#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */
#define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */
+#define CLIENT_PS_MULTI_RESULTS (1UL << 18) /* Multi-results in PS-protocol */
#define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30)
#define CLIENT_REMEMBER_OPTIONS (1UL << 31)
@@ -167,6 +184,7 @@ enum enum_server_command
CLIENT_SECURE_CONNECTION | \
CLIENT_MULTI_STATEMENTS | \
CLIENT_MULTI_RESULTS | \
+ CLIENT_PS_MULTI_RESULTS | \
CLIENT_SSL_VERIFY_SERVER_CERT | \
CLIENT_REMEMBER_OPTIONS)
@@ -203,6 +221,12 @@ enum enum_server_command
number of result set columns.
*/
#define SERVER_STATUS_METADATA_CHANGED 1024
+#define SERVER_QUERY_WAS_SLOW 2048
+
+/**
+ To mark ResultSet containing output parameter values.
+*/
+#define SERVER_PS_OUT_PARAMS 4096
/**
Server status flags that must be cleared when starting
@@ -254,24 +278,23 @@ typedef struct st_net {
unsigned int *return_status;
unsigned char reading_or_writing;
char save_char;
- my_bool unused0; /* Please remove with the next incompatible ABI change. */
- my_bool unused; /* Please remove with the next incompatible ABI change */
- my_bool compress;
my_bool unused1; /* Please remove with the next incompatible ABI change. */
+ my_bool unused2; /* Please remove with the next incompatible ABI change */
+ my_bool compress;
+ my_bool unused3; /* Please remove with the next incompatible ABI change. */
/*
Pointer to query object in query cache, do not equal NULL (0) for
queries in cache that have not stored its results yet
*/
#endif
/*
- 'query_cache_query' should be accessed only via query cache
- functions and methods to maintain proper locking.
+ Unused, please remove with the next incompatible ABI change.
*/
- unsigned char *query_cache_query;
+ unsigned char *unused;
unsigned int last_errno;
unsigned char error;
- my_bool unused2; /* Please remove with the next incompatible ABI change. */
- my_bool return_errno;
+ my_bool unused4; /* Please remove with the next incompatible ABI change. */
+ my_bool unused5; /* Please remove with the next incompatible ABI change. */
/** Client library error message buffer. Actually belongs to struct MYSQL. */
char last_error[MYSQL_ERRMSG_SIZE];
/** Client library sqlstate buffer. Set along with the error message. */
@@ -419,10 +442,6 @@ void my_net_set_write_timeout(NET *net, uint timeout);
void my_net_set_read_timeout(NET *net, uint timeout);
#endif
-/*
- The following function is not meant for normal usage
- Currently it's used internally by manager.c
-*/
struct sockaddr;
int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
unsigned int timeout);
@@ -529,4 +548,5 @@ uchar *net_store_length(uchar *pkg, ulonglong length);
#define MYSQL_STMT_HEADER 4
#define MYSQL_LONG_DATA_HEADER 6
+#define NOT_FIXED_DEC 31
#endif
diff --git a/include/mysql_embed.h b/include/mysql_embed.h
index 4a7fd3ef63c..b26b723381d 100644
--- a/include/mysql_embed.h
+++ b/include/mysql_embed.h
@@ -1,3 +1,6 @@
+#ifndef MYSQL_EMBED_INCLUDED
+#define MYSQL_EMBED_INCLUDED
+
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -21,10 +24,11 @@
/* TODO HF add #undef HAVE_VIO if we don't want client in embedded library */
#undef HAVE_PSTACK /* No stacktrace */
-#undef HAVE_OPENSSL
+#undef HAVE_DLOPEN /* No udf functions */
#undef HAVE_SMEM /* No shared memory */
#undef HAVE_NDBCLUSTER_DB /* No NDB cluster */
#define DONT_USE_RAID
#endif /* EMBEDDED_LIBRARY */
+#endif /* MYSQL_EMBED_INCLUDED */
diff --git a/include/mysys_err.h b/include/mysys_err.h
index 09e77248c17..6c18055b31b 100644
--- a/include/mysys_err.h
+++ b/include/mysys_err.h
@@ -16,6 +16,9 @@
#ifndef _mysys_err_h
#define _mysys_err_h
#ifdef __cplusplus
+
+#include "my_global.h" /* NEAR */
+
extern "C" {
#endif
diff --git a/include/password.h b/include/password.h
new file mode 100644
index 00000000000..e75b09297a3
--- /dev/null
+++ b/include/password.h
@@ -0,0 +1,32 @@
+/* Copyright 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+
+ 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 */
+
+#ifndef PASSWORD_INCLUDED
+#define PASSWORD_INCLUDED
+
+#include "my_global.h"
+
+C_MODE_START
+
+void my_make_scrambled_password_323(char *to, const char *password,
+ size_t pass_len);
+void my_make_scrambled_password(char *to, const char *password,
+ size_t pass_len);
+
+void hash_password(ulong *result, const char *password, uint password_len);
+
+C_MODE_END
+
+#endif /* PASSWORD_INCLUDED */
diff --git a/include/probes_mysql.d.base b/include/probes_mysql.d.base
new file mode 100644
index 00000000000..958e3042dde
--- /dev/null
+++ b/include/probes_mysql.d.base
@@ -0,0 +1,176 @@
+/* Copyright (C) 2008 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 */
+
+/*
+ The actual probe names in DTrace scripts will replace '__' by '-'. Thus
+ insert__row__start will be insert-row-start.
+
+ Recommendations for adding new probes:
+
+ - each probe should have the minimal set of arguments required to
+ unambiguously identify the context in which the probe fires. Redundant
+ arguments (i.e. the ones that can be obtained in user scripts from previous
+ probes' arguments or otherwise) may be added for convenience.
+
+ - try to avoid computationally expensive probe arguments. If impossible,
+ use *_ENABLED() macros to check if the probe is activated before
+ performing expensive calculations for a probe argument.
+
+ - all *-done probes should have a status argument wherever applicable to make
+ it possible for user scripts to figure out whether the completed operation
+ was successful or not.
+
+ - for all status arguments, a non-zero value should be returned on error or
+ failure, 0 should be returned on success.
+*/
+
+provider mysql {
+
+ /* The following ones fire when creating or closing a client connection */
+ probe connection__start(unsigned long conn_id, char *user, char *host);
+ probe connection__done(int status, unsigned long conn_id);
+
+ /*
+ Fire at the start/end of any client command processing (including SQL
+ queries).
+ */
+ probe command__start(unsigned long conn_id, int command,
+ char *user, char *host);
+ probe command__done(int status);
+
+ /*
+ The following probes fire at the start/end of any SQL query processing,
+ respectively.
+
+ query_start() has a lot of parameters that can be used to pick up
+ parameters for a lot of other probes here. For simplicity reasons we also
+ add the query string to most other DTrace probes as well. Hostname is
+ either the hostname or the IP address of the MySQL Client.
+ */
+ probe query__start(char *query,
+ unsigned long conn_id,
+ char *db_name,
+ char *user,
+ char *host);
+ probe query__done(int status);
+
+ /* Fire at the start/end of SQL query parsing */
+ probe query__parse__start(char *query);
+ probe query__parse__done(int status);
+
+ /* Track whether the query hits the query cache or not */
+ probe query__cache__hit(char *query, unsigned long rows);
+ probe query__cache__miss(char *query);
+
+ /*
+ This probe fires when the actual query execution starts, i.e. after
+ parsing and checking the query cache, but before privilege checks,
+ optimizing, etc.
+
+ Query means also all independent queries of a stored procedure and prepared
+ statements. Also the stored procedure itself is a query.
+
+ exec_type is:
+ 0: Executed query from sql_parse, top-level query (sql_parse.cc)
+ 1: Executed prepared statement (sql_prepare.cc)
+ 2: Executed cursor statement (sql_cursor.cc)
+ 3: Executed query in stored procedure (sp_head.cc)
+ */
+ probe query__exec__start(char *query,
+ unsigned long connid,
+ char *db_name,
+ char *user,
+ char *host,
+ int exec_type);
+ probe query__exec__done(int status);
+
+ /* These probes fire when performing row operations towards any handler */
+ probe insert__row__start(char *db, char *table);
+ probe insert__row__done(int status);
+ probe update__row__start(char *db, char *table);
+ probe update__row__done(int status);
+ probe delete__row__start(char *db, char *table);
+ probe delete__row__done(int status);
+ probe read__row__start(char *db, char *table, int scan_flag);
+ probe read__row__done(int status);
+ probe index__read__row__start(char *db, char *table);
+ probe index__read__row__done(int status);
+
+ /*
+ These probes fire when calling external_lock for any handler
+ depending on the lock type being acquired or released.
+ */
+ probe handler__rdlock__start(char *db, char *table);
+ probe handler__wrlock__start(char *db, char *table);
+ probe handler__unlock__start(char *db, char *table);
+ probe handler__rdlock__done(int status);
+ probe handler__wrlock__done(int status);
+ probe handler__unlock__done(int status);
+
+ /*
+ These probes fire when a filesort activity happens in a query.
+ */
+ probe filesort__start(char *db, char *table);
+ probe filesort__done(int status, unsigned long rows);
+ /*
+ The query types SELECT, INSERT, INSERT AS SELECT, UPDATE, UPDATE with
+ multiple tables, DELETE, DELETE with multiple tables are all probed.
+ The start probe always contains the query text.
+ */
+ probe select__start(char *query);
+ probe select__done(int status, unsigned long rows);
+ probe insert__start(char *query);
+ probe insert__done(int status, unsigned long rows);
+ probe insert__select__start(char *query);
+ probe insert__select__done(int status, unsigned long rows);
+ probe update__start(char *query);
+ probe update__done(int status,
+ unsigned long rowsmatches, unsigned long rowschanged);
+ probe multi__update__start(char *query);
+ probe multi__update__done(int status,
+ unsigned long rowsmatches,
+ unsigned long rowschanged);
+ probe delete__start(char *query);
+ probe delete__done(int status, unsigned long rows);
+ probe multi__delete__start(char *query);
+ probe multi__delete__done(int status, unsigned long rows);
+
+ /*
+ These probes can be used to measure the time waiting for network traffic
+ or identify network-related problems.
+ */
+ probe net__read__start();
+ probe net__read__done(int status, unsigned long bytes);
+ probe net__write__start(unsigned long bytes);
+ probe net__write__done(int status);
+
+ /* MyISAM Key cache probes */
+ probe keycache__read__start(char *filepath, unsigned long bytes,
+ unsigned long mem_used, unsigned long mem_free);
+ probe keycache__read__block(unsigned long bytes);
+ probe keycache__read__hit();
+ probe keycache__read__miss();
+ probe keycache__read__done(unsigned long mem_used, unsigned long mem_free);
+ probe keycache__write__start(char *filepath, unsigned long bytes,
+ unsigned long mem_used, unsigned long mem_free);
+ probe keycache__write__block(unsigned long bytes);
+ probe keycache__write__done(unsigned long mem_used, unsigned long mem_free);
+};
+
+#pragma D attributes Evolving/Evolving/Common provider mysql provider
+#pragma D attributes Evolving/Evolving/Common provider mysql module
+#pragma D attributes Evolving/Evolving/Common provider mysql function
+#pragma D attributes Evolving/Evolving/Common provider mysql name
+#pragma D attributes Evolving/Evolving/Common provider mysql args
diff --git a/include/probes_mysql.h b/include/probes_mysql.h
new file mode 100644
index 00000000000..13491c661fd
--- /dev/null
+++ b/include/probes_mysql.h
@@ -0,0 +1,13 @@
+#ifndef PROBES_MYSQL_H
+
+#define PROBES_MYSQL_H
+
+#include <my_global.h>
+
+#if defined(HAVE_DTRACE) && !defined(DISABLE_DTRACE)
+#include "probes_mysql_dtrace.h"
+#else
+#include "probes_mysql_nodtrace.h"
+#endif
+
+#endif /* PROBES_MYSQL_H */
diff --git a/include/probes_mysql_nodtrace.h b/include/probes_mysql_nodtrace.h
new file mode 100644
index 00000000000..bc3b65a00e5
--- /dev/null
+++ b/include/probes_mysql_nodtrace.h
@@ -0,0 +1,129 @@
+/*
+ * Generated by dheadgen(1).
+ */
+
+#ifndef _PROBES_MYSQL_D
+#define _PROBES_MYSQL_D
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MYSQL_CONNECTION_START(arg0, arg1, arg2)
+#define MYSQL_CONNECTION_START_ENABLED() (0)
+#define MYSQL_CONNECTION_DONE(arg0, arg1)
+#define MYSQL_CONNECTION_DONE_ENABLED() (0)
+#define MYSQL_COMMAND_START(arg0, arg1, arg2, arg3)
+#define MYSQL_COMMAND_START_ENABLED() (0)
+#define MYSQL_COMMAND_DONE(arg0)
+#define MYSQL_COMMAND_DONE_ENABLED() (0)
+#define MYSQL_QUERY_START(arg0, arg1, arg2, arg3, arg4)
+#define MYSQL_QUERY_START_ENABLED() (0)
+#define MYSQL_QUERY_DONE(arg0)
+#define MYSQL_QUERY_DONE_ENABLED() (0)
+#define MYSQL_QUERY_PARSE_START(arg0)
+#define MYSQL_QUERY_PARSE_START_ENABLED() (0)
+#define MYSQL_QUERY_PARSE_DONE(arg0)
+#define MYSQL_QUERY_PARSE_DONE_ENABLED() (0)
+#define MYSQL_QUERY_CACHE_HIT(arg0, arg1)
+#define MYSQL_QUERY_CACHE_HIT_ENABLED() (0)
+#define MYSQL_QUERY_CACHE_MISS(arg0)
+#define MYSQL_QUERY_CACHE_MISS_ENABLED() (0)
+#define MYSQL_QUERY_EXEC_START(arg0, arg1, arg2, arg3, arg4, arg5)
+#define MYSQL_QUERY_EXEC_START_ENABLED() (0)
+#define MYSQL_QUERY_EXEC_DONE(arg0)
+#define MYSQL_QUERY_EXEC_DONE_ENABLED() (0)
+#define MYSQL_INSERT_ROW_START(arg0, arg1)
+#define MYSQL_INSERT_ROW_START_ENABLED() (0)
+#define MYSQL_INSERT_ROW_DONE(arg0)
+#define MYSQL_INSERT_ROW_DONE_ENABLED() (0)
+#define MYSQL_UPDATE_ROW_START(arg0, arg1)
+#define MYSQL_UPDATE_ROW_START_ENABLED() (0)
+#define MYSQL_UPDATE_ROW_DONE(arg0)
+#define MYSQL_UPDATE_ROW_DONE_ENABLED() (0)
+#define MYSQL_DELETE_ROW_START(arg0, arg1)
+#define MYSQL_DELETE_ROW_START_ENABLED() (0)
+#define MYSQL_DELETE_ROW_DONE(arg0)
+#define MYSQL_DELETE_ROW_DONE_ENABLED() (0)
+#define MYSQL_READ_ROW_START(arg0, arg1, arg2)
+#define MYSQL_READ_ROW_START_ENABLED() (0)
+#define MYSQL_READ_ROW_DONE(arg0)
+#define MYSQL_READ_ROW_DONE_ENABLED() (0)
+#define MYSQL_INDEX_READ_ROW_START(arg0, arg1)
+#define MYSQL_INDEX_READ_ROW_START_ENABLED() (0)
+#define MYSQL_INDEX_READ_ROW_DONE(arg0)
+#define MYSQL_INDEX_READ_ROW_DONE_ENABLED() (0)
+#define MYSQL_HANDLER_RDLOCK_START(arg0, arg1)
+#define MYSQL_HANDLER_RDLOCK_START_ENABLED() (0)
+#define MYSQL_HANDLER_WRLOCK_START(arg0, arg1)
+#define MYSQL_HANDLER_WRLOCK_START_ENABLED() (0)
+#define MYSQL_HANDLER_UNLOCK_START(arg0, arg1)
+#define MYSQL_HANDLER_UNLOCK_START_ENABLED() (0)
+#define MYSQL_HANDLER_RDLOCK_DONE(arg0)
+#define MYSQL_HANDLER_RDLOCK_DONE_ENABLED() (0)
+#define MYSQL_HANDLER_WRLOCK_DONE(arg0)
+#define MYSQL_HANDLER_WRLOCK_DONE_ENABLED() (0)
+#define MYSQL_HANDLER_UNLOCK_DONE(arg0)
+#define MYSQL_HANDLER_UNLOCK_DONE_ENABLED() (0)
+#define MYSQL_FILESORT_START(arg0, arg1)
+#define MYSQL_FILESORT_START_ENABLED() (0)
+#define MYSQL_FILESORT_DONE(arg0, arg1)
+#define MYSQL_FILESORT_DONE_ENABLED() (0)
+#define MYSQL_SELECT_START(arg0)
+#define MYSQL_SELECT_START_ENABLED() (0)
+#define MYSQL_SELECT_DONE(arg0, arg1)
+#define MYSQL_SELECT_DONE_ENABLED() (0)
+#define MYSQL_INSERT_START(arg0)
+#define MYSQL_INSERT_START_ENABLED() (0)
+#define MYSQL_INSERT_DONE(arg0, arg1)
+#define MYSQL_INSERT_DONE_ENABLED() (0)
+#define MYSQL_INSERT_SELECT_START(arg0)
+#define MYSQL_INSERT_SELECT_START_ENABLED() (0)
+#define MYSQL_INSERT_SELECT_DONE(arg0, arg1)
+#define MYSQL_INSERT_SELECT_DONE_ENABLED() (0)
+#define MYSQL_UPDATE_START(arg0)
+#define MYSQL_UPDATE_START_ENABLED() (0)
+#define MYSQL_UPDATE_DONE(arg0, arg1, arg2)
+#define MYSQL_UPDATE_DONE_ENABLED() (0)
+#define MYSQL_MULTI_UPDATE_START(arg0)
+#define MYSQL_MULTI_UPDATE_START_ENABLED() (0)
+#define MYSQL_MULTI_UPDATE_DONE(arg0, arg1, arg2)
+#define MYSQL_MULTI_UPDATE_DONE_ENABLED() (0)
+#define MYSQL_DELETE_START(arg0)
+#define MYSQL_DELETE_START_ENABLED() (0)
+#define MYSQL_DELETE_DONE(arg0, arg1)
+#define MYSQL_DELETE_DONE_ENABLED() (0)
+#define MYSQL_MULTI_DELETE_START(arg0)
+#define MYSQL_MULTI_DELETE_START_ENABLED() (0)
+#define MYSQL_MULTI_DELETE_DONE(arg0, arg1)
+#define MYSQL_MULTI_DELETE_DONE_ENABLED() (0)
+#define MYSQL_NET_READ_START()
+#define MYSQL_NET_READ_START_ENABLED() (0)
+#define MYSQL_NET_READ_DONE(arg0, arg1)
+#define MYSQL_NET_READ_DONE_ENABLED() (0)
+#define MYSQL_NET_WRITE_START(arg0)
+#define MYSQL_NET_WRITE_START_ENABLED() (0)
+#define MYSQL_NET_WRITE_DONE(arg0)
+#define MYSQL_NET_WRITE_DONE_ENABLED() (0)
+#define MYSQL_KEYCACHE_READ_START(arg0, arg1, arg2, arg3)
+#define MYSQL_KEYCACHE_READ_START_ENABLED() (0)
+#define MYSQL_KEYCACHE_READ_BLOCK(arg0)
+#define MYSQL_KEYCACHE_READ_BLOCK_ENABLED() (0)
+#define MYSQL_KEYCACHE_READ_HIT()
+#define MYSQL_KEYCACHE_READ_HIT_ENABLED() (0)
+#define MYSQL_KEYCACHE_READ_MISS()
+#define MYSQL_KEYCACHE_READ_MISS_ENABLED() (0)
+#define MYSQL_KEYCACHE_READ_DONE(arg0, arg1)
+#define MYSQL_KEYCACHE_READ_DONE_ENABLED() (0)
+#define MYSQL_KEYCACHE_WRITE_START(arg0, arg1, arg2, arg3)
+#define MYSQL_KEYCACHE_WRITE_START_ENABLED() (0)
+#define MYSQL_KEYCACHE_WRITE_BLOCK(arg0)
+#define MYSQL_KEYCACHE_WRITE_BLOCK_ENABLED() (0)
+#define MYSQL_KEYCACHE_WRITE_DONE(arg0, arg1)
+#define MYSQL_KEYCACHE_WRITE_DONE_ENABLED() (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PROBES_MYSQL_D */
diff --git a/include/queues.h b/include/queues.h
index d01b73ba999..07962f09201 100644
--- a/include/queues.h
+++ b/include/queues.h
@@ -22,6 +22,9 @@
#ifndef _queues_h
#define _queues_h
+
+#include "my_global.h" /* uchar */
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/include/rijndael.h b/include/rijndael.h
index 89963a85c99..71df1c48dbf 100644
--- a/include/rijndael.h
+++ b/include/rijndael.h
@@ -1,3 +1,6 @@
+#ifndef RIJNDAEL_INCLUDED
+#define RIJNDAEL_INCLUDED
+
/* Copyright (C) 2002 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -39,3 +42,5 @@ void rijndaelEncrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
const uint8 pt[16], uint8 ct[16]);
void rijndaelDecrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
const uint8 ct[16], uint8 pt[16]);
+
+#endif /* RIJNDAEL_INCLUDED */
diff --git a/include/service_versions.h b/include/service_versions.h
new file mode 100644
index 00000000000..114957cdd86
--- /dev/null
+++ b/include/service_versions.h
@@ -0,0 +1,24 @@
+/* Copyright (C) 2009 Sun Microsystems, Inc.
+
+ 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 */
+
+#ifdef _WIN32
+#define SERVICE_VERSION __declspec(dllexport) void *
+#else
+#define SERVICE_VERSION void *
+#endif
+
+#define VERSION_my_snprintf 0x0100
+#define VERSION_thd_alloc 0x0100
+
diff --git a/include/sha1.h b/include/sha1.h
index e476456a9bd..5b4dc5d46ed 100644
--- a/include/sha1.h
+++ b/include/sha1.h
@@ -1,3 +1,6 @@
+#ifndef SHA1_INCLUDED
+#define SHA1_INCLUDED
+
/* Copyright (C) 2002, 2006 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -64,3 +67,5 @@ int mysql_sha1_input(SHA1_CONTEXT*, const uint8 *, unsigned int);
int mysql_sha1_result(SHA1_CONTEXT* , uint8 Message_Digest[SHA1_HASH_SIZE]);
C_MODE_END
+
+#endif /* SHA__INCLUDED */
diff --git a/include/sha2.h b/include/sha2.h
new file mode 100644
index 00000000000..e67a4100ff2
--- /dev/null
+++ b/include/sha2.h
@@ -0,0 +1,72 @@
+/* Copyright (C) 2007 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 */
+
+#ifndef included_sha2_h
+#define included_sha2_h
+
+#include <my_config.h>
+
+#if defined(HAVE_YASSL) || defined(HAVE_OPENSSL)
+
+# ifdef HAVE_STDDEF_H
+# include <stddef.h>
+# endif
+
+# ifndef HAVE_YASSL
+# include <openssl/sha.h>
+
+# else
+
+#include "../extra/yassl/taocrypt/include/sha.hpp"
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+#ifndef SHA512_DIGEST_LENGTH
+#define SHA512_DIGEST_LENGTH TaoCrypt::SHA512::DIGEST_SIZE
+#endif
+
+#ifndef SHA384_DIGEST_LENGTH
+#define SHA384_DIGEST_LENGTH TaoCrypt::SHA384::DIGEST_SIZE
+#endif
+
+#ifndef SHA256_DIGEST_LENGTH
+#define SHA256_DIGEST_LENGTH TaoCrypt::SHA256::DIGEST_SIZE
+#endif
+
+#ifndef SHA224_DIGEST_LENGTH
+#define SHA224_DIGEST_LENGTH TaoCrypt::SHA224::DIGEST_SIZE
+#endif
+
+#define GEN_YASSL_SHA2_BRIDGE(size) \
+unsigned char* SHA##size(const unsigned char *input_ptr, size_t input_length, \
+ char unsigned *output_ptr);
+
+GEN_YASSL_SHA2_BRIDGE(512);
+GEN_YASSL_SHA2_BRIDGE(384);
+GEN_YASSL_SHA2_BRIDGE(256);
+GEN_YASSL_SHA2_BRIDGE(224);
+
+#undef GEN_YASSL_SHA2_BRIDGE
+
+# ifdef __cplusplus
+}
+# endif
+
+# endif /* HAVE_YASSL */
+
+#endif /* HAVE_OPENSSL || HAVE_YASSL */
+#endif /* included_sha2_h */
diff --git a/include/sql_common.h b/include/sql_common.h
index 9e43d076ba9..5fd8778d62b 100644
--- a/include/sql_common.h
+++ b/include/sql_common.h
@@ -1,3 +1,6 @@
+#ifndef SQL_COMMON_INCLUDED
+#define SQL_COMMON_INCLUDED
+
/* Copyright (C) 2003-2004, 2006 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -48,3 +51,4 @@ void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate);
#define protocol_41(A) ((A)->server_capabilities & CLIENT_PROTOCOL_41)
+#endif /* SQL_COMMON_INCLUDED */
diff --git a/include/sslopt-case.h b/include/sslopt-case.h
index adb9a28503b..3b64a225fe2 100644
--- a/include/sslopt-case.h
+++ b/include/sslopt-case.h
@@ -1,3 +1,6 @@
+#ifndef SSLOPT_CASE_INCLUDED
+#define SSLOPT_CASE_INCLUDED
+
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -13,7 +16,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
case OPT_SSL_KEY:
case OPT_SSL_CERT:
case OPT_SSL_CA:
@@ -26,3 +29,4 @@
opt_use_ssl= 1;
break;
#endif
+#endif /* SSLOPT_CASE_INCLUDED */
diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h
index c76b5dcd252..151287e1718 100644
--- a/include/sslopt-longopts.h
+++ b/include/sslopt-longopts.h
@@ -1,3 +1,6 @@
+#ifndef SSLOPT_LONGOPTS_INCLUDED
+#define SSLOPT_LONGOPTS_INCLUDED
+
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -13,11 +16,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
{"ssl", OPT_SSL_SSL,
- "Enable SSL for connection (automatically enabled with other flags). Disable with --skip-ssl.",
- (uchar **) &opt_use_ssl, (uchar **) &opt_use_ssl, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ "Enable SSL for connection (automatically enabled with other flags).",
+ (uchar **) &opt_use_ssl, (uchar **) &opt_use_ssl, 0, GET_BOOL, OPT_ARG, 0, 0, 0,
0, 0, 0},
{"ssl-ca", OPT_SSL_CA,
"CA file in PEM format (check OpenSSL docs, implies --ssl).",
@@ -40,6 +43,7 @@
{"ssl-verify-server-cert", OPT_SSL_VERIFY_SERVER_CERT,
"Verify server's \"Common Name\" in its cert against hostname used when connecting. This option is disabled by default.",
(uchar **) &opt_ssl_verify_server_cert, (uchar **) &opt_ssl_verify_server_cert,
- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
#endif /* HAVE_OPENSSL */
+#endif /* SSLOPT_LONGOPTS_INCLUDED */
diff --git a/include/sslopt-vars.h b/include/sslopt-vars.h
index 3369f870db2..d0eec3b6d74 100644
--- a/include/sslopt-vars.h
+++ b/include/sslopt-vars.h
@@ -1,3 +1,6 @@
+#ifndef SSLOPT_VARS_INCLUDED
+#define SSLOPT_VARS_INCLUDED
+
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -13,7 +16,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
#ifdef SSL_VARS_NOT_STATIC
#define SSL_STATIC
#else
@@ -29,3 +32,4 @@ SSL_STATIC char *opt_ssl_key = 0;
SSL_STATIC my_bool opt_ssl_verify_server_cert= 0;
#endif
#endif
+#endif /* SSLOPT_VARS_INCLUDED */
diff --git a/include/thr_alarm.h b/include/thr_alarm.h
index fb906039269..8d7f5bcdee0 100644
--- a/include/thr_alarm.h
+++ b/include/thr_alarm.h
@@ -64,7 +64,7 @@ typedef my_bool ALARM;
#if defined(__WIN__)
typedef struct st_thr_alarm_entry
{
- rf_SetTimer crono;
+ UINT_PTR crono;
} thr_alarm_entry;
#else /* System with posix threads */
diff --git a/include/thr_lock.h b/include/thr_lock.h
index fb70c57c0e7..1f4072ca0c5 100644
--- a/include/thr_lock.h
+++ b/include/thr_lock.h
@@ -1,4 +1,4 @@
-/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
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
@@ -83,7 +83,6 @@ enum enum_thr_lock_result { THR_LOCK_SUCCESS= 0, THR_LOCK_ABORTED= 1,
extern ulong max_write_lock_count;
-extern ulong table_lock_wait_timeout;
extern my_bool thr_lock_inited;
extern enum thr_lock_type thr_upgraded_concurrent_insert_lock;
@@ -115,10 +114,11 @@ typedef struct st_thr_lock_data {
THR_LOCK_OWNER *owner;
struct st_thr_lock_data *next,**prev;
struct st_thr_lock *lock;
- pthread_cond_t *cond;
+ mysql_cond_t *cond;
enum thr_lock_type type;
void *status_param; /* Param to status functions */
void *debug_print_param;
+ struct PSI_table *m_psi;
} THR_LOCK_DATA;
struct st_lock_list {
@@ -127,7 +127,7 @@ struct st_lock_list {
typedef struct st_thr_lock {
LIST list;
- pthread_mutex_t mutex;
+ mysql_mutex_t mutex;
struct st_lock_list read_wait;
struct st_lock_list read;
struct st_lock_list write_wait;
@@ -144,7 +144,7 @@ typedef struct st_thr_lock {
extern LIST *thr_lock_thread_list;
-extern pthread_mutex_t THR_LOCK_lock;
+extern mysql_mutex_t THR_LOCK_lock;
my_bool init_thr_lock(void); /* Must be called once/thread */
#define thr_lock_owner_init(owner, info_arg) (owner)->info= (info_arg)
@@ -155,19 +155,25 @@ void thr_lock_data_init(THR_LOCK *lock,THR_LOCK_DATA *data,
void *status_param);
enum enum_thr_lock_result thr_lock(THR_LOCK_DATA *data,
THR_LOCK_OWNER *owner,
- enum thr_lock_type lock_type);
+ enum thr_lock_type lock_type,
+ ulong lock_wait_timeout);
void thr_unlock(THR_LOCK_DATA *data);
enum enum_thr_lock_result thr_multi_lock(THR_LOCK_DATA **data,
- uint count, THR_LOCK_OWNER *owner);
+ uint count, THR_LOCK_OWNER *owner,
+ ulong lock_wait_timeout);
void thr_multi_unlock(THR_LOCK_DATA **data,uint count);
+void
+thr_lock_merge_status(THR_LOCK_DATA **data, uint count);
void thr_abort_locks(THR_LOCK *lock, my_bool upgrade_lock);
my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread);
void thr_print_locks(void); /* For debugging */
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);
void thr_downgrade_write_lock(THR_LOCK_DATA *data,
enum thr_lock_type new_lock_type);
-my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data);
+my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data,
+ ulong lock_wait_timeout);
#ifdef __cplusplus
}
#endif
diff --git a/include/typelib.h b/include/typelib.h
index 46106d1bdab..c6a7f7a42e9 100644
--- a/include/typelib.h
+++ b/include/typelib.h
@@ -36,4 +36,9 @@ extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from);
extern TYPELIB sql_protocol_typelib;
+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);
+
#endif /* _typelib_h */
diff --git a/include/violite.h b/include/violite.h
index 1eef3ef5730..05ceaa272c1 100644
--- a/include/violite.h
+++ b/include/violite.h
@@ -30,6 +30,10 @@
extern "C" {
#endif /* __cplusplus */
+#ifdef __cplusplus
+typedef struct st_vio Vio;
+#endif /* __cplusplus */
+
enum enum_vio_type
{
VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET, VIO_TYPE_NAMEDPIPE,
@@ -51,9 +55,6 @@ Vio* vio_new_win32shared_memory(HANDLE handle_file_map,
HANDLE event_client_wrote,
HANDLE event_client_read,
HANDLE event_conn_closed);
-size_t vio_read_pipe(Vio *vio, uchar * buf, size_t size);
-size_t vio_write_pipe(Vio *vio, const uchar * buf, size_t size);
-int vio_close_pipe(Vio * vio);
#else
#define HANDLE void *
#endif /* __WIN__ */
@@ -84,10 +85,18 @@ int vio_errno(Vio*vio);
/* Get socket number */
my_socket vio_fd(Vio*vio);
/* Remote peer's address and name in text form */
-my_bool vio_peer_addr(Vio* vio, char *buf, uint16 *port);
-/* Remotes in_addr */
-void vio_in_addr(Vio *vio, struct in_addr *in);
-my_bool vio_poll_read(Vio *vio,uint timeout);
+my_bool vio_peer_addr(Vio *vio, char *buf, uint16 *port, size_t buflen);
+my_bool vio_poll_read(Vio *vio, uint timeout);
+my_bool vio_is_connected(Vio *vio);
+ssize_t vio_pending(Vio *vio);
+
+my_bool vio_get_normalized_ip_string(const struct sockaddr *addr, int addr_length,
+ char *ip_string, size_t ip_string_size);
+
+int vio_getnameinfo(const struct sockaddr *sa,
+ char *hostname, size_t hostname_size,
+ char *port, size_t port_size,
+ int flags);
#ifdef HAVE_OPENSSL
#include <openssl/opensslv.h>
@@ -109,6 +118,7 @@ typedef my_socket YASSL_SOCKET_T;
#include <openssl/ssl.h>
#include <openssl/err.h>
+#ifndef EMBEDDED_LIBRARY
enum enum_ssl_init_error
{
SSL_INITERR_NOERROR= 0, SSL_INITERR_CERT, SSL_INITERR_KEY,
@@ -134,14 +144,9 @@ struct st_VioSSLFd
const char *ca_file,const char *ca_path,
const char *cipher, enum enum_ssl_init_error* error);
void free_vio_ssl_acceptor_fd(struct st_VioSSLFd *fd);
+#endif /* ! EMBEDDED_LIBRARY */
#endif /* HAVE_OPENSSL */
-#ifdef HAVE_SMEM
-size_t vio_read_shared_memory(Vio *vio, uchar * buf, size_t size);
-size_t vio_write_shared_memory(Vio *vio, const uchar * buf, size_t size);
-int vio_close_shared_memory(Vio * vio);
-#endif
-
void vio_end(void);
#ifdef __cplusplus
@@ -161,9 +166,10 @@ void vio_end(void);
#define vio_should_retry(vio) (vio)->should_retry(vio)
#define vio_was_interrupted(vio) (vio)->was_interrupted(vio)
#define vio_close(vio) ((vio)->vioclose)(vio)
-#define vio_peer_addr(vio, buf, prt) (vio)->peer_addr(vio, buf, prt)
-#define vio_in_addr(vio, in) (vio)->in_addr(vio, in)
+#define vio_peer_addr(vio, buf, prt, buflen) (vio)->peer_addr(vio, buf, prt, buflen)
#define vio_timeout(vio, which, seconds) (vio)->timeout(vio, which, seconds)
+#define vio_poll_read(vio, timeout) (vio)->poll_read(vio, timeout)
+#define vio_is_connected(vio) (vio)->is_connected(vio)
#endif /* !defined(DONT_MAP_VIO) */
/* This enumerator is used in parser - should be always visible */
@@ -185,8 +191,9 @@ struct st_vio
HANDLE hPipe;
my_bool localhost; /* Are we from localhost? */
int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
- struct sockaddr_in local; /* Local internet address */
- struct sockaddr_in remote; /* Remote internet address */
+ struct sockaddr_storage local; /* Local internet address */
+ struct sockaddr_storage remote; /* Remote internet address */
+ int addrLen; /* Length of remote address */
enum enum_vio_type type; /* Type of connection */
char desc[30]; /* String description */
char *read_buffer; /* buffer for vio_read_buff */
@@ -202,12 +209,14 @@ struct st_vio
my_bool (*is_blocking)(Vio*);
int (*viokeepalive)(Vio*, my_bool);
int (*fastsend)(Vio*);
- my_bool (*peer_addr)(Vio*, char *, uint16*);
- void (*in_addr)(Vio*, struct in_addr*);
+ my_bool (*peer_addr)(Vio*, char *, uint16*, size_t);
+ void (*in_addr)(Vio*, struct sockaddr_storage*);
my_bool (*should_retry)(Vio*);
my_bool (*was_interrupted)(Vio*);
int (*vioclose)(Vio*);
void (*timeout)(Vio*, unsigned int which, unsigned int timeout);
+ my_bool (*poll_read)(Vio *vio, uint timeout);
+ my_bool (*is_connected)(Vio*);
#ifdef HAVE_OPENSSL
void *ssl_arg;
#endif