summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2011-02-28 19:39:30 +0200
committerMichael Widenius <monty@askmonty.org>2011-02-28 19:39:30 +0200
commit3358cdd5048671ee6cbbf50c291f7e0d0fda8e1e (patch)
treeda0e622896425203d23ecdfd1bc77b57e3502edf /mysys
parent869f5d0e81d5cbecaec3605f292fbb363b9ccbf6 (diff)
parentf83e594218a6d19da2fa1ea2a01d860c30fe2913 (diff)
downloadmariadb-git-3358cdd5048671ee6cbbf50c291f7e0d0fda8e1e.tar.gz
Merge with 5.1 to get in changes from MySQL 5.1.55
Diffstat (limited to 'mysys')
-rw-r--r--mysys/errors.c4
-rw-r--r--mysys/hash.c3
-rw-r--r--mysys/my_bitmap.c3
-rw-r--r--mysys/my_fopen.c138
-rw-r--r--mysys/my_getncpus.c2
-rw-r--r--mysys/my_getsystime.c11
-rw-r--r--mysys/my_seek.c1
-rw-r--r--mysys/my_symlink.c3
-rw-r--r--mysys/safemalloc.c6
-rw-r--r--mysys/stacktrace.c110
-rw-r--r--mysys/thr_lock.c8
-rw-r--r--mysys/thr_mutex.c20
-rw-r--r--mysys/thr_rwlock.c2
13 files changed, 278 insertions, 33 deletions
diff --git a/mysys/errors.c b/mysys/errors.c
index 4c568952ee3..33fb9ff7acd 100644
--- a/mysys/errors.c
+++ b/mysys/errors.c
@@ -52,8 +52,8 @@ const char * NEAR globerrs[GLOBERRS]=
"File '%s' (fileno: %d) was not closed",
"Can't change ownership of the file '%s' (Errcode: %d)",
"Can't change permissions of the file '%s' (Errcode: %d)",
+ "Can't seek in file '%s' (Errcode: %d)"
"Can't change mode for file '%s' to 0x%lx (Error: %d)",
- "Can't do seek on file '%s' (Errcode: %d)",
"Warning: Can't copy ownership for file '%s' (Error: %d)"
};
@@ -98,8 +98,8 @@ void init_glob_errs()
EE(EE_CHANGE_OWNERSHIP) = "Can't change ownership of the file '%s' (Errcode: %d)";
EE(EE_CHANGE_PERMISSIONS) = "Can't change permissions of the file '%s' (Errcode: %d)";
EE(EE_CANT_CHMOD) = "Can't change mode for file '%s' to 0x%lx (Error: %d)";
- EE(EE_CANT_SEEK) = "Can't do seek on file '%s' (Errcode: %d)";
EE(EE_CANT_COPY_OWNERSHIP)= "Warning: Can't copy ownership for file '%s' (Error: %d)";
+ EE(EE_CANT_SEEK) = "Can't seek in file '%s' (Errcode: %d)";
}
#endif
diff --git a/mysys/hash.c b/mysys/hash.c
index 0e22ddcf215..924f0ef418d 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -130,7 +130,8 @@ static inline void my_hash_free_elements(HASH *hash)
void my_hash_free(HASH *hash)
{
DBUG_ENTER("my_hash_free");
- DBUG_PRINT("enter",("hash: 0x%lx", (long) hash));
+ DBUG_PRINT("enter",("hash: 0x%lx elements: %ld",
+ (long) hash, hash->records));
my_hash_free_elements(hash);
hash->free= 0;
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index 0c3f45be374..c89aec67da8 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -274,7 +274,10 @@ void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size)
memset(m, 0xff, prefix_bytes);
m+= prefix_bytes;
if ((prefix_bits= prefix_size & 7))
+ {
*m++= (1 << prefix_bits)-1;
+ prefix_bytes++;
+ }
if ((d= no_bytes_in_map(map)-prefix_bytes))
bzero(m, d);
}
diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c
index 351851cca76..a4b0c9f895d 100644
--- a/mysys/my_fopen.c
+++ b/mysys/my_fopen.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 1985-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,6 +19,10 @@
#include <errno.h>
#include "mysys_err.h"
+#if defined(__FreeBSD__)
+extern int getosreldate(void);
+#endif
+
static void make_ftype(char * to,int flag);
/*
@@ -97,8 +102,137 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags)
} /* my_fopen */
- /* Close a stream */
+#if defined(_WIN32)
+
+static FILE *my_win_freopen(const char *path, const char *mode, FILE *stream)
+{
+ int handle_fd, fd= _fileno(stream);
+ HANDLE osfh;
+
+ DBUG_ASSERT(path && stream);
+
+ /* Services don't have stdout/stderr on Windows, so _fileno returns -1. */
+ if (fd < 0)
+ {
+ if (!freopen(path, mode, stream))
+ return NULL;
+
+ fd= _fileno(stream);
+ }
+
+ if ((osfh= CreateFile(path, GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE |
+ FILE_SHARE_DELETE, NULL,
+ OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,
+ NULL)) == INVALID_HANDLE_VALUE)
+ return NULL;
+
+ if ((handle_fd= _open_osfhandle((intptr_t)osfh,
+ _O_APPEND | _O_TEXT)) == -1)
+ {
+ CloseHandle(osfh);
+ return NULL;
+ }
+
+ if (_dup2(handle_fd, fd) < 0)
+ {
+ CloseHandle(osfh);
+ return NULL;
+ }
+
+ _close(handle_fd);
+
+ return stream;
+}
+
+#elif defined(__FreeBSD__)
+
+/* No close operation hook. */
+
+static int no_close(void *cookie __attribute__((unused)))
+{
+ return 0;
+}
+
+/*
+ A hack around a race condition in the implementation of freopen.
+
+ The race condition steams from the fact that the current fd of
+ the stream is closed before its number is used to duplicate the
+ new file descriptor. This defeats the desired atomicity of the
+ close and duplicate of dup2().
+
+ See PR number 79887 for reference:
+ http://www.freebsd.org/cgi/query-pr.cgi?pr=79887
+*/
+
+static FILE *my_freebsd_freopen(const char *path, const char *mode, FILE *stream)
+{
+ int old_fd;
+ FILE *result;
+
+ flockfile(stream);
+
+ old_fd= fileno(stream);
+
+ /* Use a no operation close hook to avoid having the fd closed. */
+ stream->_close= no_close;
+
+ /* Relies on the implicit dup2 to close old_fd. */
+ result= freopen(path, mode, stream);
+
+ /* If successful, the _close hook was replaced. */
+
+ if (result == NULL)
+ close(old_fd);
+ else
+ funlockfile(result);
+
+ return result;
+}
+
+#endif
+
+
+/**
+ Change the file associated with a file stream.
+
+ @param path Path to file.
+ @param mode Mode of the stream.
+ @param stream File stream.
+
+ @note
+ This function is used to redirect stdout and stderr to a file and
+ subsequently to close and reopen that file for log rotation.
+
+ @retval A FILE pointer on success. Otherwise, NULL.
+*/
+
+FILE *my_freopen(const char *path, const char *mode, FILE *stream)
+{
+ FILE *result;
+
+#if defined(_WIN32)
+ result= my_win_freopen(path, mode, stream);
+#elif defined(__FreeBSD__)
+ /*
+ XXX: Once the fix is ported to the stable releases, this should
+ be dependent upon the specific FreeBSD versions. Check at:
+ http://www.freebsd.org/cgi/query-pr.cgi?pr=79887
+ */
+ if (getosreldate() > 900027)
+ result= freopen(path, mode, stream);
+ else
+ result= my_freebsd_freopen(path, mode, stream);
+#else
+ result= freopen(path, mode, stream);
+#endif
+
+ return result;
+}
+
+/* Close a stream */
int my_fclose(FILE *fd, myf MyFlags)
{
int err,file;
diff --git a/mysys/my_getncpus.c b/mysys/my_getncpus.c
index 4cb96ac0bca..de176803b4d 100644
--- a/mysys/my_getncpus.c
+++ b/mysys/my_getncpus.c
@@ -33,7 +33,7 @@ int my_getncpus()
GetSystemInfo(&sysinfo);
ncpus= sysinfo.dwNumberOfProcessors;
#else
-/* unknown so play safe: assume SMP and forbid uniprocessor build */
+ /* unknown so play safe: assume SMP and forbid uniprocessor build */
ncpus= 2;
#endif
}
diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c
index 336d005d7d5..6bffcd65d30 100644
--- a/mysys/my_getsystime.c
+++ b/mysys/my_getsystime.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2004 MySQL AB
+/* Copyright (c) 2004, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2009-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -174,7 +175,13 @@ ulonglong my_micro_time_and_time(time_t *time_arg)
pthread_mutex_lock(&THR_LOCK_time);
cur_gethrtime= gethrtime();
- if ((cur_gethrtime - prev_gethrtime) > DELTA_FOR_SECONDS)
+ /*
+ Due to bugs in the Solaris (x86) implementation of gethrtime(),
+ the time returned by it might not be monotonic. Don't use the
+ cached time(2) value if this is a case.
+ */
+ if ((prev_gethrtime > cur_gethrtime) ||
+ ((cur_gethrtime - prev_gethrtime) > DELTA_FOR_SECONDS))
{
cur_time= time(0);
prev_gethrtime= cur_gethrtime;
diff --git a/mysys/my_seek.c b/mysys/my_seek.c
index 4ca5393e640..d186d56869a 100644
--- a/mysys/my_seek.c
+++ b/mysys/my_seek.c
@@ -101,6 +101,7 @@ my_off_t my_tell(File fd, myf MyFlags)
my_errno= errno;
if (MyFlags & MY_WME)
my_error(EE_CANT_SEEK, MYF(0), my_filename(fd), my_errno);
+ DBUG_PRINT("error", ("tell: %lu errno: %d", (ulong) pos, my_errno));
}
DBUG_PRINT("exit",("pos: %lu", (ulong) pos));
DBUG_RETURN((my_off_t) pos);
diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c
index 164533ad765..b001354275d 100644
--- a/mysys/my_symlink.c
+++ b/mysys/my_symlink.c
@@ -121,8 +121,7 @@ int my_is_symlink(const char *filename __attribute__((unused)))
(including the end \0)
*/
-int my_realpath(char *to, const char *filename,
- myf MyFlags __attribute__((unused)))
+int my_realpath(char *to, const char *filename, myf MyFlags)
{
#if defined(HAVE_REALPATH) && !defined(HAVE_BROKEN_REALPATH)
int result=0;
diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c
index 0e489263c69..deb6c73327e 100644
--- a/mysys/safemalloc.c
+++ b/mysys/safemalloc.c
@@ -60,7 +60,7 @@
*/
#ifndef SAFEMALLOC
-#define SAFEMALLOC /* Get protos from my_sys */
+#define SAFEMALLOC 1 /* Get protos from my_sys */
#endif
#include "mysys_priv.h"
@@ -124,7 +124,8 @@ void *_mymalloc(size_t size, const char *filename, uint lineno, myf MyFlags)
struct st_irem *irem;
uchar *data;
DBUG_ENTER("_mymalloc");
- DBUG_PRINT("enter",("Size: %lu", (ulong) size));
+ DBUG_PRINT("enter",("Size: %lu Total alloc: %lu", (ulong) size,
+ (ulong) sf_malloc_cur_memory));
if (!sf_malloc_quick)
(void) _sanity (filename, lineno);
@@ -320,6 +321,7 @@ void _myfree(void *ptr, const char *filename, uint lineno, myf myflags)
sf_malloc_cur_memory-= irem->datasize;
sf_malloc_count--;
pthread_mutex_unlock(&THR_LOCK_malloc);
+ DBUG_PRINT("info", ("bytes freed: %ld", (ulong) irem->datasize));
#ifndef HAVE_valgrind
/* Mark this data as free'ed */
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index 7bac8017324..93e8ae6b508 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -27,6 +27,11 @@
#include <unistd.h>
#include <strings.h>
+#ifdef __linux__
+#include <ctype.h> /* isprint */
+#include <sys/syscall.h> /* SYS_gettid */
+#endif
+
#if HAVE_EXECINFO_H
#include <execinfo.h>
#endif
@@ -46,10 +51,99 @@ void my_init_stacktrace()
#endif
}
-void my_safe_print_str(const char* name, const char* val, int max_len)
+#ifdef __linux__
+
+static void print_buffer(char *buffer, size_t count)
+{
+ for (; count && *buffer; --count)
+ {
+ int c= (int) *buffer++;
+ fputc(isprint(c) ? c : ' ', stderr);
+ }
+}
+
+/**
+ Access the pages of this process through /proc/self/task/<tid>/mem
+ in order to safely print the contents of a memory address range.
+
+ @param addr The address at the start of the memory region.
+ @param max_len The length of the memory region.
+
+ @return Zero on success.
+*/
+static int safe_print_str(const char *addr, int max_len)
{
- char *heap_end= (char*) sbrk(0);
- fprintf(stderr, "%s at %p ", name, val);
+ int fd;
+ pid_t tid;
+ off_t offset;
+ ssize_t nbytes= 0;
+ size_t total, count;
+ char buf[256];
+
+ tid= (pid_t) syscall(SYS_gettid);
+
+ sprintf(buf, "/proc/self/task/%d/mem", tid);
+
+ if ((fd= open(buf, O_RDONLY)) < 0)
+ return -1;
+
+ /* Ensure that off_t can hold a pointer. */
+ compile_time_assert(sizeof(off_t) >= sizeof(intptr));
+
+ total= max_len;
+ offset= (intptr) addr;
+
+ /* Read up to the maximum number of bytes. */
+ while (total)
+ {
+ count= min(sizeof(buf), total);
+
+ if ((nbytes= pread(fd, buf, count, offset)) < 0)
+ {
+ /* Just in case... */
+ if (errno == EINTR)
+ continue;
+ else
+ break;
+ }
+
+ /* Advance offset into memory. */
+ total-= nbytes;
+ offset+= nbytes;
+ addr+= nbytes;
+
+ /* Output the printable characters. */
+ print_buffer(buf, nbytes);
+
+ /* Break if less than requested... */
+ if ((count - nbytes))
+ break;
+ }
+
+ /* Output a new line if something was printed. */
+ if (total != (size_t) max_len)
+ fputc('\n', stderr);
+
+ if (nbytes == -1)
+ fprintf(stderr, "Can't read from address %p: %m.\n", addr);
+
+ close(fd);
+
+ return 0;
+}
+
+#endif
+
+void my_safe_print_str(const char* val, int max_len)
+{
+ char *heap_end;
+
+#ifdef __linux__
+ if (!safe_print_str(val, max_len))
+ return;
+#endif
+
+ heap_end= (char*) sbrk(0);
if (!PTR_SANE(val))
{
@@ -57,7 +151,6 @@ void my_safe_print_str(const char* name, const char* val, int max_len)
return;
}
- fprintf(stderr, "= ");
for (; max_len && PTR_SANE(val) && *val; --max_len)
fputc(*val++, stderr);
fputc('\n', stderr);
@@ -318,6 +411,9 @@ end:
/* Produce a core for the thread */
void my_write_core(int sig)
{
+#ifdef HAVE_gcov
+ extern void __gcov_flush(void);
+#endif
signal(sig, SIG_DFL);
#ifdef HAVE_gcov
/*
@@ -325,7 +421,6 @@ void my_write_core(int sig)
information from this process, causing gcov output to be incomplete.
So we force the writing of coverage information here before terminating.
*/
- extern void __gcov_flush(void);
__gcov_flush();
#endif
pthread_kill(pthread_self(), sig);
@@ -655,10 +750,9 @@ void my_write_core(int unused)
}
-void my_safe_print_str(const char *name, const char *val, int len)
+void my_safe_print_str(const char *val, int len)
{
- fprintf(stderr,"%s at %p", name, val);
- __try
+ __try
{
fprintf(stderr,"=%.*s\n", len, val);
}
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index 68a3caf6da7..f7908ab57bc 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -182,8 +182,10 @@ static int check_lock(struct st_lock_list *list, const char* lock_type,
last_lock_type != TL_WRITE_CONCURRENT_INSERT)
{
fprintf(stderr,
- "Warning: Found locks from different threads in %s at '%s'. org_lock_type: %d last_lock_type: %d new_lock_type: %d\n",
- lock_type, where, list->data->type, last_lock_type, data->type);
+ "Warning: Found locks from different threads for lock '%s' in '%s' at '%s'. org_lock_type: %d last_lock_type: %d new_lock_type: %d\n",
+ data->lock->name ? data->lock->name : "",
+ lock_type, where, list->data->type, last_lock_type,
+ data->type);
return 1;
}
if (no_cond && data->cond)
@@ -405,6 +407,7 @@ void thr_lock_data_init(THR_LOCK *lock,THR_LOCK_DATA *data, void *param)
data->status_param=param;
data->cond=0;
data->priority= 0;
+ data->debug_print_param= 0;
}
@@ -879,6 +882,7 @@ void thr_unlock(THR_LOCK_DATA *data, uint unlock_flags)
data->type=TL_UNLOCK; /* Mark unlocked */
check_locks(lock,"after releasing lock",1);
wake_up_waiters(lock);
+ check_locks(lock,"end of thr_unlock",1);
pthread_mutex_unlock(&lock->mutex);
DBUG_VOID_RETURN;
}
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index 77f2286b3d1..9421a3b2d98 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -170,16 +170,16 @@ static int safe_mutex_lazy_init_deadlock_detection(safe_mutex_t *mp)
pthread_mutex_lock(&THR_LOCK_mutex);
mp->id= ++safe_mutex_id;
pthread_mutex_unlock(&THR_LOCK_mutex);
- hash_init(mp->locked_mutex, &my_charset_bin,
- 1000,
- offsetof(safe_mutex_deadlock_t, id),
- sizeof(mp->id),
- 0, 0, HASH_UNIQUE);
- hash_init(mp->used_mutex, &my_charset_bin,
- 1000,
- offsetof(safe_mutex_t, id),
- sizeof(mp->id),
- 0, 0, HASH_UNIQUE);
+ hash_init2(mp->locked_mutex, 64, &my_charset_bin,
+ 128,
+ offsetof(safe_mutex_deadlock_t, id),
+ sizeof(mp->id),
+ 0, 0, HASH_UNIQUE);
+ hash_init2(mp->used_mutex, 64, &my_charset_bin,
+ 128,
+ offsetof(safe_mutex_t, id),
+ sizeof(mp->id),
+ 0, 0, HASH_UNIQUE);
return 0;
}
diff --git a/mysys/thr_rwlock.c b/mysys/thr_rwlock.c
index 280a0ec19e7..ea98a854a4d 100644
--- a/mysys/thr_rwlock.c
+++ b/mysys/thr_rwlock.c
@@ -29,7 +29,7 @@
* Multithreaded Demo Source
*
* Copyright (C) 1995 by Sun Microsystems, Inc.
-* All rights reserved.
+*
*
* This file is a product of SunSoft, Inc. and is provided for
* unrestricted use provided that this legend is included on all