From b01e8b2eecd1841865102346a6b9fb8351dc8266 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 6 Jan 2016 13:21:07 +0200 Subject: [PATCH] Added utils library initialization function and improved replace_quoted Currently the initialization function only prepares PCRE2 patterns for use. Added the call to the new utils_init() function to MaxScale and all relevant tests. The replace_quoted now uses a shared PCRE2 pattern which should remove some of the overhead of the function. --- server/core/gateway.c | 9 +++++ utils/skygw_utils.cc | 89 ++++++++++++++++++++++++++----------------- utils/skygw_utils.h | 2 + 3 files changed, 65 insertions(+), 35 deletions(-) diff --git a/server/core/gateway.c b/server/core/gateway.c index 5aadda73f..fdfb8435b 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -1574,6 +1574,14 @@ int main(int argc, char **argv) goto return_main; } + if (!utils_init()) + { + char* logerr = "Failed to initialise utility library."; + print_log_n_stderr(true, true, logerr, logerr, eno); + rc = MAXSCALE_INTERNALERROR; + goto return_main; + } + /** OpenSSL initialization */ if (!HAVE_OPENSSL_THREADS) { @@ -1939,6 +1947,7 @@ int main(int argc, char **argv) /** Release mysql thread context*/ mysql_thread_end(); + utils_end(); datadir_cleanup(); MXS_NOTICE("MaxScale shutdown completed."); diff --git a/utils/skygw_utils.cc b/utils/skygw_utils.cc index e04617cad..0c59b585d 100644 --- a/utils/skygw_utils.cc +++ b/utils/skygw_utils.cc @@ -2122,6 +2122,9 @@ retblock: return newstr; } +static pcre2_code* replace_quoted_re = NULL; +static const PCRE2_SPTR replace_quoted_pattern = (PCRE2_SPTR) "(['\"])[^'\"]+(['\"])"; + /** * Replace everything inside single or double quotes with question marks. * @param str String to modify @@ -2129,52 +2132,35 @@ retblock: */ char* replace_quoted(const char* str) { - PCRE2_SIZE erroffset; - int errcore; - static const PCRE2_SPTR pattern = (PCRE2_SPTR) "(['\"])[^'\"]+(['\"])"; static const PCRE2_SPTR replace = (PCRE2_SPTR) "$1?$2"; - pcre2_code* re; pcre2_match_data* mdata; - int orig_len = strlen(str); - size_t len = strlen(str); + size_t orig_len = strlen(str); + size_t len = orig_len; char* output; - if ((output = (char*) malloc(len * sizeof(char)))) + if ((output = (char*) malloc(len * sizeof (char))) && + (mdata = pcre2_match_data_create_from_pattern(replace_quoted_re, NULL))) { - /** TODO: Consider moving pattern compilation to some init function. */ - if ((re = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED, - 0, &errcore, &erroffset, NULL))) + while (pcre2_substitute(replace_quoted_re, (PCRE2_SPTR) str, orig_len, 0, + PCRE2_SUBSTITUTE_GLOBAL, mdata, NULL, + replace, PCRE2_ZERO_TERMINATED, + (PCRE2_UCHAR8*) output, &len) == PCRE2_ERROR_NOMEMORY) { - if ((mdata = pcre2_match_data_create_from_pattern(re, NULL))) - { - while (pcre2_substitute(re, (PCRE2_SPTR) str, orig_len, 0, - PCRE2_SUBSTITUTE_GLOBAL, mdata, NULL, - replace, PCRE2_ZERO_TERMINATED, - (PCRE2_UCHAR8*) output, &len) == PCRE2_ERROR_NOMEMORY) - { - char* tmp = (char*) realloc(output, len *= 2); - if (tmp == NULL) - { - free(output); - output = NULL; - break; - } - output = tmp; - } - pcre2_match_data_free(mdata); - } - else + char* tmp = (char*) realloc(output, len *= 2); + if (tmp == NULL) { free(output); output = NULL; + break; } - pcre2_code_free(re); - } - else - { - free(output); - output = NULL; + output = tmp; } + pcre2_match_data_free(mdata); + } + else + { + free(output); + output = NULL; } return output; } @@ -2267,3 +2253,36 @@ int simple_str_hash(char* key) return hash; } + +/** + * Initialize the utils library + * + * This function initializes structures used in various functions. + * @return true on success, false on error + */ +bool utils_init() +{ + bool rval = true; + + PCRE2_SIZE erroffset; + int errcore; + + ss_info_dassert(replace_quoted_re == NULL, "utils_init called multiple times"); + replace_quoted_re = pcre2_compile(replace_quoted_pattern, PCRE2_ZERO_TERMINATED, 0, &errcore, + &erroffset, NULL); + if (replace_quoted_re == NULL) + { + rval = false; + } + + return rval; +} + +/** + * Close the utils library. This should be the last call to this library. + */ +void utils_end() +{ + pcre2_code_free(replace_quoted_re); + replace_quoted_re = NULL; +} diff --git a/utils/skygw_utils.h b/utils/skygw_utils.h index 083842291..68a0f9384 100644 --- a/utils/skygw_utils.h +++ b/utils/skygw_utils.h @@ -158,6 +158,8 @@ struct skygw_file_st { EXTERN_C_BLOCK_BEGIN +bool utils_init(); /*< Call this first before using any other function */ +void utils_end(); slist_cursor_t* slist_init(void); void slist_done(slist_cursor_t* c); size_t slist_size(slist_cursor_t* c);