diff options
author | Michael Widenius <monty@askmonty.org> | 2011-02-28 19:39:30 +0200 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2011-02-28 19:39:30 +0200 |
commit | 3358cdd5048671ee6cbbf50c291f7e0d0fda8e1e (patch) | |
tree | da0e622896425203d23ecdfd1bc77b57e3502edf /mysys | |
parent | 869f5d0e81d5cbecaec3605f292fbb363b9ccbf6 (diff) | |
parent | f83e594218a6d19da2fa1ea2a01d860c30fe2913 (diff) | |
download | mariadb-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.c | 4 | ||||
-rw-r--r-- | mysys/hash.c | 3 | ||||
-rw-r--r-- | mysys/my_bitmap.c | 3 | ||||
-rw-r--r-- | mysys/my_fopen.c | 138 | ||||
-rw-r--r-- | mysys/my_getncpus.c | 2 | ||||
-rw-r--r-- | mysys/my_getsystime.c | 11 | ||||
-rw-r--r-- | mysys/my_seek.c | 1 | ||||
-rw-r--r-- | mysys/my_symlink.c | 3 | ||||
-rw-r--r-- | mysys/safemalloc.c | 6 | ||||
-rw-r--r-- | mysys/stacktrace.c | 110 | ||||
-rw-r--r-- | mysys/thr_lock.c | 8 | ||||
-rw-r--r-- | mysys/thr_mutex.c | 20 | ||||
-rw-r--r-- | mysys/thr_rwlock.c | 2 |
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 |