summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <msvensson@neptunus.(none)>2005-04-27 21:40:11 +0200
committerunknown <msvensson@neptunus.(none)>2005-04-27 21:40:11 +0200
commit57d9c6d077bd6f2d437457e1bc4aa86607e80f46 (patch)
tree695946f806da8fe0c8de98f19a9c883412f8dec7
parentcd50bf9ae4407e856a5cb4263512013a24cff5b7 (diff)
parent3238612840467f6edc8aab676f31940fc731bff7 (diff)
downloadmariadb-git-57d9c6d077bd6f2d437457e1bc4aa86607e80f46.tar.gz
Merge bk-internal.mysql.com:/home/bk/mysql-4.1
into neptunus.(none):/home/msvensson/mysql/mysql-4.1 configure.in: Auto merged
-rw-r--r--acinclude.m42
-rw-r--r--configure.in155
-rw-r--r--include/my_global.h9
-rw-r--r--myisam/Makefile.am2
-rw-r--r--mysql-test/r/func_math.result11
-rw-r--r--mysql-test/t/func_math.test13
-rw-r--r--mysys/thr_mutex.c2
-rw-r--r--scripts/Makefile.am2
-rw-r--r--scripts/mysqld_safe.sh2
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/lock.cc51
-rw-r--r--sql/mysql_priv.h5
-rw-r--r--sql/sql_insert.cc75
-rw-r--r--sql/stacktrace.c4
-rw-r--r--sql/stacktrace.h4
-rw-r--r--support-files/Makefile.am2
-rw-r--r--tools/mysqlmanager.c2
17 files changed, 244 insertions, 99 deletions
diff --git a/acinclude.m4 b/acinclude.m4
index 61b37294377..f868489f2d2 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -1005,7 +1005,7 @@ AC_DEFUN([MYSQL_FIND_OPENSSL], [
if test -z "$OPENSSL_LIB" -o -z "$OPENSSL_INCLUDE" ; then
echo "Could not find an installation of OpenSSL"
if test -n "$OPENSSL_LIB" ; then
- if test "$IS_LINUX" = "true"; then
+ if test "$TARGET_LINUX" = "true"; then
echo "Looks like you've forgotten to install OpenSSL development RPM"
fi
fi
diff --git a/configure.in b/configure.in
index bc058265b9a..e90bea90dad 100644
--- a/configure.in
+++ b/configure.in
@@ -410,15 +410,16 @@ AC_MSG_CHECKING("if we should use 'skip-locking' as default for $target_os")
if expr "$target_os" : "[[Ll]]inux.*" > /dev/null
then
MYSQLD_DEFAULT_SWITCHES="--skip-locking"
- IS_LINUX="true"
- AC_MSG_RESULT("yes");
+ TARGET_LINUX="true"
+ AC_MSG_RESULT("yes")
+ AC_DEFINE([TARGET_OS_LINUX], [1], [Whether we build for Linux])
else
MYSQLD_DEFAULT_SWITCHES=""
- IS_LINUX="false"
- AC_MSG_RESULT("no");
+ TARGET_LINUX="false"
+ AC_MSG_RESULT("no")
fi
AC_SUBST(MYSQLD_DEFAULT_SWITCHES)
-AC_SUBST(IS_LINUX)
+AC_SUBST(TARGET_LINUX)
dnl Find paths to some shell programs
AC_PATH_PROG(LN, ln, ln)
@@ -607,7 +608,7 @@ AC_SUBST(NOINST_LDFLAGS)
# (this is true on the MySQL build machines to avoid NSS problems)
#
-if test "$IS_LINUX" = "true" -a "$static_nss" = ""
+if test "$TARGET_LINUX" = "true" -a "$static_nss" = ""
then
tmp=`nm /usr/lib/libc.a | grep _nss_files_getaliasent_r`
if test -n "$tmp"
@@ -841,7 +842,7 @@ struct request_info *req;
])
AC_SUBST(WRAPLIBS)
-if test "$IS_LINUX" = "true"; then
+if test "$TARGET_LINUX" = "true"; then
AC_MSG_CHECKING([for atomic operations])
atom_ops=
@@ -885,7 +886,7 @@ int main()
[ USE_PSTACK=no ])
pstack_libs=
pstack_dirs=
- if test "$USE_PSTACK" = yes -a "$IS_LINUX" = "true" -a "$BASE_MACHINE_TYPE" = "i386" -a "$with_mit_threads" = "no"
+ if test "$USE_PSTACK" = yes -a "$TARGET_LINUX" = "true" -a "$BASE_MACHINE_TYPE" = "i386" -a "$with_mit_threads" = "no"
then
have_libiberty= have_libbfd=
my_save_LIBS="$LIBS"
@@ -1266,61 +1267,93 @@ esac
# We have to check libc last because else it fails on Solaris 2.6
with_posix_threads="no"
-# Hack for DEC-UNIX (OSF1)
+# Search thread lib on Linux
if test "$with_named_thread" = "no" -a "$with_mit_threads" = "no"
then
- # Look for LinuxThreads.
- AC_MSG_CHECKING("LinuxThreads")
- res=`grep Linuxthreads /usr/include/pthread.h 2>/dev/null | wc -l`
- if test "$res" -gt 0
+ AC_MSG_CHECKING("Linux threads")
+ if test "$TARGET_LINUX" = "true"
then
- AC_MSG_RESULT("Found")
- AC_DEFINE([HAVE_LINUXTHREADS], [1],
- [Whether we are using Xavier Leroy's LinuxThreads])
- # Linux 2.0 sanity check
- AC_TRY_COMPILE([#include <sched.h>], [int a = sched_get_priority_min(1);], ,
- AC_MSG_ERROR([Syntax error in sched.h. Change _P to __P in the /usr/include/sched.h file. See the Installation chapter in the Reference Manual]))
- # RedHat 5.0 does not work with dynamic linking of this. -static also
- # gives a speed increase in linux so it does not hurt on other systems.
- with_named_thread="-lpthread"
- else
- AC_MSG_RESULT("Not found")
- # If this is a linux machine we should barf
- if test "$IS_LINUX" = "true"
- then
- AC_MSG_ERROR([This is a linux system and Linuxthreads was not
-found. On linux Linuxthreads should be used. Please install Linuxthreads
-(or a new glibc) and try again. See the Installation chapter in the
-Reference Manual for more information.])
- else
- AC_MSG_CHECKING("DEC threads")
- if test -f /usr/shlib/libpthread.so -a -f /usr/lib/libmach.a -a -f /usr/ccs/lib/cmplrs/cc/libexc.a
- then
- with_named_thread="-lpthread -lmach -lexc"
- CFLAGS="$CFLAGS -D_REENTRANT"
- CXXFLAGS="$CXXFLAGS -D_REENTRANT"
- AC_DEFINE(HAVE_DEC_THREADS, [1],
- [Whether we are using DEC threads])
- AC_MSG_RESULT("yes")
- else
- AC_MSG_RESULT("no")
- AC_MSG_CHECKING("DEC 3.2 threads")
- if test -f /usr/shlib/libpthreads.so -a -f /usr/lib/libmach.a -a -f /usr/ccs/lib/cmplrs/cc/libexc.a
- then
- with_named_thread="-lpthreads -lmach -lc_r"
- AC_DEFINE(HAVE_DEC_THREADS, [1])
- AC_DEFINE([HAVE_DEC_3_2_THREADS], [1],
- [Whether we are using OSF1 DEC threads on 3.2])
- with_osf32_threads="yes"
- MYSQLD_DEFAULT_SWITCHES="--skip-thread-priority"
- AC_MSG_RESULT("yes")
- else
- AC_MSG_RESULT("no")
+ AC_MSG_RESULT("starting")
+ # use getconf to check glibc contents
+ AC_MSG_CHECKING("getconf GNU_LIBPTHREAD_VERSION")
+ case `getconf GNU_LIBPTHREAD_VERSION | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` in
+ NPTL* )
+ AC_MSG_RESULT("NPTL")
+ AC_DEFINE([HAVE_NPTL], [1], [NPTL threads implementation])
+ with_named_thread="-lpthread"
+ ;;
+ LINUXTHREADS* )
+ AC_MSG_RESULT("Linuxthreads")
+ AC_DEFINE([HAVE_LINUXTHREADS], [1],
+ [Whether we are using Xavier Leroy's LinuxThreads])
+ with_named_thread="-lpthread"
+ ;;
+ * )
+ AC_MSG_RESULT("unknown")
+ ;;
+ esac
+ if test "$with_named_thread" = "no"
+ then
+ # old method, check headers
+ # Look for LinuxThreads.
+ AC_MSG_CHECKING("LinuxThreads in header file comment")
+ res=`grep Linuxthreads /usr/include/pthread.h 2>/dev/null | wc -l`
+ if test "$res" -gt 0
+ then
+ AC_MSG_RESULT("Found")
+ AC_DEFINE([HAVE_LINUXTHREADS], [1],
+ [Whether we are using Xavier Leroy's LinuxThreads])
+ # Linux 2.0 sanity check
+ AC_TRY_COMPILE([#include <sched.h>], [int a = sched_get_priority_min(1);], ,
+ AC_MSG_ERROR([Syntax error in sched.h. Change _P to __P in the /usr/include/sched.h file. See the Installation chapter in the Reference Manual]))
+ # RedHat 5.0 does not work with dynamic linking of this. -static also
+ # gives a speed increase in linux so it does not hurt on other systems.
+ with_named_thread="-lpthread"
+ else
+ AC_MSG_RESULT("Not found")
+ # If this is a linux machine we should barf
+ AC_MSG_ERROR([This is a Linux system without a working getconf,
+and Linuxthreads was not found. Please install it (or a new glibc) and try again.
+See the Installation chapter in the Reference Manual for more information.])
fi
- fi
- fi
- fi
-fi
+ else
+ AC_MSG_RESULT("no need to check headers")
+ fi
+
+ AC_MSG_CHECKING("for pthread_create in -lpthread");
+ ac_save_LIBS="$LIBS"
+ LIBS="$LIBS -lpthread"
+ AC_TRY_LINK( [#include <pthread.h>],
+ [ (void) pthread_create((pthread_t*) 0,(pthread_attr_t*) 0, 0, 0); ],
+ AC_MSG_RESULT("yes"),
+ [ AC_MSG_RESULT("no")
+ AC_MSG_ERROR([
+This is a Linux system claiming to support threads, either Linuxthreads or NPTL, but linking a test program failed.
+Please install one of these (or a new glibc) and try again.
+See the Installation chapter in the Reference Manual for more information.]) ]
+ )
+ LIBS="$ac_save_LIBS"
+ else
+ AC_MSG_RESULT("no")
+ fi # "$TARGET_LINUX"
+fi # "$with_named_thread" = "no" -a "$with_mit_threads" = "no"
+
+
+# Hack for DEC-UNIX (OSF1 -> Tru64)
+if test "$with_named_thread" = "no" -a "$with_mit_threads" = "no"
+then
+ AC_MSG_CHECKING("DEC threads post OSF/1 3.2")
+ if test -f /usr/shlib/libpthread.so -a -f /usr/lib/libmach.a -a -f /usr/ccs/lib/cmplrs/cc/libexc.a
+ then
+ with_named_thread="-lpthread -lmach -lexc"
+ CFLAGS="$CFLAGS -D_REENTRANT"
+ CXXFLAGS="$CXXFLAGS -D_REENTRANT"
+ AC_DEFINE(HAVE_DEC_THREADS, [1], [Whether we are using DEC threads])
+ AC_MSG_RESULT("yes")
+ else
+ AC_MSG_RESULT("no")
+ fi # DEC threads
+fi # "$with_named_thread" = "no" -a "$with_mit_threads" = "no"
dnl This is needed because -lsocket has to come after the thread
@@ -1738,7 +1771,7 @@ fi
AC_SUBST(COMPILATION_COMMENT)
AC_MSG_CHECKING("need of special linking flags")
-if test "$IS_LINUX" = "true" -a "$ac_cv_prog_gcc" = "yes" -a "$all_is_static" != "yes"
+if test "$TARGET_LINUX" = "true" -a "$ac_cv_prog_gcc" = "yes" -a "$all_is_static" != "yes"
then
LDFLAGS="$LDFLAGS -rdynamic"
AC_MSG_RESULT("-rdynamic")
@@ -1957,7 +1990,7 @@ CFLAGS="$ORG_CFLAGS"
# Sanity check: We chould not have any fseeko symbol unless
# large_file_support=yes
AC_CHECK_FUNC(fseeko,
-[if test "$large_file_support" = no -a "$IS_LINUX" = "true";
+[if test "$large_file_support" = no -a "$TARGET_LINUX" = "true";
then
AC_MSG_ERROR("Found fseeko symbol but large_file_support is not enabled!");
fi]
diff --git a/include/my_global.h b/include/my_global.h
index 23cf0d54824..745179e8a06 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -97,7 +97,7 @@
/* Fix problem with S_ISLNK() on Linux */
-#if defined(HAVE_LINUXTHREADS)
+#if defined(TARGET_OS_LINUX)
#undef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
@@ -107,6 +107,7 @@
#undef THREAD
#undef HAVE_mit_thread
#undef HAVE_LINUXTHREADS
+#undef HAVE_NPTL
#undef HAVE_UNIXWARE7_THREADS
#endif
@@ -214,13 +215,13 @@ C_MODE_START int __cxa_pure_virtual() {\
#endif
/* In Linux-alpha we have atomic.h if we are using gcc */
-#if defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && defined(__alpha__) && (__GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 95)) && !defined(HAVE_ATOMIC_ADD)
+#if defined(TARGET_OS_LINUX) && defined(__GNUC__) && defined(__alpha__) && (__GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 95)) && !defined(HAVE_ATOMIC_ADD)
#define HAVE_ATOMIC_ADD
#define HAVE_ATOMIC_SUB
#endif
/* In Linux-ia64 including atomic.h will give us an error */
-#if (defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && (defined(__ia64__)||defined(__powerpc64__))) || !defined(THREAD)
+#if (defined(TARGET_OS_LINUX) && defined(__GNUC__) && (defined(__ia64__)||defined(__powerpc64__))) || !defined(THREAD)
#undef HAVE_ATOMIC_ADD
#undef HAVE_ATOMIC_SUB
#endif
@@ -755,7 +756,7 @@ typedef unsigned long uint32; /* Short for unsigned integer >= 32 bits */
error "Neither int or long is of 4 bytes width"
#endif
-#if !defined(HAVE_ULONG) && !defined(HAVE_LINUXTHREADS) && !defined(__USE_MISC)
+#if !defined(HAVE_ULONG) && !defined(TARGET_OS_LINUX) && !defined(__USE_MISC)
typedef unsigned long ulong; /* Short for unsigned long */
#endif
#ifndef longlong_defined
diff --git a/myisam/Makefile.am b/myisam/Makefile.am
index 378e8107814..0b8a25e3404 100644
--- a/myisam/Makefile.am
+++ b/myisam/Makefile.am
@@ -88,7 +88,7 @@ SUFFIXES = .sh
-e 's!@''FIND_PROC''@!@FIND_PROC@!' \
-e 's!@''MYSQLD_DEFAULT_SWITCHES''@!@MYSQLD_DEFAULT_SWITCHES@!' \
-e 's!@''MYSQL_UNIX_ADDR''@!@MYSQL_UNIX_ADDR@!' \
- -e 's!@''IS_LINUX''@!@IS_LINUX@!' \
+ -e 's!@''TARGET_LINUX''@!@TARGET_LINUX@!' \
-e "s!@""CONF_COMMAND""@!@CONF_COMMAND@!" \
-e 's!@''MYSQLD_USER''@!@MYSQLD_USER@!' \
-e 's!@''sysconfdir''@!@sysconfdir@!' \
diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result
index 3a28cccfac5..9cb1e4a56d6 100644
--- a/mysql-test/r/func_math.result
+++ b/mysql-test/r/func_math.result
@@ -1,3 +1,4 @@
+drop table if exists t1;
select floor(5.5),floor(-5.5);
floor(5.5) floor(-5.5)
5 -6
@@ -126,3 +127,13 @@ Warnings:
Note 1003 select degrees(pi()) AS `degrees(pi())`,radians(360) AS `radians(360)`
select rand(rand);
ERROR 42S22: Unknown column 'rand' in 'field list'
+create table t1 select round(1, 6);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `round(1, 6)` double(7,6) NOT NULL default '0.000000'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from t1;
+round(1, 6)
+1.000000
+drop table t1;
diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test
index 668aefc2d8d..4c24dae8c5d 100644
--- a/mysql-test/t/func_math.test
+++ b/mysql-test/t/func_math.test
@@ -2,6 +2,10 @@
# Test of math functions
#
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
select floor(5.5),floor(-5.5);
explain extended select floor(5.5),floor(-5.5);
select ceiling(5.5),ceiling(-5.5);
@@ -58,3 +62,12 @@ explain extended select degrees(pi()),radians(360);
--error 1054
select rand(rand);
+
+#
+# Bug #9837: problem with round()
+#
+
+create table t1 select round(1, 6);
+show create table t1;
+select * from t1;
+drop table t1;
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index bbcfaa8bba6..2facb4e18cf 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -17,7 +17,7 @@
/* This makes a wrapper for mutex handling to make it easier to debug mutex */
#include <my_global.h>
-#if defined(HAVE_LINUXTHREADS) && !defined (__USE_UNIX98)
+#if defined(TARGET_OS_LINUX) && !defined (__USE_UNIX98)
#define __USE_UNIX98 /* To get rw locks under Linux */
#endif
#if defined(THREAD) && defined(SAFE_MUTEX)
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index b170fa483b2..e2ef1bba97c 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -135,7 +135,7 @@ SUFFIXES = .sh
-e 's!@''MYSQLD_DEFAULT_SWITCHES''@!@MYSQLD_DEFAULT_SWITCHES@!' \
-e 's!@''MYSQL_UNIX_ADDR''@!@MYSQL_UNIX_ADDR@!' \
-e 's!@''MYSQL_TCP_PORT''@!@MYSQL_TCP_PORT@!' \
- -e 's!@''IS_LINUX''@!@IS_LINUX@!' \
+ -e 's!@''TARGET_LINUX''@!@TARGET_LINUX@!' \
-e "s!@""CONF_COMMAND""@!@CONF_COMMAND@!" \
-e 's!@''MYSQLD_USER''@!@MYSQLD_USER@!' \
-e 's!@''STATIC_NSS_FLAGS''@!@STATIC_NSS_FLAGS@!' \
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index 308db270828..8a232f4f7f9 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -324,7 +324,7 @@ do
break
fi
- if @IS_LINUX@ && test $KILL_MYSQLD -eq 1
+ if @TARGET_LINUX@ && test $KILL_MYSQLD -eq 1
then
# Test if one process was hanging.
# This is only a fix for Linux (running as base 3 mysqld processes)
diff --git a/sql/item_func.cc b/sql/item_func.cc
index eb6e395c266..2b38584fe23 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1072,6 +1072,8 @@ void Item_func_round::fix_length_and_dec()
decimals=0;
else
decimals=min(tmp,NOT_FIXED_DEC);
+ if ((tmp= decimals - args[0]->decimals) > 0)
+ max_length+= tmp;
}
}
diff --git a/sql/lock.cc b/sql/lock.cc
index 8f1cd080db7..03541bb0810 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -82,7 +82,8 @@ static int unlock_external(THD *thd, TABLE **table,uint count);
static void print_lock_error(int error);
-MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
+MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
+ bool ignore_global_read_lock)
{
MYSQL_LOCK *sql_lock;
TABLE *write_lock_used;
@@ -93,7 +94,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
if (!(sql_lock = get_lock_data(thd,tables,count, 0,&write_lock_used)))
break;
- if (global_read_lock && write_lock_used)
+ if (global_read_lock && write_lock_used && ! ignore_global_read_lock)
{
/*
Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
@@ -911,3 +912,49 @@ void make_global_read_lock_block_commit(THD *thd)
pthread_mutex_unlock(&LOCK_open);
thd->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
}
+
+
+/*
+ Set protection against global read lock.
+
+ SYNOPSIS
+ set_protect_against_global_read_lock()
+ void
+
+ RETURN
+ FALSE OK, no global read lock exists.
+ TRUE Error, global read lock exists already.
+*/
+
+my_bool set_protect_against_global_read_lock(void)
+{
+ my_bool global_read_lock_exists;
+
+ pthread_mutex_lock(&LOCK_open);
+ if (! (global_read_lock_exists= test(global_read_lock)))
+ protect_against_global_read_lock++;
+ pthread_mutex_unlock(&LOCK_open);
+ return global_read_lock_exists;
+}
+
+
+/*
+ Unset protection against global read lock.
+
+ SYNOPSIS
+ unset_protect_against_global_read_lock()
+ void
+
+ RETURN
+ void
+*/
+
+void unset_protect_against_global_read_lock(void)
+{
+ pthread_mutex_lock(&LOCK_open);
+ protect_against_global_read_lock--;
+ pthread_mutex_unlock(&LOCK_open);
+ pthread_cond_broadcast(&COND_refresh);
+}
+
+
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index e75a6f25957..f5d4464ce68 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -975,7 +975,8 @@ extern pthread_t signal_thread;
extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd;
#endif /* HAVE_OPENSSL */
-MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **table,uint count);
+MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
+ bool ignore_global_read_lock= FALSE);
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count);
@@ -988,6 +989,8 @@ void unlock_global_read_lock(THD *thd);
bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, bool is_not_commit);
void start_waiting_global_read_lock(THD *thd);
void make_global_read_lock_block_commit(THD *thd);
+my_bool set_protect_against_global_read_lock(void);
+void unset_protect_against_global_read_lock(void);
/* Lock based on name */
int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list);
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 7f890a583c6..31393b2173a 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -851,27 +851,42 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
{
int error;
delayed_insert *tmp;
+ TABLE *table;
DBUG_ENTER("delayed_get_table");
if (!table_list->db)
table_list->db=thd->db;
- /* no match; create a new thread to handle the table */
+ /* Find the thread which handles this table. */
if (!(tmp=find_handler(thd,table_list)))
{
- /* Don't create more than max_insert_delayed_threads */
+ /*
+ No match. Create a new thread to handle the table, but
+ no more than max_insert_delayed_threads.
+ */
if (delayed_insert_threads >= thd->variables.max_insert_delayed_threads)
DBUG_RETURN(0);
thd->proc_info="Creating delayed handler";
pthread_mutex_lock(&LOCK_delayed_create);
- if (!(tmp=find_handler(thd,table_list))) // Was just created
+ /*
+ The first search above was done without LOCK_delayed_create.
+ Another thread might have created the handler in between. Search again.
+ */
+ if (! (tmp= find_handler(thd, table_list)))
{
+ /*
+ Avoid that a global read lock steps in while we are creating the
+ new thread. It would block trying to open the table. Hence, the
+ DI thread and this thread would wait until after the global
+ readlock is gone. If the read lock exists already, we leave with
+ no table and then switch to non-delayed insert.
+ */
+ if (set_protect_against_global_read_lock())
+ goto err;
if (!(tmp=new delayed_insert()))
{
- thd->fatal_error();
my_error(ER_OUTOFMEMORY,MYF(0),sizeof(delayed_insert));
- pthread_mutex_unlock(&LOCK_delayed_create);
- DBUG_RETURN(0);
+ goto err1;
}
pthread_mutex_lock(&LOCK_thread_count);
thread_count++;
@@ -880,10 +895,8 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
!(tmp->thd.query=my_strdup(table_list->real_name,MYF(MY_WME))))
{
delete tmp;
- thd->fatal_error();
my_error(ER_OUT_OF_RESOURCES,MYF(0));
- pthread_mutex_unlock(&LOCK_delayed_create);
- DBUG_RETURN(0);
+ goto err1;
}
tmp->table_list= *table_list; // Needed to open table
tmp->table_list.db= tmp->thd.db;
@@ -899,10 +912,8 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
pthread_mutex_unlock(&tmp->mutex);
tmp->unlock();
delete tmp;
- thd->fatal_error();
- pthread_mutex_unlock(&LOCK_delayed_create);
net_printf(thd,ER_CANT_CREATE_THREAD,error);
- DBUG_RETURN(0);
+ goto err1;
}
/* Wait until table is open */
@@ -912,6 +923,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
pthread_cond_wait(&tmp->cond_client,&tmp->mutex);
}
pthread_mutex_unlock(&tmp->mutex);
+ unset_protect_against_global_read_lock();
thd->proc_info="got old table";
if (tmp->thd.killed)
{
@@ -923,28 +935,34 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
thd->net.last_errno=tmp->thd.net.last_errno;
}
tmp->unlock();
- pthread_mutex_unlock(&LOCK_delayed_create);
- DBUG_RETURN(0); // Continue with normal insert
+ goto err;
}
if (thd->killed)
{
tmp->unlock();
- pthread_mutex_unlock(&LOCK_delayed_create);
- DBUG_RETURN(0);
+ goto err;
}
}
pthread_mutex_unlock(&LOCK_delayed_create);
}
pthread_mutex_lock(&tmp->mutex);
- TABLE *table=tmp->get_local_table(thd);
+ table=tmp->get_local_table(thd);
pthread_mutex_unlock(&tmp->mutex);
- tmp->unlock();
if (table)
thd->di=tmp;
else if (tmp->thd.is_fatal_error)
thd->fatal_error();
+ /* Unlock the delayed insert object after its last access. */
+ tmp->unlock();
DBUG_RETURN((table_list->table=table));
+
+ err1:
+ thd->fatal_error();
+ unset_protect_against_global_read_lock();
+ err:
+ pthread_mutex_unlock(&LOCK_delayed_create);
+ DBUG_RETURN(0); // Continue with normal insert
}
@@ -1165,6 +1183,14 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg)
thd->killed=abort_loop;
pthread_mutex_unlock(&LOCK_thread_count);
+ /*
+ Wait until the client runs into pthread_cond_wait(),
+ where we free it after the table is opened and di linked in the list.
+ If we did not wait here, the client might detect the opened table
+ before it is linked to the list. It would release LOCK_delayed_create
+ and allow another thread to create another handler for the same table,
+ since it does not find one in the list.
+ */
pthread_mutex_lock(&di->mutex);
#if !defined( __WIN__) && !defined(OS2) /* Win32 calls this in pthread_create */
if (my_thread_init())
@@ -1279,8 +1305,17 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg)
if (di->tables_in_use && ! thd->lock)
{
- /* request for new delayed insert */
- if (!(thd->lock=mysql_lock_tables(thd,&di->table,1)))
+ /*
+ Request for new delayed insert.
+ Lock the table, but avoid to be blocked by a global read lock.
+ If we got here while a global read lock exists, then one or more
+ inserts started before the lock was requested. These are allowed
+ to complete their work before the server returns control to the
+ client which requested the global read lock. The delayed insert
+ handler will close the table and finish when the outstanding
+ inserts are done.
+ */
+ if (! (thd->lock= mysql_lock_tables(thd, &di->table, 1, TRUE)))
{
di->dead= 1; // Some fatal error
thd->killed= 1;
diff --git a/sql/stacktrace.c b/sql/stacktrace.c
index 322d647e741..838f547dc02 100644
--- a/sql/stacktrace.c
+++ b/sql/stacktrace.c
@@ -43,7 +43,7 @@ void safe_print_str(const char* name, const char* val, int max_len)
fputc('\n', stderr);
}
-#ifdef HAVE_LINUXTHREADS
+#ifdef TARGET_OS_LINUX
#define SIGRETURN_FRAME_COUNT 2
#if defined(__alpha__) && defined(__GNUC__)
@@ -201,7 +201,7 @@ end:
stack trace is much more helpful in diagnosing the problem, so please do \n\
resolve it\n");
}
-#endif /* HAVE_LINUXTHREADS */
+#endif /* TARGET_OS_LINUX */
#endif /* HAVE_STACKTRACE */
/* Produce a core for the thread */
diff --git a/sql/stacktrace.h b/sql/stacktrace.h
index 980e1ea07eb..d5d1e05ef0e 100644
--- a/sql/stacktrace.h
+++ b/sql/stacktrace.h
@@ -18,7 +18,7 @@
extern "C" {
#endif
-#ifdef HAVE_LINUXTHREADS
+#ifdef TARGET_OS_LINUX
#if defined(HAVE_STACKTRACE) || (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__)))
#undef HAVE_STACKTRACE
#define HAVE_STACKTRACE
@@ -30,7 +30,7 @@ extern char* heap_start;
void print_stacktrace(gptr stack_bottom, ulong thread_stack);
void safe_print_str(const char* name, const char* val, int max_len);
#endif /* (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) */
-#endif /* HAVE_LINUXTHREADS */
+#endif /* TARGET_OS_LINUX */
/* Define empty prototypes for functions that are not implemented */
#ifndef HAVE_STACKTRACE
diff --git a/support-files/Makefile.am b/support-files/Makefile.am
index 0a6077f0efc..5f5a10fc1fc 100644
--- a/support-files/Makefile.am
+++ b/support-files/Makefile.am
@@ -90,7 +90,7 @@ SUFFIXES = .sh
-e 's!@''FIND_PROC''@!@FIND_PROC@!' \
-e 's!@''MYSQLD_DEFAULT_SWITCHES''@!@MYSQLD_DEFAULT_SWITCHES@!' \
-e 's!@''MYSQL_UNIX_ADDR''@!@MYSQL_UNIX_ADDR@!' \
- -e 's!@''IS_LINUX''@!@IS_LINUX@!' \
+ -e 's!@''TARGET_LINUX''@!@TARGET_LINUX@!' \
-e "s!@""CONF_COMMAND""@!@CONF_COMMAND@!" \
-e 's!@''MYSQLD_USER''@!@MYSQLD_USER@!' \
-e 's!@''sysconfdir''@!@sysconfdir@!' \
diff --git a/tools/mysqlmanager.c b/tools/mysqlmanager.c
index bb0a76d6c49..27caa1e0255 100644
--- a/tools/mysqlmanager.c
+++ b/tools/mysqlmanager.c
@@ -101,7 +101,7 @@ static CHARSET_INFO *cs= &my_charset_latin1;
set by the user
*/
-#if defined(__i386__) && defined(HAVE_LINUXTHREADS)
+#if defined(__i386__) && defined(TARGET_OS_LINUX)
#define DO_STACKTRACE 1
#endif