summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
Diffstat (limited to 'mysys')
-rw-r--r--mysys/charset-def.c132
-rw-r--r--mysys/charset.c10
-rw-r--r--mysys/my_addr_resolve.c68
-rw-r--r--mysys/my_default.c476
-rw-r--r--mysys/my_error.c4
-rw-r--r--mysys/my_getopt.c109
-rw-r--r--mysys/my_getsystime.c30
-rw-r--r--mysys/my_init.c152
-rw-r--r--mysys/my_pthread.c63
-rw-r--r--mysys/my_winfile.c13
-rw-r--r--mysys/stacktrace.c45
-rw-r--r--mysys/thr_rwlock.c139
-rw-r--r--mysys/thr_timer.c31
-rw-r--r--mysys/typelib.c2
14 files changed, 514 insertions, 760 deletions
diff --git a/mysys/charset-def.c b/mysys/charset-def.c
index b4317806762..249fb1b5e4d 100644
--- a/mysys/charset-def.c
+++ b/mysys/charset-def.c
@@ -116,37 +116,37 @@ extern struct charset_info_st my_charset_utf16_unicode_520_nopad_ci;
#endif /* HAVE_CHARSET_utf16 */
-#ifdef HAVE_CHARSET_utf8
-extern struct charset_info_st my_charset_utf8_german2_uca_ci;
-extern struct charset_info_st my_charset_utf8_icelandic_uca_ci;
-extern struct charset_info_st my_charset_utf8_latvian_uca_ci;
-extern struct charset_info_st my_charset_utf8_romanian_uca_ci;
-extern struct charset_info_st my_charset_utf8_slovenian_uca_ci;
-extern struct charset_info_st my_charset_utf8_polish_uca_ci;
-extern struct charset_info_st my_charset_utf8_estonian_uca_ci;
-extern struct charset_info_st my_charset_utf8_spanish_uca_ci;
-extern struct charset_info_st my_charset_utf8_swedish_uca_ci;
-extern struct charset_info_st my_charset_utf8_turkish_uca_ci;
-extern struct charset_info_st my_charset_utf8_czech_uca_ci;
-extern struct charset_info_st my_charset_utf8_danish_uca_ci;
-extern struct charset_info_st my_charset_utf8_lithuanian_uca_ci;
-extern struct charset_info_st my_charset_utf8_slovak_uca_ci;
-extern struct charset_info_st my_charset_utf8_spanish2_uca_ci;
-extern struct charset_info_st my_charset_utf8_roman_uca_ci;
-extern struct charset_info_st my_charset_utf8_persian_uca_ci;
-extern struct charset_info_st my_charset_utf8_esperanto_uca_ci;
-extern struct charset_info_st my_charset_utf8_hungarian_uca_ci;
-extern struct charset_info_st my_charset_utf8_croatian_mysql561_uca_ci;
-extern struct charset_info_st my_charset_utf8_sinhala_uca_ci;
-extern struct charset_info_st my_charset_utf8_unicode_520_ci;
-extern struct charset_info_st my_charset_utf8_vietnamese_ci;
-extern struct charset_info_st my_charset_utf8_croatian_uca_ci;
-extern struct charset_info_st my_charset_utf8_myanmar_uca_ci;
-extern struct charset_info_st my_charset_utf8_thai_520_w2;
+#ifdef HAVE_CHARSET_utf8mb3
+extern struct charset_info_st my_charset_utf8mb3_german2_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_icelandic_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_latvian_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_romanian_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_slovenian_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_polish_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_estonian_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_spanish_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_swedish_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_turkish_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_czech_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_danish_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_lithuanian_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_slovak_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_spanish2_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_roman_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_persian_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_esperanto_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_hungarian_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_croatian_mysql561_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_sinhala_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_unicode_520_ci;
+extern struct charset_info_st my_charset_utf8mb3_vietnamese_ci;
+extern struct charset_info_st my_charset_utf8mb3_croatian_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_myanmar_uca_ci;
+extern struct charset_info_st my_charset_utf8mb3_thai_520_w2;
#ifdef HAVE_UTF8_GENERAL_CS
-extern struct charset_info_st my_charset_utf8_general_cs;
+extern struct charset_info_st my_charset_utf8mb3_general_cs;
#endif
-extern struct charset_info_st my_charset_utf8_unicode_520_nopad_ci;
+extern struct charset_info_st my_charset_utf8mb3_unicode_520_nopad_ci;
#endif
#ifdef HAVE_CHARSET_utf8mb4
@@ -304,47 +304,47 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused)))
add_compiled_collation(&my_charset_ujis_nopad_bin);
#endif
-#ifdef HAVE_CHARSET_utf8
- add_compiled_collation(&my_charset_utf8_general_ci);
- add_compiled_collation(&my_charset_utf8_general_nopad_ci);
- add_compiled_collation(&my_charset_utf8_bin);
- add_compiled_collation(&my_charset_utf8_nopad_bin);
- add_compiled_collation(&my_charset_utf8_general_mysql500_ci);
+#ifdef HAVE_CHARSET_utf8mb3
+ add_compiled_collation(&my_charset_utf8mb3_general_ci);
+ add_compiled_collation(&my_charset_utf8mb3_general_nopad_ci);
+ add_compiled_collation(&my_charset_utf8mb3_bin);
+ add_compiled_collation(&my_charset_utf8mb3_nopad_bin);
+ add_compiled_collation(&my_charset_utf8mb3_general_mysql500_ci);
#ifdef HAVE_UTF8_GENERAL_CS
- add_compiled_collation(&my_charset_utf8_general_cs);
+ add_compiled_collation(&my_charset_utf8mb3_general_cs);
#endif
#ifdef HAVE_UCA_COLLATIONS
- add_compiled_collation(&my_charset_utf8_unicode_ci);
- add_compiled_collation(&my_charset_utf8_german2_uca_ci);
- add_compiled_collation(&my_charset_utf8_icelandic_uca_ci);
- add_compiled_collation(&my_charset_utf8_latvian_uca_ci);
- add_compiled_collation(&my_charset_utf8_romanian_uca_ci);
- add_compiled_collation(&my_charset_utf8_slovenian_uca_ci);
- add_compiled_collation(&my_charset_utf8_polish_uca_ci);
- add_compiled_collation(&my_charset_utf8_estonian_uca_ci);
- add_compiled_collation(&my_charset_utf8_spanish_uca_ci);
- add_compiled_collation(&my_charset_utf8_swedish_uca_ci);
- add_compiled_collation(&my_charset_utf8_turkish_uca_ci);
- add_compiled_collation(&my_charset_utf8_czech_uca_ci);
- add_compiled_collation(&my_charset_utf8_danish_uca_ci);
- add_compiled_collation(&my_charset_utf8_lithuanian_uca_ci);
- add_compiled_collation(&my_charset_utf8_slovak_uca_ci);
- add_compiled_collation(&my_charset_utf8_spanish2_uca_ci);
- add_compiled_collation(&my_charset_utf8_roman_uca_ci);
- add_compiled_collation(&my_charset_utf8_persian_uca_ci);
- add_compiled_collation(&my_charset_utf8_esperanto_uca_ci);
- add_compiled_collation(&my_charset_utf8_hungarian_uca_ci);
- add_compiled_collation(&my_charset_utf8_croatian_mysql561_uca_ci);
- add_compiled_collation(&my_charset_utf8_sinhala_uca_ci);
- add_compiled_collation(&my_charset_utf8_unicode_520_ci);
- add_compiled_collation(&my_charset_utf8_vietnamese_ci);
- add_compiled_collation(&my_charset_utf8_croatian_uca_ci);
- add_compiled_collation(&my_charset_utf8_myanmar_uca_ci);
- add_compiled_collation(&my_charset_utf8_thai_520_w2);
- add_compiled_collation(&my_charset_utf8_unicode_nopad_ci);
- add_compiled_collation(&my_charset_utf8_unicode_520_nopad_ci);
+ add_compiled_collation(&my_charset_utf8mb3_unicode_ci);
+ add_compiled_collation(&my_charset_utf8mb3_german2_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_icelandic_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_latvian_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_romanian_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_slovenian_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_polish_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_estonian_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_spanish_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_swedish_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_turkish_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_czech_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_danish_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_lithuanian_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_slovak_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_spanish2_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_roman_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_persian_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_esperanto_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_hungarian_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_croatian_mysql561_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_sinhala_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_unicode_520_ci);
+ add_compiled_collation(&my_charset_utf8mb3_vietnamese_ci);
+ add_compiled_collation(&my_charset_utf8mb3_croatian_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_myanmar_uca_ci);
+ add_compiled_collation(&my_charset_utf8mb3_thai_520_w2);
+ add_compiled_collation(&my_charset_utf8mb3_unicode_nopad_ci);
+ add_compiled_collation(&my_charset_utf8mb3_unicode_520_nopad_ci);
#endif
-#endif /* HAVE_CHARSET_utf8 */
+#endif /* HAVE_CHARSET_utf8mb3 */
#ifdef HAVE_CHARSET_utf8mb4
diff --git a/mysys/charset.c b/mysys/charset.c
index f44dc7606c1..7771f5800ef 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -262,7 +262,7 @@ static my_bool simple_cs_is_full(CHARSET_INFO *cs)
}
-#if defined(HAVE_UCA_COLLATIONS) && (defined(HAVE_CHARSET_ucs2) || defined(HAVE_CHARSET_utf8))
+#if defined(HAVE_UCA_COLLATIONS) && (defined(HAVE_CHARSET_ucs2) || defined(HAVE_CHARSET_utf8mb3))
/**
Initialize a loaded collation.
@param [OUT] to - The new charset_info_st structure to initialize.
@@ -350,12 +350,12 @@ static int add_collation(struct charset_info_st *cs)
}
else if (!strcmp(cs->csname, "utf8") || !strcmp(cs->csname, "utf8mb3"))
{
-#if defined (HAVE_CHARSET_utf8) && defined(HAVE_UCA_COLLATIONS)
+#if defined (HAVE_CHARSET_utf8mb3) && defined(HAVE_UCA_COLLATIONS)
copy_uca_collation(newcs, newcs->state & MY_CS_NOPAD ?
- &my_charset_utf8_unicode_nopad_ci :
- &my_charset_utf8_unicode_ci,
+ &my_charset_utf8mb3_unicode_nopad_ci :
+ &my_charset_utf8mb3_unicode_ci,
cs);
- newcs->ctype= my_charset_utf8_unicode_ci.ctype;
+ newcs->ctype= my_charset_utf8mb3_unicode_ci.ctype;
if (init_state_maps(newcs))
return MY_XML_ERROR;
#endif
diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c
index 7590d576a7c..ff15558ddd4 100644
--- a/mysys/my_addr_resolve.c
+++ b/mysys/my_addr_resolve.c
@@ -191,7 +191,9 @@ int start_addr2line_fork(const char *binary_path)
return 0;
}
-int my_addr_resolve(void *ptr, my_addr_loc *loc)
+static int first_error= 0;
+
+static int addr_resolve(void *ptr, my_addr_loc *loc)
{
char input[32];
size_t len;
@@ -206,29 +208,13 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
int filename_start = -1;
int line_number_start = -1;
- Dl_info info;
- void *offset;
-
- if (!dladdr(ptr, &info))
- return 1;
-
- if (strcmp(addr2line_binary, info.dli_fname))
- {
- /* We use dli_fname in case the path is longer than the length of our static
- string. We don't want to allocate anything dynamicaly here as we are in
- a "crashed" state. */
- if (start_addr2line_fork(info.dli_fname))
- {
- addr2line_binary[0] = '\0';
- return 2;
- }
- /* Save result for future comparisons. */
- strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary));
- }
- offset = info.dli_fbase;
- len= my_snprintf(input, sizeof(input), "%08x\n", (ulonglong)(ptr - offset));
+ len= my_snprintf(input, sizeof(input), "%p\n", ptr);
if (write(in[1], input, len) <= 0)
+ {
+ if (!first_error++)
+ fputs("Printing to addr2line failed\n", stderr);
return 3;
+ }
FD_ZERO(&set);
FD_SET(out[0], &set);
@@ -278,7 +264,7 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
loc->line= atoi(output + line_number_start);
/* Addr2line was unable to extract any meaningful information. */
- if (strcmp(loc->file, "??") == 0)
+ if (strcmp(loc->file, "??") == 0 && loc->func[0] == '?')
return 6;
loc->file= strip_path(loc->file);
@@ -286,6 +272,42 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
return 0;
}
+
+int my_addr_resolve(void *ptr, my_addr_loc *loc)
+{
+ Dl_info info;
+ int error;
+
+ if (!dladdr(ptr, &info))
+ return 1;
+
+ if (strcmp(addr2line_binary, info.dli_fname))
+ {
+ /*
+ We use dli_fname in case the path is longer than the length of
+ our static string. We don't want to allocate anything
+ dynamicaly here as we are in a "crashed" state.
+ */
+ if (start_addr2line_fork(info.dli_fname))
+ {
+ if (!first_error++)
+ fputs("Can't start addr2line\n", stderr);
+ addr2line_binary[0] = '\0';
+ return 2;
+ }
+ /* Save result for future comparisons. */
+ strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary));
+ }
+ if (!(error= addr_resolve(ptr, loc)))
+ return 0;
+#ifdef EXTRA_RESOLVE
+ if (!(error= addr_resolve((void*) (ptr - info.dli_fbase), loc)))
+ return 0;
+#endif
+ return error;
+}
+
+
const char *my_addr_resolve_init()
{
return 0;
diff --git a/mysys/my_default.c b/mysys/my_default.c
index deeb9b4a5b8..8655cccf050 100644
--- a/mysys/my_default.c
+++ b/mysys/my_default.c
@@ -43,52 +43,23 @@
#include <winbase.h>
#endif
-/**
- arguments separator
-
- load_defaults() loads arguments from config file and put them
- before the arguments from command line, this separator is used to
- separate the arguments loaded from config file and arguments user
- provided on command line.
-
- Options with value loaded from config file are always in the form
- '--option=value', while for command line options, the value can be
- given as the next argument. Thus we used a separator so that
- handle_options() can distinguish them.
-
- Note: any other places that does not need to distinguish them
- should skip the separator.
-
- The content of arguments separator does not matter, one should only
- check the pointer, use "----args-separator----" here to ease debug
- if someone misused it.
-
- The args separator will only be added when
- my_getopt_use_args_seprator is set to TRUE before calling
- load_defaults();
-
- See BUG#25192
+/*
+ Mark file names in argv[]. File marker is *always* followed by a file name
+ All options after it come from that file.
+ Empty file name ("") means command line.
*/
-static const char *args_separator= "----args-separator----";
-inline static void set_args_separator(char** arg)
+static char *file_marker= (char*)"----file-marker----";
+my_bool my_defaults_mark_files= FALSE;
+my_bool is_file_marker(const char* arg)
{
- DBUG_ASSERT(my_getopt_use_args_separator);
- *arg= (char*)args_separator;
-}
-my_bool my_getopt_use_args_separator= FALSE;
-my_bool my_getopt_is_args_separator(const char* arg)
-{
- return (arg == args_separator);
+ return arg == file_marker;
}
+
+my_bool my_no_defaults=FALSE, my_print_defaults= FALSE;
const char *my_defaults_file=0;
const char *my_defaults_group_suffix=0;
const char *my_defaults_extra_file=0;
-static char my_defaults_file_buffer[FN_REFLEN];
-static char my_defaults_extra_file_buffer[FN_REFLEN];
-
-static my_bool defaults_already_read= FALSE;
-
/* Which directories are searched for options (and in which order) */
#define MAX_DEFAULT_DIRS 7
@@ -103,15 +74,6 @@ static const char *f_extensions[]= { ".cnf", 0 };
#define NEWLINE "\n"
#endif
-static int handle_default_option(void *, const char *, const char *);
-
-/*
- This structure defines the context that we pass to callback
- function 'handle_default_option' used in search_default_file
- to process each option. This context is used if search_default_file
- was called from load_defaults.
-*/
-
struct handle_option_ctx
{
MEM_ROOT *alloc;
@@ -119,12 +81,11 @@ struct handle_option_ctx
TYPELIB *group;
};
-static int search_default_file(Process_option_func func, void *func_ctx,
- const char *dir, const char *config_file);
-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 int search_default_file(struct handle_option_ctx *,
+ const char *, const char *);
+static int search_default_file_with_ext(struct handle_option_ctx *,
+ const char *, const char *,
+ const char *, int);
/**
@@ -159,33 +120,6 @@ static char *remove_end_comment(char *ptr);
/*
- Expand a file name so that the current working directory is added if
- the name is relative.
-
- RETURNS
- 0 All OK
- 2 Out of memory or path to long
- 3 Not able to get working directory
- */
-
-static int
-fn_expand(const char *filename, char *result_buf)
-{
- char dir[FN_REFLEN];
- const int flags= MY_UNPACK_FILENAME | MY_SAFE_PATH | MY_RELATIVE_PATH;
- DBUG_ENTER("fn_expand");
- DBUG_PRINT("enter", ("filename: %s, result_buf: %p",
- filename, result_buf));
- if (my_getwd(dir, sizeof(dir), MYF(0)))
- DBUG_RETURN(3);
- DBUG_PRINT("debug", ("dir: %s", dir));
- if (fn_format(result_buf, filename, dir, "", flags) == NULL)
- DBUG_RETURN(2);
- DBUG_PRINT("return", ("result: %s", result_buf));
- DBUG_RETURN(0);
-}
-
-/*
Process config files in default directories.
SYNOPSIS
@@ -194,8 +128,6 @@ fn_expand(const char *filename, char *result_buf)
If this is a path, then only this file is read.
argc Pointer to argc of original program
argv Pointer to argv of original program
- args_used Pointer to variable for storing the number of
- arguments used.
func Pointer to the function to process options
func_ctx It's context. Usually it is the structure to
store additional options.
@@ -219,53 +151,20 @@ fn_expand(const char *filename, char *result_buf)
--defaults_group_suffix
*/
-int my_search_option_files(const char *conf_file, int *argc, char ***argv,
- uint *args_used, Process_option_func func,
- void *func_ctx, const char **default_directories)
+static int my_search_option_files(const char *conf_file, int *argc, char ***argv,
+ struct handle_option_ctx *ctx,
+ const char **default_directories)
{
- const char **dirs, *forced_default_file, *forced_extra_defaults;
+ const char **dirs;
int error= 0;
DBUG_ENTER("my_search_option_files");
- /* Check if we want to force the use a specific default file */
- *args_used+= get_defaults_options(*argc - *args_used, *argv + *args_used,
- (char **) &forced_default_file,
- (char **) &forced_extra_defaults,
- (char **) &my_defaults_group_suffix);
-
- if (! my_defaults_group_suffix)
- my_defaults_group_suffix= getenv("MYSQL_GROUP_SUFFIX");
-
- if (forced_extra_defaults && !defaults_already_read)
- {
- int error= fn_expand(forced_extra_defaults, my_defaults_extra_file_buffer);
- if (error)
- DBUG_RETURN(error);
- my_defaults_extra_file= my_defaults_extra_file_buffer;
- }
-
- if (forced_default_file && !defaults_already_read)
- {
- int error= fn_expand(forced_default_file, my_defaults_file_buffer);
- if (error)
- DBUG_RETURN(error);
- my_defaults_file= my_defaults_file_buffer;
- }
-
- defaults_already_read= TRUE;
-
- /*
- We can only handle 'defaults-group-suffix' if we are called from
- load_defaults() as otherwise we can't know the type of 'func_ctx'
- */
-
- if (my_defaults_group_suffix && func == handle_default_option)
+ if (my_defaults_group_suffix)
{
/* Handle --defaults-group-suffix= */
uint i;
const char **extra_groups;
const size_t instance_len= strlen(my_defaults_group_suffix);
- struct handle_option_ctx *ctx= (struct handle_option_ctx*) func_ctx;
char *ptr;
TYPELIB *group= ctx->group;
@@ -297,7 +196,7 @@ int my_search_option_files(const char *conf_file, int *argc, char ***argv,
if (my_defaults_file)
{
- if ((error= search_default_file_with_ext(func, func_ctx, "", "",
+ if ((error= search_default_file_with_ext(ctx, "", "",
my_defaults_file, 0)) < 0)
goto err;
if (error > 0)
@@ -309,7 +208,7 @@ int my_search_option_files(const char *conf_file, int *argc, char ***argv,
}
else if (dirname_length(conf_file))
{
- if ((error= search_default_file(func, func_ctx, NullS, conf_file)) < 0)
+ if ((error= search_default_file(ctx, NullS, conf_file)) < 0)
goto err;
}
else
@@ -318,12 +217,12 @@ int my_search_option_files(const char *conf_file, int *argc, char ***argv,
{
if (**dirs)
{
- if (search_default_file(func, func_ctx, *dirs, conf_file) < 0)
+ if (search_default_file(ctx, *dirs, conf_file) < 0)
goto err;
}
else if (my_defaults_extra_file)
{
- if ((error= search_default_file_with_ext(func, func_ctx, "", "",
+ if ((error= search_default_file_with_ext(ctx, "", "",
my_defaults_extra_file, 0)) < 0)
goto err; /* Fatal error */
if (error > 0)
@@ -345,47 +244,23 @@ err:
/*
- The option handler for load_defaults.
+ adds an option to the array of options
SYNOPSIS
- handle_deault_option()
- in_ctx Handler context. In this case it is a
- handle_option_ctx structure.
- group_name The name of the group the option belongs to.
+ add_option()
+ in_ctx Handler context.
option The very option to be processed. It is already
- prepared to be used in argv (has -- prefix). If it
- is NULL, we are handling a new group (section).
-
- DESCRIPTION
- This handler checks whether a group is one of the listed and adds an option
- to the array if yes. Some other handler can record, for instance, all
- groups and their options, not knowing in advance the names and amount of
- groups.
+ prepared to be used in argv (has -- prefix).
RETURN
0 - ok
1 - error occurred
*/
-static int handle_default_option(void *in_ctx, const char *group_name,
- const char *option)
+static int add_option(struct handle_option_ctx *ctx, const char *option)
{
- char *tmp;
- struct handle_option_ctx *ctx= (struct handle_option_ctx *) in_ctx;
-
- if (!option)
- return 0;
-
- if (find_type((char *)group_name, ctx->group, FIND_TYPE_NO_PREFIX))
- {
- if (!(tmp= alloc_root(ctx->alloc, strlen(option) + 1)))
- return 1;
- if (insert_dynamic(ctx->args, (uchar*) &tmp))
- return 1;
- strmov(tmp, option);
- }
-
- return 0;
+ char *tmp= strdup_root(ctx->alloc, option);
+ return !tmp || insert_dynamic(ctx->args, (uchar*) &tmp);
}
@@ -394,50 +269,74 @@ static int handle_default_option(void *in_ctx, const char *group_name,
SYNOPSIS
get_defaults_options()
- argc Pointer to argc of original program
argv Pointer to argv of original program
- defaults --defaults-file option
- extra_defaults --defaults-extra-file option
+
+ DESCRIPTION
+ Sets my_no_defaults, my_defaults_file, my_defaults_extra_file,
+ my_defaults_group_suffix, my_print_defaults
RETURN
# Number of arguments used from *argv
- defaults and extra_defaults will be set to option of the appropriate
- items of argv array, or to NULL if there are no such options
*/
-int get_defaults_options(int argc, char **argv,
- char **defaults,
- char **extra_defaults,
- char **group_suffix)
+int get_defaults_options(char **argv)
{
- int org_argc= argc;
- *defaults= *extra_defaults= *group_suffix= 0;
+ static char file_buffer[FN_REFLEN];
+ static char extra_file_buffer[FN_REFLEN];
+ char **orig_argv= argv;
+
+ argv++; /* Skip program name */
+
+ my_defaults_file= my_defaults_group_suffix= my_defaults_extra_file= 0;
+ my_no_defaults= my_print_defaults= FALSE;
- while (argc >= 2)
+ if (*argv && !strcmp(*argv, "--no-defaults"))
{
- /* Skip program name or previously handled argument */
+ my_no_defaults= 1;
argv++;
- if (!*defaults && is_prefix(*argv,"--defaults-file="))
- {
- *defaults= *argv + sizeof("--defaults-file=")-1;
- argc--;
- continue;
- }
- if (!*extra_defaults && is_prefix(*argv,"--defaults-extra-file="))
- {
- *extra_defaults= *argv + sizeof("--defaults-extra-file=")-1;
- argc--;
- continue;
- }
- if (!*group_suffix && is_prefix(*argv, "--defaults-group-suffix="))
+ }
+ else
+ for(; *argv; argv++)
{
- *group_suffix= *argv + sizeof("--defaults-group-suffix=")-1;
- argc--;
- continue;
+ if (!my_defaults_file && is_prefix(*argv, "--defaults-file="))
+ my_defaults_file= *argv + sizeof("--defaults-file=")-1;
+ else
+ if (!my_defaults_extra_file && is_prefix(*argv, "--defaults-extra-file="))
+ my_defaults_extra_file= *argv + sizeof("--defaults-extra-file=")-1;
+ else
+ if (!my_defaults_group_suffix && is_prefix(*argv, "--defaults-group-suffix="))
+ my_defaults_group_suffix= *argv + sizeof("--defaults-group-suffix=")-1;
+ else
+ break;
}
- break;
+
+ if (*argv && !strcmp(*argv, "--print-defaults"))
+ {
+ my_print_defaults= 1;
+ my_defaults_mark_files= FALSE;
+ argv++;
}
- return org_argc - argc;
+
+ if (! my_defaults_group_suffix)
+ my_defaults_group_suffix= getenv("MYSQL_GROUP_SUFFIX");
+
+ if (my_defaults_extra_file && my_defaults_extra_file != extra_file_buffer)
+ {
+ int error= my_realpath(extra_file_buffer, my_defaults_extra_file, MYF(0));
+ if (error)
+ return error;
+ my_defaults_extra_file= extra_file_buffer;
+ }
+
+ if (my_defaults_file && my_defaults_file != file_buffer)
+ {
+ int error= my_realpath(file_buffer, my_defaults_file, MYF(0));
+ if (error)
+ return error;
+ my_defaults_file= file_buffer;
+ }
+
+ return (int)(argv - orig_argv);
}
/*
@@ -504,132 +403,85 @@ int load_defaults(const char *conf_file, const char **groups,
*/
-int my_load_defaults(const char *conf_file, const char **groups,
- int *argc, char ***argv, const char ***default_directories)
+int my_load_defaults(const char *conf_file, const char **groups, int *argc,
+ char ***argv, const char ***default_directories)
{
DYNAMIC_ARRAY args;
- TYPELIB group;
- my_bool found_print_defaults= 0;
- uint args_used= 0;
+ int args_used= 0;
int error= 0;
MEM_ROOT alloc;
char *ptr,**res;
- struct handle_option_ctx ctx;
const char **dirs;
- uint args_sep= my_getopt_use_args_separator ? 1 : 0;
- DBUG_ENTER("load_defaults");
+ DBUG_ENTER("my_load_defaults");
init_alloc_root(&alloc, "my_load_defaults", 512, 0, MYF(0));
if ((dirs= init_default_directories(&alloc)) == NULL)
goto err;
- /*
- Check if the user doesn't want any default option processing
- --no-defaults is always the first option
- */
- if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults"))
- {
- /* remove the --no-defaults argument and return only the other arguments */
- uint i, j;
- if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
- (*argc + 1)*sizeof(char*))))
- goto err;
- res= (char**) (ptr+sizeof(alloc));
- res[0]= **argv; /* Copy program name */
- j= 1; /* Start from 1 for the reset result args */
- if (my_getopt_use_args_separator)
- {
- /* set arguments separator */
- set_args_separator(&res[1]);
- j++;
- }
- for (i=2 ; i < (uint) *argc ; i++, j++)
- res[j]=argv[0][i];
- res[j]=0; /* End pointer */
- /*
- Update the argc, if have not added args separator, then we have
- to decrease argc because we have removed the "--no-defaults".
- */
- if (!my_getopt_use_args_separator)
- (*argc)--;
- *argv=res;
- *(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
- if (default_directories)
- *default_directories= dirs;
- DBUG_RETURN(0);
- }
-
- group.count=0;
- group.name= "defaults";
- group.type_names= groups;
- for (; *groups ; groups++)
- group.count++;
+ args_used= get_defaults_options(*argv);
if (my_init_dynamic_array(&args, sizeof(char*), 128, 64, MYF(0)))
goto err;
- ctx.alloc= &alloc;
- ctx.args= &args;
- ctx.group= &group;
+ insert_dynamic(&args, *argv);/* Name MUST be set, even by embedded library */
- if ((error= my_search_option_files(conf_file, argc, argv, &args_used,
- handle_default_option, (void *) &ctx,
- dirs)))
+ *argc-= args_used;
+ *argv+= args_used;
+
+ if (!my_no_defaults)
{
- delete_dynamic(&args);
- free_root(&alloc,MYF(0));
- DBUG_RETURN(error);
+ TYPELIB group; // XXX
+ struct handle_option_ctx ctx;
+
+ group.count=0;
+ group.name= "defaults";
+ group.type_names= groups;
+
+ for (; *groups ; groups++)
+ group.count++;
+
+ ctx.alloc= &alloc;
+ ctx.args= &args;
+ ctx.group= &group;
+
+ if ((error= my_search_option_files(conf_file, argc - args_used,
+ argv + args_used, &ctx, dirs)))
+ {
+ delete_dynamic(&args);
+ free_root(&alloc,MYF(0));
+ DBUG_RETURN(error);
+ }
}
- /*
- Here error contains <> 0 only if we have a fully specified conf_file
- or a forced default file
- */
- if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
- (args.elements + *argc + 1 + args_sep) *sizeof(char*))))
+
+ if (!(ptr=(char*) alloc_root(&alloc, sizeof(alloc) +
+ (args.elements + *argc + 3) * sizeof(char*))))
goto err;
res= (char**) (ptr+sizeof(alloc));
- /* copy name + found arguments + command line arguments to new array */
- res[0]= argv[0][0]; /* Name MUST be set, even by embedded library */
- memcpy((uchar*) (res+1), args.buffer, args.elements*sizeof(char*));
- /* Skip --defaults-xxx options */
- (*argc)-= args_used;
- (*argv)+= args_used;
+ /* found arguments + command line arguments to new array */
+ memcpy(res, args.buffer, args.elements * sizeof(char*));
- /*
- Check if we want to see the new argument list
- This options must always be the last of the default options
- */
- if (*argc >= 2 && !strcmp(argv[0][1],"--print-defaults"))
+ if (my_defaults_mark_files)
{
- found_print_defaults=1;
- --*argc; ++*argv; /* skip argument */
- }
-
- if (my_getopt_use_args_separator)
- {
- /* set arguments separator for arguments from config file and
- command line */
- set_args_separator(&res[args.elements+1]);
+ res[args.elements++]= file_marker;
+ res[args.elements++]= (char*)"";
}
if (*argc)
- memcpy((uchar*) (res+1+args.elements+args_sep), (char*) ((*argv)+1),
- (*argc-1)*sizeof(char*));
- res[args.elements+ *argc+args_sep]=0; /* last null */
+ memcpy(res + args.elements, *argv, *argc * sizeof(char*));
- (*argc)+=args.elements+args_sep;
- *argv= (char**) res;
+ (*argc)+= args.elements;
+ *argv= res;
+ (*argv)[*argc]= 0;
*(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
delete_dynamic(&args);
- if (found_print_defaults)
+ if (my_print_defaults)
{
int i;
printf("%s would have been started with the following arguments:\n",
**argv);
for (i=1 ; i < *argc ; i++)
- if (!my_getopt_is_args_separator((*argv)[i])) /* skip arguments separator */
- printf("%s ", (*argv)[i]);
+ printf("%s ", (*argv)[i]);
puts("");
DBUG_RETURN(4);
}
@@ -653,9 +505,7 @@ void free_defaults(char **argv)
}
-static int search_default_file(Process_option_func opt_handler,
- void *handler_ctx,
- const char *dir,
+static int search_default_file(struct handle_option_ctx *ctx, const char *dir,
const char *config_file)
{
char **ext;
@@ -666,9 +516,7 @@ static int search_default_file(Process_option_func opt_handler,
for (ext= (char**) exts_to_use; *ext; ext++)
{
int error;
- if ((error= search_default_file_with_ext(opt_handler, handler_ctx,
- dir, *ext,
- config_file, 0)) < 0)
+ if ((error= search_default_file_with_ext(ctx, dir, *ext, config_file, 0)) < 0)
return error;
}
return 0;
@@ -730,9 +578,7 @@ static char *get_argument(const char *keyword, size_t kwlen,
SYNOPSIS
search_default_file_with_ext()
- opt_handler Option handler function. It is used to process
- every separate option.
- handler_ctx Pointer to the structure to store actual
+ ctx Pointer to the structure to store actual
parameters of the function.
dir directory to read
ext Extension for configuration file
@@ -747,10 +593,8 @@ static char *get_argument(const char *keyword, size_t kwlen,
1 File not found (Warning)
*/
-static int search_default_file_with_ext(Process_option_func opt_handler,
- void *handler_ctx,
- const char *dir,
- const char *ext,
+static int search_default_file_with_ext(struct handle_option_ctx *ctx,
+ const char *dir, const char *ext,
const char *config_file,
int recursion_level)
{
@@ -761,12 +605,12 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
const int max_recursion_level= 10;
MYSQL_FILE *fp;
uint line=0;
- my_bool found_group=0;
+ enum { NONE, PARSE, SKIP } found_group= NONE;
uint i;
MY_DIR *search_dir;
FILEINFO *search_file;
- if ((dir ? strlen(dir) : 0 )+strlen(config_file) >= FN_REFLEN-3)
+ if (safe_strlen(dir) + strlen(config_file) >= FN_REFLEN-3)
return 0; /* Ignore wrong paths */
if (dir)
{
@@ -802,6 +646,11 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
if (!(fp= mysql_file_fopen(key_file_cnf, name, O_RDONLY, MYF(0))))
return 1; /* Ignore wrong files */
+ if (my_defaults_mark_files)
+ if (insert_dynamic(ctx->args, (uchar*) &file_marker) ||
+ add_option(ctx, name))
+ goto err;
+
while (mysql_file_fgets(buff, sizeof(buff) - 1, fp))
{
line++;
@@ -862,8 +711,7 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
fn_format(tmp, search_file->name, ptr, "",
MY_UNPACK_FILENAME | MY_SAFE_PATH);
- search_default_file_with_ext(opt_handler, handler_ctx, "", "", tmp,
- recursion_level + 1);
+ search_default_file_with_ext(ctx, "", "", tmp, recursion_level + 1);
}
}
@@ -877,8 +725,7 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
name, line)))
goto err;
- search_default_file_with_ext(opt_handler, handler_ctx, "", "", ptr,
- recursion_level + 1);
+ search_default_file_with_ext(ctx, "", "", ptr, recursion_level + 1);
}
continue;
@@ -886,7 +733,6 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
if (*ptr == '[') /* Group name */
{
- found_group=1;
if (!(end=(char *) strchr(++ptr,']')))
{
fprintf(stderr,
@@ -899,32 +745,29 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
end[0]=0;
strmake(curr_gr, ptr, MY_MIN((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
-
- /* signal that a new group is found */
- opt_handler(handler_ctx, curr_gr, NULL);
-
+ found_group= find_type(curr_gr, ctx->group, FIND_TYPE_NO_PREFIX)
+ ? PARSE : SKIP;
continue;
}
- if (!found_group)
+ switch (found_group)
{
+ case NONE:
fprintf(stderr,
"error: Found option without preceding group in config file: %s at line: %d\n",
name,line);
goto err;
+ case PARSE:
+ break;
+ case SKIP:
+ continue;
}
-
-
+
end= remove_end_comment(ptr);
if ((value= strchr(ptr, '=')))
end= value;
for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
- if (!value)
- {
- strmake(strmov(option,"--"),ptr, (size_t) (end-ptr));
- if (opt_handler(handler_ctx, curr_gr, option))
- goto err;
- }
- else
+ ptr= strmake(strmov(option,"--"), ptr, (size_t) (end-ptr));
+ if (value)
{
/* Remove pre- and end space */
char *value_end;
@@ -946,9 +789,7 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
value++;
value_end--;
}
- ptr=strnmov(strmov(option,"--"),ptr,(size_t) (end-ptr));
*ptr++= '=';
-
for ( ; value != value_end; value++)
{
if (*value == '\\' && value != value_end-1)
@@ -988,9 +829,10 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
*ptr++= *value;
}
*ptr=0;
- if (opt_handler(handler_ctx, curr_gr, option))
- goto err;
}
+
+ if (add_option(ctx, option))
+ goto err;
}
mysql_file_fclose(fp, MYF(0));
return(0);
diff --git a/mysys/my_error.c b/mysys/my_error.c
index 5f1ca0af55b..cb1fbfe1c04 100644
--- a/mysys/my_error.c
+++ b/mysys/my_error.c
@@ -118,7 +118,7 @@ void my_error(uint nr, myf MyFlags, ...)
else
{
va_start(args,MyFlags);
- (void) my_vsnprintf_ex(&my_charset_utf8_general_ci, ebuff,
+ (void) my_vsnprintf_ex(&my_charset_utf8mb3_general_ci, ebuff,
sizeof(ebuff), format, args);
va_end(args);
}
@@ -148,7 +148,7 @@ void my_printf_error(uint error, const char *format, myf MyFlags, ...)
error, MyFlags, errno, format));
va_start(args,MyFlags);
- (void) my_vsnprintf_ex(&my_charset_utf8_general_ci, ebuff,
+ (void) my_vsnprintf_ex(&my_charset_utf8mb3_general_ci, ebuff,
sizeof(ebuff), format, args);
va_end(args);
(*error_handler_hook)(error, ebuff, MyFlags);
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index 7d539cd44fe..9ebf63bf6ef 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -24,6 +24,7 @@
#include <my_getopt.h>
#include <errno.h>
+my_bool is_file_marker(const char* arg);
typedef void (*init_func_p)(const struct my_option *option, void *variable,
longlong value);
@@ -31,7 +32,7 @@ static void default_reporter(enum loglevel level, const char *format, ...);
my_error_reporter my_getopt_error_reporter= &default_reporter;
static int findopt(char *, uint, const struct my_option **, const char **);
-my_bool getopt_compare_strings(const char *, const char *, uint);
+static my_bool getopt_compare_strings(const char *, const char *, uint);
static longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
static ulonglong getopt_ull(char *, const struct my_option *, int *);
static double getopt_double(char *arg, const struct my_option *optp, int *err);
@@ -79,8 +80,9 @@ my_bool my_getopt_skip_unknown= 0;
*/
my_bool my_getopt_prefix_matching= 1;
-static void default_reporter(enum loglevel level,
- const char *format, ...)
+my_getopt_value my_getopt_get_addr= 0;
+
+static void default_reporter(enum loglevel level, const char *format, ...)
{
va_list args;
DBUG_ENTER("default_reporter");
@@ -97,13 +99,6 @@ static void default_reporter(enum loglevel level,
DBUG_VOID_RETURN;
}
-static my_getopt_value getopt_get_addr;
-
-void my_getopt_register_get_addr(my_getopt_value func_addr)
-{
- getopt_get_addr= func_addr;
-}
-
union ull_dbl
{
ulonglong ull;
@@ -140,7 +135,7 @@ double getopt_ulonglong2double(ulonglong v)
or until the end of argv. Parse options, check that the given option
matches with one of the options in struct 'my_option'.
Check that option was given an argument if it requires one
- Call the optional 'get_one_option()' function once for each option.
+ Call the 'get_one_option()' function once for each option.
Note that handle_options() can be invoked multiple times to
parse a command line in several steps.
@@ -187,19 +182,18 @@ double getopt_ulonglong2double(ulonglong v)
@param [in, out] argc command line options (count)
@param [in, out] argv command line options (values)
@param [in] longopts descriptor of all valid options
- @param [in] get_one_option optional callback function to process each option,
- can be NULL.
+ @param [in] get_one_option callback function to process each option
@return error in case of ambiguous or unknown options,
0 on success.
*/
-int handle_options(int *argc, char ***argv,
- const struct my_option *longopts,
+int handle_options(int *argc, char ***argv, const struct my_option *longopts,
my_get_one_option get_one_option)
{
uint UNINIT_VAR(opt_found), argvpos= 0, length;
my_bool end_of_options= 0, must_be_var, set_maximum_value,
option_is_loose, option_is_autoset;
char **pos, **pos_end, *optend, *opt_str, key_name[FN_REFLEN];
+ char *filename= (char*)"";
const char *UNINIT_VAR(prev_found);
const struct my_option *optp;
void *value;
@@ -208,40 +202,35 @@ int handle_options(int *argc, char ***argv,
DBUG_ENTER("handle_options");
/* handle_options() assumes arg0 (program name) always exists */
- DBUG_ASSERT(argc && *argc >= 1);
- DBUG_ASSERT(argv && *argv);
+ DBUG_ASSERT(*argc >= 1);
+ DBUG_ASSERT(*argv);
(*argc)--; /* Skip the program name */
(*argv)++; /* --- || ---- */
init_variables(longopts, init_one_value);
- /*
- Search for args_separator, if found, then the first part of the
- arguments are loaded from configs
- */
- for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
- {
- if (my_getopt_is_args_separator(*pos))
- {
- is_cmdline_arg= 0;
- break;
- }
- }
+ is_cmdline_arg= !is_file_marker(**argv);
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
{
char **first= pos;
char *cur_arg= *pos;
opt_found= 0;
- if (!is_cmdline_arg && (my_getopt_is_args_separator(cur_arg)))
+ if (!is_cmdline_arg)
{
- is_cmdline_arg= 1;
-
- /* save the separator too if skip unknown options */
- if (my_getopt_skip_unknown)
- (*argv)[argvpos++]= cur_arg;
- else
- (*argc)--;
- continue;
+ if (is_file_marker(cur_arg))
+ {
+ pos++;
+ filename= *pos;
+ is_cmdline_arg= *filename == 0; /* empty file name = command line */
+ if (my_getopt_skip_unknown)
+ {
+ (*argv)[argvpos++]= cur_arg;
+ (*argv)[argvpos++]= filename;
+ }
+ else
+ (*argc)-= 2;
+ continue;
+ }
}
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
{
@@ -408,9 +397,9 @@ int handle_options(int *argc, char ***argv,
DBUG_RETURN(EXIT_OPTION_DISABLED);
}
error= 0;
- value= optp->var_type & GET_ASK_ADDR ?
- (*getopt_get_addr)(key_name, (uint) strlen(key_name), optp, &error) :
- optp->value;
+ value= optp->var_type & GET_ASK_ADDR
+ ? (*my_getopt_get_addr)(key_name, (uint)strlen(key_name), optp, &error)
+ : optp->value;
if (error)
DBUG_RETURN(error);
@@ -453,9 +442,9 @@ int handle_options(int *argc, char ***argv,
my_progname, optp->name, optend);
continue;
}
- if (get_one_option && get_one_option(optp->id, optp,
- *((my_bool*) value) ?
- enabled_my_option : disabled_my_option))
+ if (get_one_option(optp, *((my_bool*) value) ?
+ enabled_my_option : disabled_my_option,
+ filename))
DBUG_RETURN(EXIT_ARGUMENT_INVALID);
continue;
}
@@ -472,12 +461,7 @@ int handle_options(int *argc, char ***argv,
DBUG_RETURN(EXIT_NO_ARGUMENT_ALLOWED);
}
- /*
- We support automatic setup only via get_one_option and only for
- marked options.
- */
- if (!get_one_option ||
- !(optp->var_type & GET_AUTO))
+ if (!(optp->var_type & GET_AUTO))
{
my_getopt_error_reporter(option_is_loose ?
WARNING_LEVEL : ERROR_LEVEL,
@@ -493,10 +477,11 @@ int handle_options(int *argc, char ***argv,
}
else if (optp->arg_type == REQUIRED_ARG && !optend)
{
- /* Check if there are more arguments after this one,
- Note: options loaded from config file that requires value
- should always be in the form '--option=value'.
- */
+ /*
+ Check if there are more arguments after this one,
+ Note: options loaded from config file that requires value
+ should always be in the form '--option=value'.
+ */
if (!is_cmdline_arg || !*++pos)
{
if (my_getopt_print_errors)
@@ -534,7 +519,7 @@ int handle_options(int *argc, char ***argv,
optp->arg_type == NO_ARG)
{
*((my_bool*) optp->value)= (my_bool) 1;
- if (get_one_option && get_one_option(optp->id, optp, argument))
+ if (get_one_option(optp, argument, filename))
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
continue;
}
@@ -554,7 +539,7 @@ int handle_options(int *argc, char ***argv,
{
if (optp->var_type == GET_BOOL)
*((my_bool*) optp->value)= (my_bool) 1;
- if (get_one_option && get_one_option(optp->id, optp, argument))
+ if (get_one_option(optp, argument, filename))
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
continue;
}
@@ -575,7 +560,7 @@ int handle_options(int *argc, char ***argv,
if ((error= setval(optp, optp->value, argument,
set_maximum_value)))
DBUG_RETURN(error);
- if (get_one_option && get_one_option(optp->id, optp, argument))
+ if (get_one_option(optp, argument, filename))
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
break;
}
@@ -622,7 +607,7 @@ int handle_options(int *argc, char ***argv,
((error= setval(optp, value, argument, set_maximum_value))) &&
!option_is_loose)
DBUG_RETURN(error);
- if (get_one_option && get_one_option(optp->id, optp, argument))
+ if (get_one_option(optp, argument, filename))
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
(*argc)--; /* option handled (long), decrease argument count */
@@ -1430,8 +1415,8 @@ static void init_variables(const struct my_option *options,
*/
if (options->u_max_value)
func_init_one_value(options, options->u_max_value, options->max_value);
- value= (options->var_type & GET_ASK_ADDR ?
- (*getopt_get_addr)("", 0, options, 0) : options->value);
+ value= options->var_type & GET_ASK_ADDR ?
+ (*my_getopt_get_addr)("", 0, options, 0) : options->value;
if (value)
func_init_one_value(options, value, options->def_value);
}
@@ -1635,8 +1620,8 @@ void my_print_variables(const struct my_option *options)
for (optp= options; optp->name; optp++)
{
- void *value= (optp->var_type & GET_ASK_ADDR ?
- (*getopt_get_addr)("", 0, optp, 0) : optp->value);
+ void *value= optp->var_type & GET_ASK_ADDR ?
+ (*my_getopt_get_addr)("", 0, optp, 0) : optp->value;
if (value)
{
length= print_name(optp);
diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c
index 18218c2e8de..ce8a9ca786f 100644
--- a/mysys/my_getsystime.c
+++ b/mysys/my_getsystime.c
@@ -21,10 +21,8 @@
#ifdef _WIN32
#define OFFSET_TO_EPOC 116444736000000000LL
static ulonglong query_performance_frequency;
-typedef void (WINAPI* get_system_time_as_filetime_t)(LPFILETIME);
-static get_system_time_as_filetime_t
- my_GetSystemTimePreciseAsFileTime= GetSystemTimeAsFileTime;
#endif
+
#ifdef HAVE_LINUX_UNISTD_H
#include <linux/unistd.h>
#endif
@@ -57,20 +55,12 @@ ulonglong my_interval_timer()
#elif defined(HAVE_GETHRTIME)
return gethrtime();
#elif defined(_WIN32)
+ DBUG_ASSERT(query_performance_frequency);
LARGE_INTEGER t_cnt;
- if (query_performance_frequency)
- {
- QueryPerformanceCounter(&t_cnt);
- return (t_cnt.QuadPart / query_performance_frequency * 1000000000ULL) +
+ QueryPerformanceCounter(&t_cnt);
+ return (t_cnt.QuadPart / query_performance_frequency * 1000000000ULL) +
((t_cnt.QuadPart % query_performance_frequency) * 1000000000ULL /
query_performance_frequency);
- }
- else
- {
- ulonglong newtime;
- my_GetSystemTimePreciseAsFileTime((FILETIME*)&newtime);
- return newtime*100ULL;
- }
#else
/* TODO: check for other possibilities for hi-res timestamping */
struct timeval tv;
@@ -87,7 +77,7 @@ my_hrtime_t my_hrtime()
my_hrtime_t hrtime;
#if defined(_WIN32)
ulonglong newtime;
- my_GetSystemTimePreciseAsFileTime((FILETIME*)&newtime);
+ GetSystemTimePreciseAsFileTime((FILETIME*)&newtime);
hrtime.val= (newtime - OFFSET_TO_EPOC)/10;
#elif defined(HAVE_CLOCK_GETTIME)
struct timespec tp;
@@ -129,14 +119,8 @@ void my_time_init()
#ifdef _WIN32
compile_time_assert(sizeof(LARGE_INTEGER) ==
sizeof(query_performance_frequency));
- if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency) == 0)
- query_performance_frequency= 0;
-
- get_system_time_as_filetime_t f= (get_system_time_as_filetime_t)
- GetProcAddress(GetModuleHandle("kernel32"),
- "GetSystemTimePreciseAsFileTime");
- if (f)
- my_GetSystemTimePreciseAsFileTime= f;
+ QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency);
+ DBUG_ASSERT(query_performance_frequency);
#endif
}
diff --git a/mysys/my_init.c b/mysys/my_init.c
index d8fb2003052..fdde04be084 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -22,14 +22,13 @@
#include <m_ctype.h>
#include <signal.h>
#include <mysql/psi/mysql_stage.h>
-#ifdef __WIN__
+#ifdef _WIN32
#ifdef _MSC_VER
#include <locale.h>
#include <crtdbg.h>
/* WSAStartup needs winsock library*/
#pragma comment(lib, "ws2_32")
#endif
-my_bool have_tcpip=0;
static void my_win_init(void);
static my_bool win32_init_tcp_ip();
#else
@@ -119,8 +118,9 @@ my_bool my_init(void)
my_time_init();
my_win_init();
DBUG_PRINT("exit", ("home: '%s'", home_dir));
-#ifdef __WIN__
- win32_init_tcp_ip();
+#ifdef _WIN32
+ if (win32_init_tcp_ip())
+ DBUG_RETURN(1);
#endif
#ifdef CHECK_UNLIKELY
init_my_likely();
@@ -218,7 +218,7 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
rus.ru_msgsnd, rus.ru_msgrcv, rus.ru_nsignals,
rus.ru_nvcsw, rus.ru_nivcsw);
#endif
-#if defined(__WIN__) && defined(_MSC_VER)
+#if defined(_MSC_VER)
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
@@ -245,10 +245,9 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
(FILE *) 0);
#endif /* defined(SAFE_MUTEX) */
-#ifdef __WIN__
- if (have_tcpip)
- WSACleanup();
-#endif /* __WIN__ */
+#ifdef _WIN32
+ WSACleanup();
+#endif
/* At very last, delete mysys key, it is used everywhere including DBUG */
pthread_key_delete(THR_KEY_mysys);
@@ -263,16 +262,14 @@ void my_debug_put_break_here(void)
}
#endif
-#ifdef __WIN__
+#ifdef _WIN32
/*
my_parameter_handler
Invalid parameter handler we will use instead of the one "baked"
- into the CRT for MSC v8. This one just prints out what invalid
- parameter was encountered. By providing this routine, routines like
- lseek will return -1 when we expect them to instead of crash.
+ into the CRT.
*/
void my_parameter_handler(const wchar_t * expression, const wchar_t * function,
@@ -311,78 +308,14 @@ int handle_rtc_failure(int err_type, const char *file, int line,
#pragma runtime_checks("", restore)
#endif
-/*
- Open HKEY_LOCAL_MACHINE\SOFTWARE\MySQL and set any strings found
- there as environment variables
-*/
-static void win_init_registry(void)
-{
- HKEY key_handle;
-
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)"SOFTWARE\\MySQL",
- 0, KEY_READ, &key_handle) == ERROR_SUCCESS)
- {
- LONG ret;
- DWORD index= 0;
- DWORD type;
- char key_name[256], key_data[1024];
- DWORD key_name_len= sizeof(key_name) - 1;
- DWORD key_data_len= sizeof(key_data) - 1;
-
- while ((ret= RegEnumValue(key_handle, index++,
- key_name, &key_name_len,
- NULL, &type, (LPBYTE)&key_data,
- &key_data_len)) != ERROR_NO_MORE_ITEMS)
- {
- char env_string[sizeof(key_name) + sizeof(key_data) + 2];
-
- if (ret == ERROR_MORE_DATA)
- {
- /* Registry value larger than 'key_data', skip it */
- DBUG_PRINT("error", ("Skipped registry value that was too large"));
- }
- else if (ret == ERROR_SUCCESS)
- {
- if (type == REG_SZ)
- {
- strxmov(env_string, key_name, "=", key_data, NullS);
-
- /* variable for putenv must be allocated ! */
- putenv(strdup(env_string)) ;
- }
- }
- else
- {
- /* Unhandled error, break out of loop */
- break;
- }
-
- key_name_len= sizeof(key_name) - 1;
- key_data_len= sizeof(key_data) - 1;
- }
-
- RegCloseKey(key_handle);
- }
-}
-
static void my_win_init(void)
{
DBUG_ENTER("my_win_init");
#if defined(_MSC_VER)
-#if _MSC_VER < 1300
- /*
- Clear the OS system variable TZ and avoid the 100% CPU usage
- Only for old versions of Visual C++
- */
- _putenv("TZ=");
-#endif
-#if _MSC_VER >= 1400
- /* this is required to make crt functions return -1 appropriately */
_set_invalid_parameter_handler(my_parameter_handler);
#endif
-#endif
#ifdef __MSVC_RUNTIME_CHECKS
/*
@@ -394,75 +327,22 @@ static void my_win_init(void)
_tzset();
- win_init_registry();
-
DBUG_VOID_RETURN;
}
-/*------------------------------------------------------------------
- Name: CheckForTcpip| Desc: checks if tcpip has been installed on system
- According to Microsoft Developers documentation the first registry
- entry should be enough to check if TCP/IP is installed, but as expected
- this doesn't work on all Win32 machines :(
-------------------------------------------------------------------*/
-
-#define TCPIPKEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"
-#define WINSOCK2KEY "SYSTEM\\CurrentControlSet\\Services\\Winsock2\\Parameters"
-#define WINSOCKKEY "SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters"
-
-static my_bool win32_have_tcpip(void)
-{
- HKEY hTcpipRegKey;
- if (RegOpenKeyEx ( HKEY_LOCAL_MACHINE, TCPIPKEY, 0, KEY_READ,
- &hTcpipRegKey) != ERROR_SUCCESS)
- {
- if (RegOpenKeyEx ( HKEY_LOCAL_MACHINE, WINSOCK2KEY, 0, KEY_READ,
- &hTcpipRegKey) != ERROR_SUCCESS)
- {
- if (RegOpenKeyEx ( HKEY_LOCAL_MACHINE, WINSOCKKEY, 0, KEY_READ,
- &hTcpipRegKey) != ERROR_SUCCESS)
- if (!getenv("HAVE_TCPIP") || have_tcpip) /* Provide a workaround */
- return (FALSE);
- }
- }
- RegCloseKey ( hTcpipRegKey);
- return (TRUE);
-}
-
-
static my_bool win32_init_tcp_ip()
{
- if (win32_have_tcpip())
+ WORD wVersionRequested = MAKEWORD( 2, 2 );
+ WSADATA wsaData;
+ if (WSAStartup(wVersionRequested, &wsaData))
{
- WORD wVersionRequested = MAKEWORD( 2, 2 );
- WSADATA wsaData;
- /* Be a good citizen: maybe another lib has already initialised
- sockets, so don't clobber them unless necessary */
- if (WSAStartup( wVersionRequested, &wsaData ))
- {
- /* Load failed, maybe because of previously loaded
- incompatible version; try again */
- WSACleanup( );
- if (!WSAStartup( wVersionRequested, &wsaData ))
- have_tcpip=1;
- }
- else
- {
- if (wsaData.wVersion != wVersionRequested)
- {
- /* Version is no good, try again */
- WSACleanup( );
- if (!WSAStartup( wVersionRequested, &wsaData ))
- have_tcpip=1;
- }
- else
- have_tcpip=1;
- }
+ fprintf(stderr, "WSAStartup() failed with error: %d\n", WSAGetLastError());
+ return 1;
}
return(0);
}
-#endif /* __WIN__ */
+#endif /* _WIN32 */
PSI_stage_info stage_waiting_for_table_level_lock=
{0, "Waiting for table level lock", 0};
diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c
index e2795ed7bb9..ac6d3f87de3 100644
--- a/mysys/my_pthread.c
+++ b/mysys/my_pthread.c
@@ -405,3 +405,66 @@ int pthread_dummy(int ret)
{
return ret;
}
+
+
+/*
+ pthread_attr_setstacksize() without so much platform-dependency
+
+ Return: The actual stack size if possible.
+*/
+
+size_t my_setstacksize(pthread_attr_t *attr, size_t stacksize)
+{
+ size_t guard_size __attribute__((unused))= 0;
+
+#if defined(__ia64__) || defined(__ia64)
+ /*
+ On IA64, half of the requested stack size is used for "normal stack"
+ and half for "register stack". The space measured by check_stack_overrun
+ is the "normal stack", so double the request to make sure we have the
+ caller-expected amount of normal stack.
+
+ NOTE: there is no guarantee that the register stack can't grow faster
+ than normal stack, so it's very unclear that we won't dump core due to
+ stack overrun despite check_stack_overrun's efforts. Experimentation
+ shows that in the execution_constants test, the register stack grows
+ less than half as fast as normal stack, but perhaps other scenarios are
+ less forgiving. If it turns out that more space is needed for the
+ register stack, that could be forced (rather inefficiently) by using a
+ multiplier higher than 2 here.
+ */
+ stacksize *= 2;
+#endif
+
+ /*
+ On many machines, the "guard space" is subtracted from the requested
+ stack size, and that space is quite large on some platforms. So add
+ it to our request, if we can find out what it is.
+ */
+#ifdef HAVE_PTHREAD_ATTR_GETGUARDSIZE
+ if (pthread_attr_getguardsize(attr, &guard_size))
+ guard_size = 0; /* if can't find it out, treat as 0 */
+#endif /* HAVE_PTHREAD_ATTR_GETGUARDSIZE */
+
+ pthread_attr_setstacksize(attr, stacksize + guard_size);
+
+ /* Retrieve actual stack size if possible */
+#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
+ {
+ size_t real_stack_size= 0;
+ /* We must ignore real_stack_size = 0 as Solaris 2.9 can return 0 here */
+ if (pthread_attr_getstacksize(attr, &real_stack_size) == 0 &&
+ real_stack_size > guard_size)
+ {
+ real_stack_size -= guard_size;
+ if (real_stack_size < stacksize)
+ stacksize= real_stack_size;
+ }
+ }
+#endif /* HAVE_PTHREAD_ATTR_GETSTACKSIZE */
+
+#if defined(__ia64__) || defined(__ia64)
+ stacksize /= 2;
+#endif
+ return stacksize;
+}
diff --git a/mysys/my_winfile.c b/mysys/my_winfile.c
index 0c76eb25560..9c8d747adc9 100644
--- a/mysys/my_winfile.c
+++ b/mysys/my_winfile.c
@@ -501,13 +501,12 @@ static File my_get_stdfile_descriptor(FILE *stream)
}
-File my_win_fileno(FILE *file)
+File my_win_handle2File(HANDLE hFile)
{
- HANDLE hFile= (HANDLE)_get_osfhandle(fileno(file));
int retval= -1;
uint i;
- DBUG_ENTER("my_win_fileno");
+ DBUG_ENTER("my_win_handle2File");
for(i= MY_FILE_MIN; i < my_file_limit; i++)
{
@@ -517,6 +516,14 @@ File my_win_fileno(FILE *file)
break;
}
}
+ DBUG_RETURN(retval);
+}
+
+
+File my_win_fileno(FILE *file)
+{
+ DBUG_ENTER("my_win_fileno");
+ int retval= my_win_handle2File((HANDLE) _get_osfhandle(fileno(file)));
if(retval == -1)
/* try std stream */
DBUG_RETURN(my_get_stdfile_descriptor(file));
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index 2274c505195..19dcdf11dd5 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -14,12 +14,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
-#include <my_global.h>
+#include "mysys_priv.h"
#include <my_stacktrace.h>
#ifndef __WIN__
#include <signal.h>
-#include <my_pthread.h>
#include <m_string.h>
#ifdef HAVE_STACKTRACE
#include <unistd.h>
@@ -42,11 +41,49 @@ static char *heap_start;
extern char *__bss_start;
#endif
-void my_init_stacktrace()
+/**
+ Default handler for printing stacktrace
+*/
+
+static sig_handler default_handle_fatal_signal(int sig)
+{
+ my_safe_printf_stderr("%s: Got signal %d. Attempting backtrace\n",
+ my_progname_short, sig);
+ my_print_stacktrace(0,0,1);
+#ifndef __WIN__
+ signal(sig, SIG_DFL);
+ kill(getpid(), sig);
+#endif /* __WIN__ */
+ return;
+}
+
+
+/**
+ Initialize priting off stacktrace at signal
+
+ @param setup_handlers 0 only initialize variables
+ 1 setup signal handlers for stacktrace printing
+*/
+
+void my_init_stacktrace(int setup_handlers)
{
#if(defined HAVE_BSS_START) && !(defined __linux__)
heap_start = (char*) &__bss_start;
#endif
+ if (setup_handlers)
+ {
+ struct sigaction sa;
+ sa.sa_flags = SA_RESETHAND | SA_NODEFER;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler= default_handle_fatal_signal;
+ sigaction(SIGSEGV, &sa, NULL);
+ sigaction(SIGABRT, &sa, NULL);
+#ifdef SIGBUS
+ sigaction(SIGBUS, &sa, NULL);
+#endif
+ sigaction(SIGILL, &sa, NULL);
+ sigaction(SIGFPE, &sa, NULL);
+ }
}
#ifdef __linux__
@@ -510,7 +547,7 @@ static EXCEPTION_POINTERS *exception_ptrs;
#define MODULE64_SIZE_WINXP 576
#define STACKWALK_MAX_FRAMES 64
-void my_init_stacktrace()
+void my_init_stacktrace(int setup_handlers __attribute__((unused)))
{
}
diff --git a/mysys/thr_rwlock.c b/mysys/thr_rwlock.c
index ea8b73bf8f5..a8711d517f9 100644
--- a/mysys/thr_rwlock.c
+++ b/mysys/thr_rwlock.c
@@ -21,116 +21,66 @@
#ifdef _WIN32
-static BOOL have_srwlock= FALSE;
-/* Prototypes and function pointers for windows functions */
-typedef VOID (WINAPI* srw_func) (PSRWLOCK SRWLock);
-typedef BOOLEAN (WINAPI* srw_bool_func) (PSRWLOCK SRWLock);
-
-static srw_func my_InitializeSRWLock;
-static srw_func my_AcquireSRWLockExclusive;
-static srw_func my_ReleaseSRWLockExclusive;
-static srw_func my_AcquireSRWLockShared;
-static srw_func my_ReleaseSRWLockShared;
-
-static srw_bool_func my_TryAcquireSRWLockExclusive;
-static srw_bool_func my_TryAcquireSRWLockShared;
-
-/**
- Check for presence of Windows slim reader writer lock function.
- Load function pointers.
-*/
-
-static void check_srwlock_availability(void)
-{
- HMODULE module= GetModuleHandle("kernel32");
-
- my_InitializeSRWLock= (srw_func) GetProcAddress(module,
- "InitializeSRWLock");
- my_AcquireSRWLockExclusive= (srw_func) GetProcAddress(module,
- "AcquireSRWLockExclusive");
- my_AcquireSRWLockShared= (srw_func) GetProcAddress(module,
- "AcquireSRWLockShared");
- my_ReleaseSRWLockExclusive= (srw_func) GetProcAddress(module,
- "ReleaseSRWLockExclusive");
- my_ReleaseSRWLockShared= (srw_func) GetProcAddress(module,
- "ReleaseSRWLockShared");
- my_TryAcquireSRWLockExclusive= (srw_bool_func) GetProcAddress(module,
- "TryAcquireSRWLockExclusive");
- my_TryAcquireSRWLockShared= (srw_bool_func) GetProcAddress(module,
- "TryAcquireSRWLockShared");
-
- /*
- We currently require TryAcquireSRWLockExclusive. This API is missing on
- Vista, this means SRWLock are only used starting with Win7.
-
- If "trylock" usage for rwlocks is eliminated from server codebase (it is used
- in a single place currently, in query cache), then SRWLock can be enabled on
- Vista too. In this case condition below needs to be changed to e.g check
- for my_InitializeSRWLock.
- */
-
- if (my_TryAcquireSRWLockExclusive)
- have_srwlock= TRUE;
-
-}
-
-
-static int srw_init(my_rw_lock_t *rwp)
+int my_rw_init(my_rw_lock_t *rwp)
{
- my_InitializeSRWLock(&rwp->srwlock);
+ InitializeSRWLock(&rwp->srwlock);
rwp->have_exclusive_srwlock = FALSE;
return 0;
}
-static int srw_rdlock(my_rw_lock_t *rwp)
+int my_rw_rdlock(my_rw_lock_t *rwp)
{
- my_AcquireSRWLockShared(&rwp->srwlock);
+ AcquireSRWLockShared(&rwp->srwlock);
return 0;
}
-static int srw_tryrdlock(my_rw_lock_t *rwp)
+int my_rw_tryrdlock(my_rw_lock_t *rwp)
{
-
- if (!my_TryAcquireSRWLockShared(&rwp->srwlock))
+ if (!TryAcquireSRWLockShared(&rwp->srwlock))
return EBUSY;
return 0;
}
-static int srw_wrlock(my_rw_lock_t *rwp)
+int my_rw_wrlock(my_rw_lock_t *rwp)
{
- my_AcquireSRWLockExclusive(&rwp->srwlock);
+ AcquireSRWLockExclusive(&rwp->srwlock);
rwp->have_exclusive_srwlock= TRUE;
return 0;
}
-
-static int srw_trywrlock(my_rw_lock_t *rwp)
+int my_rw_trywrlock(my_rw_lock_t *rwp)
{
- if (!my_TryAcquireSRWLockExclusive(&rwp->srwlock))
+ if (!TryAcquireSRWLockExclusive(&rwp->srwlock))
return EBUSY;
rwp->have_exclusive_srwlock= TRUE;
return 0;
}
-static int srw_unlock(my_rw_lock_t *rwp)
+int my_rw_unlock(my_rw_lock_t *rwp)
{
if (rwp->have_exclusive_srwlock)
{
rwp->have_exclusive_srwlock= FALSE;
- my_ReleaseSRWLockExclusive(&rwp->srwlock);
+ ReleaseSRWLockExclusive(&rwp->srwlock);
}
else
{
- my_ReleaseSRWLockShared(&rwp->srwlock);
+ ReleaseSRWLockShared(&rwp->srwlock);
}
return 0;
}
-#endif /*_WIN32 */
+int my_rw_destroy(my_rw_lock_t* rwp)
+{
+ DBUG_ASSERT(!rwp->have_exclusive_srwlock);
+ return 0;
+}
+
+#else
/*
Source base from Sun Microsystems SPILT, simplified for MySQL use
@@ -175,22 +125,6 @@ int my_rw_init(my_rw_lock_t *rwp)
{
pthread_condattr_t cond_attr;
-#ifdef _WIN32
- /*
- Once initialization is used here rather than in my_init(), in order to
- - avoid my_init() pitfalls- (undefined order in which initialization should
- run)
- - be potentially useful C++ (static constructors)
- - just to simplify the API.
- Also, the overhead is of my_pthread_once is very small.
- */
- static my_pthread_once_t once_control= MY_PTHREAD_ONCE_INIT;
- my_pthread_once(&once_control, check_srwlock_availability);
-
- if (have_srwlock)
- return srw_init(rwp);
-#endif
-
pthread_mutex_init( &rwp->lock, MY_MUTEX_INIT_FAST);
pthread_condattr_init( &cond_attr );
pthread_cond_init( &rwp->readers, &cond_attr );
@@ -209,10 +143,6 @@ int my_rw_init(my_rw_lock_t *rwp)
int my_rw_destroy(my_rw_lock_t *rwp)
{
-#ifdef _WIN32
- if (have_srwlock)
- return 0; /* no destroy function */
-#endif
DBUG_ASSERT(rwp->state == 0);
pthread_mutex_destroy( &rwp->lock );
pthread_cond_destroy( &rwp->readers );
@@ -223,11 +153,6 @@ int my_rw_destroy(my_rw_lock_t *rwp)
int my_rw_rdlock(my_rw_lock_t *rwp)
{
-#ifdef _WIN32
- if (have_srwlock)
- return srw_rdlock(rwp);
-#endif
-
pthread_mutex_lock(&rwp->lock);
/* active or queued writers */
@@ -242,12 +167,6 @@ int my_rw_rdlock(my_rw_lock_t *rwp)
int my_rw_tryrdlock(my_rw_lock_t *rwp)
{
int res;
-
-#ifdef _WIN32
- if (have_srwlock)
- return srw_tryrdlock(rwp);
-#endif
-
pthread_mutex_lock(&rwp->lock);
if ((rwp->state < 0 ) || rwp->waiters)
res= EBUSY; /* Can't get lock */
@@ -263,11 +182,6 @@ int my_rw_tryrdlock(my_rw_lock_t *rwp)
int my_rw_wrlock(my_rw_lock_t *rwp)
{
-#ifdef _WIN32
- if (have_srwlock)
- return srw_wrlock(rwp);
-#endif
-
pthread_mutex_lock(&rwp->lock);
rwp->waiters++; /* another writer queued */
@@ -289,11 +203,6 @@ int my_rw_trywrlock(my_rw_lock_t *rwp)
{
int res;
-#ifdef _WIN32
- if (have_srwlock)
- return srw_trywrlock(rwp);
-#endif
-
pthread_mutex_lock(&rwp->lock);
if (rwp->state)
res= EBUSY; /* Can't get lock */
@@ -312,11 +221,6 @@ int my_rw_trywrlock(my_rw_lock_t *rwp)
int my_rw_unlock(my_rw_lock_t *rwp)
{
-#ifdef _WIN32
- if (have_srwlock)
- return srw_unlock(rwp);
-#endif
-
DBUG_PRINT("rw_unlock",
("state: %d waiters: %d", rwp->state, rwp->waiters));
pthread_mutex_lock(&rwp->lock);
@@ -347,7 +251,8 @@ int my_rw_unlock(my_rw_lock_t *rwp)
return(0);
}
-#endif /* defined(NEED_MY_RW_LOCK) */
+#endif /* !defined _WIN32 */
+#endif /* NEED_MY_RW_LOCK*/
int rw_pr_init(rw_pr_lock_t *rwlock)
diff --git a/mysys/thr_timer.c b/mysys/thr_timer.c
index 1532875d7f3..f87c1f75555 100644
--- a/mysys/thr_timer.c
+++ b/mysys/thr_timer.c
@@ -85,7 +85,7 @@ my_bool init_thr_timer(uint alloc_timers)
/* Create a thread to handle timers */
pthread_attr_init(&thr_attr);
pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
- pthread_attr_setstacksize(&thr_attr,8196);
+ pthread_attr_setstacksize(&thr_attr,64*1024);
thr_timer_inited= 1;
if (mysql_thread_create(key_thread_timer, &timer_thread, &thr_attr,
timer_handler, NULL))
@@ -141,6 +141,18 @@ void thr_timer_init(thr_timer_t *timer_data, void(*function)(void*),
DBUG_VOID_RETURN;
}
+/*
+ Make timer periodic
+
+ @param timer_data Timer structure
+ @param micro_seconds Period
+*/
+void thr_timer_set_period(thr_timer_t* timer_data, ulonglong micro_seconds)
+{
+ DBUG_ENTER("thr_timer_set_period");
+ timer_data->period= micro_seconds;
+ DBUG_VOID_RETURN;
+}
/*
Request timer after X milliseconds
@@ -240,18 +252,35 @@ static sig_handler process_timers(struct timespec *now)
{
void (*function)(void*);
void *func_arg;
+ my_bool is_periodic;
timer_data= (thr_timer_t*) queue_top(&timer_queue);
function= timer_data->func;
func_arg= timer_data->func_arg;
+ is_periodic= timer_data->period != 0;
timer_data->expired= 1; /* Mark expired */
/*
We remove timer before calling timer function to allow thread to
delete it's timer data any time.
+
+ Deleting timer inside the callback would not work
+ for periodic timers, they need to be removed from
+ queue prior to destroying timer_data.
*/
queue_remove_top(&timer_queue); /* Remove timer */
(*function)(func_arg); /* Inform thread of timeout */
+ /*
+ If timer is periodic, recalculate next expiration time, and
+ reinsert it into the queue.
+ */
+ if (is_periodic && timer_data->period)
+ {
+ set_timespec_nsec(timer_data->expire_time, timer_data->period * 1000);
+ timer_data->expired= 0;
+ queue_insert(&timer_queue, (uchar*)timer_data);
+ }
+
/* Check if next one has also expired */
timer_data= (thr_timer_t*) queue_top(&timer_queue);
if (cmp_timespec(timer_data->expire_time, (*now)) > 0)
diff --git a/mysys/typelib.c b/mysys/typelib.c
index f0037921a87..715e7ad42ba 100644
--- a/mysys/typelib.c
+++ b/mysys/typelib.c
@@ -226,7 +226,7 @@ my_ulonglong find_typeset(char *x, TYPELIB *lib, int *err)
NULL otherwise
*/
-TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from)
+TYPELIB *copy_typelib(MEM_ROOT *root, const TYPELIB *from)
{
TYPELIB *to;
uint i;