diff options
Diffstat (limited to 'mysys')
-rwxr-xr-x | mysys/CMakeLists.txt | 2 | ||||
-rw-r--r-- | mysys/Makefile.am | 2 | ||||
-rw-r--r-- | mysys/default.c | 176 | ||||
-rw-r--r-- | mysys/mf_arr_appstr.c | 61 | ||||
-rw-r--r-- | mysys/mf_keycache.c | 2 | ||||
-rw-r--r-- | mysys/mf_qsort.c | 4 | ||||
-rw-r--r-- | mysys/mf_sort.c | 4 | ||||
-rw-r--r-- | mysys/my_delete.c | 10 | ||||
-rw-r--r-- | mysys/my_getopt.c | 159 | ||||
-rw-r--r-- | mysys/my_lib.c | 4 | ||||
-rw-r--r-- | mysys/my_write.c | 4 | ||||
-rw-r--r-- | mysys/queues.c | 38 | ||||
-rw-r--r-- | mysys/thr_lock.c | 33 |
13 files changed, 361 insertions, 138 deletions
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index 6b24165686a..60e75c96b75 100755 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -29,7 +29,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_ errors.c hash.c list.c md5.c mf_brkhant.c mf_cache.c mf_dirname.c mf_fn_ext.c mf_format.c mf_getdate.c mf_iocache.c mf_iocache2.c mf_keycache.c mf_keycaches.c mf_loadpath.c mf_pack.c mf_path.c mf_qsort.c mf_qsort2.c - mf_radix.c mf_same.c mf_sort.c mf_soundex.c mf_strip.c mf_tempdir.c + mf_radix.c mf_same.c mf_sort.c mf_soundex.c mf_strip.c mf_arr_appstr.c mf_tempdir.c mf_tempfile.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_access.c my_aes.c my_alarm.c my_alloc.c my_append.c my_bit.c my_bitmap.c my_chsize.c my_clock.c my_compress.c my_conio.c my_copy.c my_crc32.c my_create.c my_delete.c diff --git a/mysys/Makefile.am b/mysys/Makefile.am index fca13ab52b8..f06d81da849 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -35,7 +35,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ my_error.c errors.c my_div.c my_messnc.c \ mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \ my_symlink.c my_symlink2.c \ - mf_pack.c mf_unixpath.c mf_strip.c \ + mf_pack.c mf_unixpath.c mf_strip.c mf_arr_appstr.c \ mf_wcomp.c mf_wfile.c my_gethwaddr.c \ mf_qsort.c mf_qsort2.c mf_sort.c \ ptr_cmp.c mf_radix.c queues.c my_getncpus.c \ diff --git a/mysys/default.c b/mysys/default.c index 3cc5b08e77c..2758029ec12 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -47,7 +47,7 @@ char *my_defaults_extra_file=0; /* Which directories are searched for options (and in which order) */ -#define MAX_DEFAULT_DIRS 7 +#define MAX_DEFAULT_DIRS 6 const char *default_directories[MAX_DEFAULT_DIRS + 1]; #ifdef __WIN__ @@ -83,7 +83,22 @@ static int search_default_file_with_ext(Process_option_func func, void *func_ctx, const char *dir, const char *ext, const char *config_file, int recursion_level); -static void init_default_directories(); + + + +/** + Create the list of default directories. + + @details + On all systems, if a directory is already in the list, it will be moved + to the end of the list. This avoids reading defaults files multiple times, + while ensuring the correct precedence. + + @return void +*/ + +static void (*init_default_directories)(); + static char *remove_end_comment(char *ptr); @@ -922,6 +937,34 @@ void print_defaults(const char *conf_file, const char **groups) #include <help_end.h> +/* + This extra complexity is to avoid declaring 'rc' if it won't be + used. +*/ +#define ADD_DIRECTORY_INTERNAL(DIR) \ + array_append_string_unique((DIR), default_directories, \ + array_elements(default_directories)) +#ifdef DBUG_OFF +# define ADD_DIRECTORY(DIR) (void) ADD_DIRECTORY_INTERNAL(DIR) +#else +#define ADD_DIRECTORY(DIR) \ + do { \ + my_bool rc= ADD_DIRECTORY_INTERNAL(DIR); \ + DBUG_ASSERT(rc == FALSE); /* Success */ \ + } while (0) +#endif + + +#define ADD_COMMON_DIRECTORIES() \ + do { \ + char *env; \ + if ((env= getenv(STRINGIFY_ARG(DEFAULT_HOME_ENV)))) \ + ADD_DIRECTORY(env); \ + /* Placeholder for --defaults-extra-file=<path> */ \ + ADD_DIRECTORY(""); \ + } while (0) + + #ifdef __WIN__ /* This wrapper for GetSystemWindowsDirectory() will dynamically bind to the @@ -956,71 +999,33 @@ static size_t my_get_system_windows_directory(char *buffer, size_t size) } return count; } -#endif -/* - Create the list of default directories. +/** + Initialize default directories for Microsoft Windows - On Microsoft Windows, this is: - 1. C:/ + @details + 1. GetSystemWindowsDirectory() 2. GetWindowsDirectory() - 3. GetSystemWindowsDirectory() - 4. getenv(DEFAULT_HOME_ENV) - 5. Directory above where the executable is located - 6. "" - 7. --sysconfdir=<path> - - On Novell NetWare, this is: - 1. sys:/etc/ - 2. getenv(DEFAULT_HOME_ENV) - 3. "" - 4. --sysconfdir=<path> - - On OS/2, this is: - 1. getenv(ETC) - 2. /etc/ - 3. getenv(DEFAULT_HOME_ENV) - 4. "" - 5. "~/" - 6. --sysconfdir=<path> - - Everywhere else, this is: - 1. /etc/ - 2. /etc/mysql/ - 3. getenv(DEFAULT_HOME_ENV) - 4. "" - 5. "~/" - 6. --sysconfdir=<path> - - */ + 3. C:/ + 4. Directory above where the executable is located + 5. getenv(DEFAULT_HOME_ENV) + 6. --defaults-extra-file=<path> (run-time option) +*/ -static void init_default_directories() +static void init_default_directories_win() { - const char *env, **ptr= default_directories; + bzero((char *) default_directories, sizeof(default_directories)); -#ifdef __WIN__ - *ptr++= "C:/"; + if (my_get_system_windows_directory(shared_system_dir, + sizeof(shared_system_dir))) + ADD_DIRECTORY(shared_system_dir); if (GetWindowsDirectory(system_dir,sizeof(system_dir))) - *ptr++= (char*)&system_dir; - if (my_get_system_windows_directory(shared_system_dir, - sizeof(shared_system_dir)) && - strcmp(system_dir, shared_system_dir)) - *ptr++= (char *)&shared_system_dir; + ADD_DIRECTORY(system_dir); + + ADD_DIRECTORY("C:/"); -#elif defined(__NETWARE__) - *ptr++= "sys:/etc/"; -#else - *ptr++= "/etc/"; - *ptr++= "/etc/mysql/"; -#endif - if ((env= getenv(STRINGIFY_ARG(DEFAULT_HOME_ENV)))) - *ptr++= env; - *ptr++= ""; /* Place for defaults_extra_file */ -#if !defined(__WIN__) && !defined(__NETWARE__) - *ptr++= "~/";; -#elif defined(__WIN__) if (GetModuleFileName(NULL, config_dir, sizeof(config_dir))) { char *last= NULL, *end= strend(config_dir); @@ -1050,12 +1055,61 @@ static void init_default_directories() last= end; } } - *ptr++= (char *)&config_dir; + ADD_DIRECTORY(config_dir); } -#endif + + ADD_COMMON_DIRECTORIES(); +} + +static void (*init_default_directories)()= init_default_directories_win; + +#elif defined(__NETWARE__) + +/** + Initialize default directories for Novell Netware + + @details + 1. sys:/etc/ + 2. getenv(DEFAULT_HOME_ENV) + 3. --defaults-extra-file=<path> (run-time option) +*/ + +static void init_default_directories_netware() +{ + bzero((char *) default_directories, sizeof(default_directories)); + ADD_DIRECTORY("sys:/etc/"); + ADD_COMMON_DIRECTORIES(); +} + +static void (*init_default_directories)()= init_default_directories_netware; + +#else + +/** + Initialize default directories for Unix + + @details + 1. /etc/ + 2. /etc/mysql/ + 3. --sysconfdir=<path> (compile-time option) + 4. getenv(DEFAULT_HOME_ENV) + 5. --defaults-extra-file=<path> (run-time option) + 6. "~/" +*/ + +static void init_default_directories_unix() +{ + bzero((char *) default_directories, sizeof(default_directories)); + ADD_DIRECTORY("/etc/"); + ADD_DIRECTORY("/etc/mysql/"); #ifdef DEFAULT_SYSCONFDIR if (DEFAULT_SYSCONFDIR != "") - *ptr++= DEFAULT_SYSCONFDIR; + ADD_DIRECTORY(DEFAULT_SYSCONFDIR); #endif - *ptr= 0; /* end marker */ + ADD_COMMON_DIRECTORIES(); + ADD_DIRECTORY("~/"); } + +static void (*init_default_directories)()= init_default_directories_unix; + +#endif diff --git a/mysys/mf_arr_appstr.c b/mysys/mf_arr_appstr.c new file mode 100644 index 00000000000..1edbea9df4a --- /dev/null +++ b/mysys/mf_arr_appstr.c @@ -0,0 +1,61 @@ +/* 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 */ + +#include "mysys_priv.h" +#include <m_string.h> /* strcmp() */ + + +/** + Append str to array, or move to the end if it already exists + + @param str String to be appended + @param array The array, terminated by a NULL element, all unused elements + pre-initialized to NULL + @param size Size of the array; array must be terminated by a NULL + pointer, so can hold size - 1 elements + + @retval FALSE Success + @retval TRUE Failure, array is full +*/ + +my_bool array_append_string_unique(const char *str, + const char **array, size_t size) +{ + const char **p; + /* end points at the terminating NULL element */ + const char **end= array + size - 1; + DBUG_ASSERT(*end == NULL); + + for (p= array; *p; ++p) + { + if (strcmp(*p, str) == 0) + break; + } + if (p >= end) + return TRUE; /* Array is full */ + + DBUG_ASSERT(*p == NULL || strcmp(*p, str) == 0); + + while (*(p + 1)) + { + *p= *(p + 1); + ++p; + } + + DBUG_ASSERT(p < end); + *p= str; + + return FALSE; /* Success */ +} diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index c81da9a469a..a03d71f32d8 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -3429,7 +3429,7 @@ static int flush_cached_blocks(KEY_CACHE *keycache, As all blocks referred in 'cache' are marked by BLOCK_IN_FLUSH we are guarunteed no thread will change them */ - qsort((uchar*) cache, count, sizeof(*cache), (qsort_cmp) cmp_sec_link); + my_qsort((uchar*) cache, count, sizeof(*cache), (qsort_cmp) cmp_sec_link); keycache_pthread_mutex_lock(&keycache->cache_lock); /* diff --git a/mysys/mf_qsort.c b/mysys/mf_qsort.c index 3d52d56c952..4b3ecb603a6 100644 --- a/mysys/mf_qsort.c +++ b/mysys/mf_qsort.c @@ -91,10 +91,10 @@ typedef struct st_stack *****************************************************************************/ #ifdef QSORT_EXTRA_CMP_ARGUMENT -qsort_t qsort2(void *base_ptr, size_t count, size_t size, qsort2_cmp cmp, +qsort_t my_qsort2(void *base_ptr, size_t count, size_t size, qsort2_cmp cmp, void *cmp_argument) #else -qsort_t qsort(void *base_ptr, size_t count, size_t size, qsort_cmp cmp) +qsort_t my_qsort(void *base_ptr, size_t count, size_t size, qsort_cmp cmp) #endif { char *low, *high, *pivot; diff --git a/mysys/mf_sort.c b/mysys/mf_sort.c index 741c8f42327..686ebbc1d14 100644 --- a/mysys/mf_sort.c +++ b/mysys/mf_sort.c @@ -34,8 +34,8 @@ void my_string_ptr_sort(uchar *base, uint items, size_t size) { if (size && items) { - qsort2(base,items, sizeof(uchar*), get_ptr_compare(size), - (void*) &size); + my_qsort2(base,items, sizeof(uchar*), get_ptr_compare(size), + (void*) &size); } } } diff --git a/mysys/my_delete.c b/mysys/my_delete.c index bac3e2513e1..cff00bf7e08 100644 --- a/mysys/my_delete.c +++ b/mysys/my_delete.c @@ -56,16 +56,20 @@ int nt_share_delete(const char *name, myf MyFlags) ulong cnt; DBUG_ENTER("nt_share_delete"); DBUG_PRINT("my",("name %s MyFlags %d", name, MyFlags)); - + for (cnt= GetTickCount(); cnt; cnt--) { sprintf(buf, "%s.%08X.deleted", name, cnt); if (MoveFile(name, buf)) break; - + if ((errno= GetLastError()) == ERROR_ALREADY_EXISTS) continue; - + + /* This happened during tests with MERGE tables. */ + if (errno == ERROR_ACCESS_DENIED) + continue; + DBUG_PRINT("warning", ("Failed to rename %s to %s, errno: %d", name, buf, errno)); break; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 3aad6152dfd..5132ac820b8 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -86,6 +86,7 @@ static void default_reporter(enum loglevel level, fprintf(stderr, "%s", "Info: "); vfprintf(stderr, format, args); va_end(args); + fputc('\n', stderr); fflush(stderr); } @@ -153,7 +154,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: Option '-O' requires an argument\n", + "%s: Option '-O' requires an argument", my_progname); return EXIT_ARGUMENT_REQUIRED; } @@ -171,7 +172,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: Option '--set-variable' requires an argument\n", + "%s: Option '--set-variable' requires an argument", my_progname); return EXIT_ARGUMENT_REQUIRED; } @@ -185,7 +186,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: Option '--set-variable' requires an argument\n", + "%s: Option '--set-variable' requires an argument", my_progname); return EXIT_ARGUMENT_REQUIRED; } @@ -247,7 +248,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: ambiguous option '--%s-%s' (--%s-%s)\n", + "%s: ambiguous option '--%s-%s' (--%s-%s)", my_progname, special_opt_prefix[i], cur_arg, special_opt_prefix[i], prev_found); @@ -298,7 +299,7 @@ int handle_options(int *argc, char ***argv, if (my_getopt_print_errors) my_getopt_error_reporter(option_is_loose ? WARNING_LEVEL : ERROR_LEVEL, - "%s: unknown variable '%s'\n", + "%s: unknown variable '%s'", my_progname, cur_arg); if (!option_is_loose) return EXIT_UNKNOWN_VARIABLE; @@ -308,7 +309,7 @@ int handle_options(int *argc, char ***argv, if (my_getopt_print_errors) my_getopt_error_reporter(option_is_loose ? WARNING_LEVEL : ERROR_LEVEL, - "%s: unknown option '--%s'\n", + "%s: unknown option '--%s'", my_progname, cur_arg); if (!option_is_loose) return EXIT_UNKNOWN_OPTION; @@ -326,7 +327,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: variable prefix '%s' is not unique\n", + "%s: variable prefix '%s' is not unique", my_progname, opt_str); return EXIT_VAR_PREFIX_NOT_UNIQUE; } @@ -334,7 +335,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: ambiguous option '--%s' (%s, %s)\n", + "%s: ambiguous option '--%s' (%s, %s)", my_progname, opt_str, prev_found, optp->name); return EXIT_AMBIGUOUS_OPTION; @@ -357,7 +358,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: option '%s' cannot take an argument\n", + "%s: option '%s' cannot take an argument", my_progname, optp->name); return EXIT_NO_ARGUMENT_ALLOWED; } @@ -370,7 +371,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: option '--%s' cannot take an argument\n", + "%s: option '--%s' cannot take an argument", my_progname, optp->name); return EXIT_NO_ARGUMENT_ALLOWED; } @@ -392,7 +393,7 @@ int handle_options(int *argc, char ***argv, { my_getopt_error_reporter(WARNING_LEVEL, "%s: ignoring option '--%s' due to \ -invalid value '%s'\n", +invalid value '%s'", my_progname, optp->name, optend); continue; } @@ -423,7 +424,7 @@ invalid value '%s'\n", { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: option '--%s' requires an argument\n", + "%s: option '--%s' requires an argument", my_progname, optp->name); return EXIT_ARGUMENT_REQUIRED; } @@ -483,7 +484,7 @@ invalid value '%s'\n", { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: option '-%c' requires an argument\n", + "%s: option '-%c' requires an argument", my_progname, optp->id); return EXIT_ARGUMENT_REQUIRED; } @@ -496,7 +497,7 @@ invalid value '%s'\n", set_maximum_value))) { my_getopt_error_reporter(ERROR_LEVEL, - "%s: Error while setting value '%s' to '%s'\n", + "%s: Error while setting value '%s' to '%s'", my_progname, argument, optp->name); return error; } @@ -508,7 +509,7 @@ invalid value '%s'\n", { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: unknown option '-%c'\n", + "%s: unknown option '-%c'", my_progname, *optend); return EXIT_UNKNOWN_OPTION; } @@ -519,7 +520,7 @@ invalid value '%s'\n", if ((error= setval(optp, value, argument, set_maximum_value))) { my_getopt_error_reporter(ERROR_LEVEL, - "%s: Error while setting value '%s' to '%s'\n", + "%s: Error while setting value '%s' to '%s'", my_progname, argument, optp->name); return error; } @@ -608,13 +609,17 @@ static int setval(const struct my_option *opts, uchar* *value, char *argument, *((my_bool*) result_pos)= (my_bool) atoi(argument) != 0; break; case GET_INT: - case GET_UINT: /* fall through */ *((int*) result_pos)= (int) getopt_ll(argument, opts, &err); break; + case GET_UINT: + *((uint*) result_pos)= (uint) getopt_ull(argument, opts, &err); + break; case GET_LONG: - case GET_ULONG: /* fall through */ *((long*) result_pos)= (long) getopt_ll(argument, opts, &err); break; + case GET_ULONG: + *((long*) result_pos)= (long) getopt_ull(argument, opts, &err); + break; case GET_LL: *((longlong*) result_pos)= getopt_ll(argument, opts, &err); break; @@ -778,23 +783,70 @@ static longlong eval_num_suffix(char *argument, int *error, char *option_name) static longlong getopt_ll(char *arg, const struct my_option *optp, int *err) { - longlong num; + longlong num=eval_num_suffix(arg, err, (char*) optp->name); + return getopt_ll_limit_value(num, optp, NULL); +} + +/* + function: getopt_ll_limit_value + + Applies min/max/block_size to a numeric value of an option. + Returns "fixed" value. +*/ + +longlong getopt_ll_limit_value(longlong num, const struct my_option *optp, + bool *fix) +{ + longlong old= num; + bool adjusted= FALSE; + char buf1[255], buf2[255]; ulonglong block_size= (optp->block_size ? (ulonglong) optp->block_size : 1L); - - num= eval_num_suffix(arg, err, (char*) optp->name); - if (num > 0 && (ulonglong) num > (ulonglong) optp->max_value && + + if (num > 0 && ((ulonglong) num > (ulonglong) optp->max_value) && optp->max_value) /* if max value is not set -> no upper limit */ { - char buf[22]; - my_getopt_error_reporter(WARNING_LEVEL, - "Truncated incorrect %s value: '%s'", - optp->name, llstr(num, buf)); - num= (ulonglong) optp->max_value; + adjusted= TRUE; } + + switch ((optp->var_type & GET_TYPE_MASK)) { + case GET_INT: + if (num > (longlong) INT_MAX) + { + num= ((longlong) INT_MAX); + adjusted= TRUE; + } + break; + case GET_LONG: +#if SIZEOF_LONG < SIZEOF_LONG_LONG + if (num > (longlong) LONG_MAX) + { + num= ((longlong) LONG_MAX); + adjusted= TRUE; + } +#endif + break; + default: + DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_LL); + break; + } + num= ((num - optp->sub_size) / block_size); num= (longlong) (num * block_size); - return max(num, optp->min_value); + + if (num < optp->min_value) + { + num= optp->min_value; + adjusted= TRUE; + } + + if (fix) + *fix= adjusted; + else if (adjusted) + my_getopt_error_reporter(WARNING_LEVEL, + "option '%s': signed value %s adjusted to %s", + optp->name, llstr(old, buf1), llstr(num, buf2)); + return num; } /* @@ -806,25 +858,66 @@ static longlong getopt_ll(char *arg, const struct my_option *optp, int *err) static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err) { - ulonglong num; - - num= eval_num_suffix(arg, err, (char*) optp->name); - return getopt_ull_limit_value(num, optp); + ulonglong num= eval_num_suffix(arg, err, (char*) optp->name); + return getopt_ull_limit_value(num, optp, NULL); } -ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp) +ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp, + bool *fix) { + bool adjusted= FALSE; + ulonglong old= num; + char buf1[255], buf2[255]; + if ((ulonglong) num > (ulonglong) optp->max_value && optp->max_value) /* if max value is not set -> no upper limit */ + { num= (ulonglong) optp->max_value; + adjusted= TRUE; + } + + switch ((optp->var_type & GET_TYPE_MASK)) { + case GET_UINT: + if (num > (ulonglong) UINT_MAX) + { + num= ((ulonglong) UINT_MAX); + adjusted= TRUE; + } + break; + case GET_ULONG: +#if SIZEOF_LONG < SIZEOF_LONG_LONG + if (num > (ulonglong) ULONG_MAX) + { + num= ((ulonglong) ULONG_MAX); + adjusted= TRUE; + } +#endif + break; + default: + DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_ULL); + break; + } + if (optp->block_size > 1) { num/= (ulonglong) optp->block_size; num*= (ulonglong) optp->block_size; } + if (num < (ulonglong) optp->min_value) + { num= (ulonglong) optp->min_value; + adjusted= TRUE; + } + + if (fix) + *fix= adjusted; + else if (adjusted) + my_getopt_error_reporter(WARNING_LEVEL, + "option '%s': unsigned value %s adjusted to %s", + optp->name, ullstr(old, buf1), ullstr(num, buf2)); + return num; } diff --git a/mysys/my_lib.c b/mysys/my_lib.c index c10b2e391b4..c18d14fb549 100644 --- a/mysys/my_lib.c +++ b/mysys/my_lib.c @@ -180,7 +180,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags) result->number_off_files= dir_entries_storage->elements; if (!(MyFlags & MY_DONT_SORT)) - qsort((void *) result->dir_entry, result->number_off_files, + my_qsort((void *) result->dir_entry, result->number_off_files, sizeof(FILEINFO), (qsort_cmp) comp_names); DBUG_RETURN(result); @@ -491,7 +491,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags) result->number_off_files= dir_entries_storage->elements; if (!(MyFlags & MY_DONT_SORT)) - qsort((void *) result->dir_entry, result->number_off_files, + my_qsort((void *) result->dir_entry, result->number_off_files, sizeof(FILEINFO), (qsort_cmp) comp_names); DBUG_PRINT("exit", ("found %d files", result->number_off_files)); DBUG_RETURN(result); diff --git a/mysys/my_write.c b/mysys/my_write.c index 056a84f1794..c67b1d8f3f2 100644 --- a/mysys/my_write.c +++ b/mysys/my_write.c @@ -29,6 +29,10 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags) Filedes, (long) Buffer, (ulong) Count, MyFlags)); errors=0; written=0; + /* The behavior of write(fd, buf, 0) is not portable */ + if (unlikely(!Count)) + DBUG_RETURN(0); + for (;;) { if ((writenbytes= write(Filedes, Buffer, Count)) == Count) diff --git a/mysys/queues.c b/mysys/queues.c index d8a7ca19bee..94f49ab8f9c 100644 --- a/mysys/queues.c +++ b/mysys/queues.c @@ -61,7 +61,7 @@ int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key, queue->first_cmp_arg=first_cmp_arg; queue->max_elements=max_elements; queue->offset_to_key=offset_to_key; - queue->max_at_top= max_at_top ? (-1 ^ 1) : 0; + queue_set_max_at_top(queue, max_at_top); DBUG_RETURN(0); } @@ -137,7 +137,7 @@ int reinit_queue(QUEUE *queue, uint max_elements, uint offset_to_key, queue->compare=compare; queue->first_cmp_arg=first_cmp_arg; queue->offset_to_key=offset_to_key; - queue->max_at_top= max_at_top ? (-1 ^ 1) : 0; + queue_set_max_at_top(queue, max_at_top); resize_queue(queue, max_elements); DBUG_RETURN(0); } @@ -208,16 +208,14 @@ void delete_queue(QUEUE *queue) void queue_insert(register QUEUE *queue, uchar *element) { reg2 uint idx, next; - int cmp; DBUG_ASSERT(queue->elements < queue->max_elements); queue->root[0]= element; idx= ++queue->elements; /* max_at_top swaps the comparison if we want to order by desc */ - while ((cmp= queue->compare(queue->first_cmp_arg, - element + queue->offset_to_key, - queue->root[(next= idx >> 1)] + - queue->offset_to_key)) && - (cmp ^ queue->max_at_top) < 0) + while ((queue->compare(queue->first_cmp_arg, + element + queue->offset_to_key, + queue->root[(next= idx >> 1)] + + queue->offset_to_key) * queue->max_at_top) < 0) { queue->root[idx]= queue->root[next]; idx= next; @@ -287,19 +285,17 @@ void _downheap(register QUEUE *queue, uint idx) while (idx <= half_queue) { - int cmp; next_index=idx+idx; if (next_index < elements && (queue->compare(queue->first_cmp_arg, queue->root[next_index]+offset_to_key, - queue->root[next_index+1]+offset_to_key) ^ + queue->root[next_index+1]+offset_to_key) * queue->max_at_top) > 0) next_index++; if (first && - (((cmp=queue->compare(queue->first_cmp_arg, - queue->root[next_index]+offset_to_key, - element+offset_to_key)) == 0) || - ((cmp ^ queue->max_at_top) > 0))) + (((queue->compare(queue->first_cmp_arg, + queue->root[next_index]+offset_to_key, + element+offset_to_key) * queue->max_at_top) >= 0))) { queue->root[idx]= element; return; @@ -314,7 +310,7 @@ void _downheap(register QUEUE *queue, uint idx) { if ((queue->compare(queue->first_cmp_arg, queue->root[next_index]+offset_to_key, - element+offset_to_key) ^ + element+offset_to_key) * queue->max_at_top) < 0) break; queue->root[idx]=queue->root[next_index]; @@ -334,7 +330,6 @@ void _downheap(register QUEUE *queue, uint idx) { uchar *element; uint elements,half_queue,next_index,offset_to_key; - int cmp; offset_to_key=queue->offset_to_key; element=queue->root[idx]; @@ -346,13 +341,12 @@ void _downheap(register QUEUE *queue, uint idx) if (next_index < elements && (queue->compare(queue->first_cmp_arg, queue->root[next_index]+offset_to_key, - queue->root[next_index+1]+offset_to_key) ^ + queue->root[next_index+1]+offset_to_key) * queue->max_at_top) > 0) next_index++; - if ((cmp=queue->compare(queue->first_cmp_arg, - queue->root[next_index]+offset_to_key, - element+offset_to_key)) == 0 || - (cmp ^ queue->max_at_top) > 0) + if ((queue->compare(queue->first_cmp_arg, + queue->root[next_index]+offset_to_key, + element+offset_to_key) * queue->max_at_top) >= 0) break; queue->root[idx]=queue->root[next_index]; idx=next_index; @@ -382,7 +376,7 @@ void queue_fix(QUEUE *queue) make test_priority_queue ./test_priority_queue - Written by Mikael Ronström, 2005 + Written by Mikael Ronström, 2005 */ static uint num_array[1025]; diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index a81ed925562..7f7be4835a5 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -396,6 +396,7 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, struct timespec wait_timeout; enum enum_thr_lock_result result= THR_LOCK_ABORTED; my_bool can_deadlock= test(data->owner->info->n_cursors); + DBUG_ENTER("wait_for_lock"); if (!in_wait_list) { @@ -431,13 +432,21 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, if the predicate is true. */ if (data->cond == 0) + { + DBUG_PRINT("thr_lock", ("lock granted/aborted")); break; + } if (rc == ETIMEDOUT || rc == ETIME) { + /* purecov: begin inspected */ + DBUG_PRINT("thr_lock", ("lock timed out")); result= THR_LOCK_WAIT_TIMEOUT; break; + /* purecov: end */ } } + DBUG_PRINT("thr_lock", ("aborted: %d in_wait_list: %d", + thread_var->abort, in_wait_list)); if (data->cond || data->type == TL_UNLOCK) { @@ -453,6 +462,7 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, } else { + DBUG_PRINT("thr_lock", ("lock aborted")); check_locks(data->lock, "aborted wait_for_lock", 0); } } @@ -471,7 +481,7 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, thread_var->current_mutex= 0; thread_var->current_cond= 0; pthread_mutex_unlock(&thread_var->mutex); - return result; + DBUG_RETURN(result); } @@ -509,7 +519,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, and the read lock is not TL_READ_NO_INSERT */ - DBUG_PRINT("lock",("write locked by thread: 0x%lx", + DBUG_PRINT("lock",("write locked 1 by thread: 0x%lx", lock->write.data->owner->info->thread_id)); if (thr_lock_owner_equal(data->owner, lock->write.data->owner) || (lock->write.data->type <= TL_WRITE_DELAYED && @@ -598,10 +608,14 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, { if (lock->write.data->type == TL_WRITE_ONLY) { - /* We are not allowed to get a lock in this case */ - data->type=TL_UNLOCK; - result= THR_LOCK_ABORTED; /* Can't wait for this one */ - goto end; + /* Allow lock owner to bypass TL_WRITE_ONLY. */ + if (!thr_lock_owner_equal(data->owner, lock->write.data->owner)) + { + /* We are not allowed to get a lock in this case */ + data->type=TL_UNLOCK; + result= THR_LOCK_ABORTED; /* Can't wait for this one */ + goto end; + } } /* @@ -631,10 +645,8 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, statistic_increment(locks_immediate,&THR_LOCK_lock); goto end; } - /* purecov: begin inspected */ - DBUG_PRINT("lock",("write locked by thread: 0x%lx", + DBUG_PRINT("lock",("write locked 2 by thread: 0x%lx", lock->write.data->owner->info->thread_id)); - /* purecov: end */ } else { @@ -669,7 +681,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, goto end; } } - DBUG_PRINT("lock",("write locked by thread: 0x%lx type: %d", + DBUG_PRINT("lock",("write locked 3 by thread: 0x%lx type: %d", lock->read.data->owner->info->thread_id, data->type)); } wait_queue= &lock->write_wait; @@ -683,6 +695,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, lock_owner= lock->read.data ? lock->read.data : lock->write.data; if (lock_owner && lock_owner->owner->info == owner->info) { + DBUG_PRINT("lock",("deadlock")); result= THR_LOCK_DEADLOCK; goto end; } |