diff options
Diffstat (limited to 'sql/tztime.cc')
-rw-r--r-- | sql/tztime.cc | 154 |
1 files changed, 93 insertions, 61 deletions
diff --git a/sql/tztime.cc b/sql/tztime.cc index 81a80686de2..504decd9e7c 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1,5 +1,4 @@ -/* - Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 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 @@ -12,8 +11,7 @@ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Most of the following code and structures were derived from @@ -22,7 +20,7 @@ */ /* - We should not include mysql_priv.h in mysql_tzinfo_to_sql utility since + We should not include sql_priv.h in mysql_tzinfo_to_sql utility since it creates unsolved link dependencies on some platforms. */ @@ -32,7 +30,12 @@ #include <my_global.h> #if !defined(TZINFO2SQL) && !defined(TESTTIME) -#include "mysql_priv.h" +#include "sql_priv.h" +#include "unireg.h" +#include "tztime.h" +#include "sql_time.h" // localtime_to_TIME +#include "sql_base.h" // open_system_tables_for_read, + // close_system_tables #else #include <my_time.h> #include "tztime.h" @@ -42,6 +45,9 @@ #include "tzfile.h" #include <m_string.h> #include <my_dir.h> +#include <mysql/psi/mysql_file.h> +#include "lock.h" // MYSQL_LOCK_IGNORE_FLUSH, + // MYSQL_LOCK_IGNORE_TIMEOUT /* Now we don't use abbreviations in server but we will do this in future. @@ -158,9 +164,9 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage) uchar *p; int read_from_file; uint i; - FILE *file; + MYSQL_FILE *file; - if (!(file= my_fopen(name, O_RDONLY|O_BINARY, MYF(MY_WME)))) + if (!(file= mysql_file_fopen(0, name, O_RDONLY|O_BINARY, MYF(MY_WME)))) return 1; { union @@ -177,9 +183,9 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage) uint ttisgmtcnt; char *tzinfo_buf; - read_from_file= my_fread(file, u.buf, sizeof(u.buf), MYF(MY_WME)); + read_from_file= mysql_file_fread(file, u.buf, sizeof(u.buf), MYF(MY_WME)); - if (my_fclose(file, MYF(MY_WME)) != 0) + if (mysql_file_fclose(file, MYF(MY_WME)) != 0) return 1; if (read_from_file < (int)sizeof(struct tzhead)) @@ -1434,7 +1440,7 @@ static MEM_ROOT tz_storage; time zone in offset_tzs or creating if it didn't existed before in tz_storage. So contention is low. */ -static pthread_mutex_t tz_LOCK; +static mysql_mutex_t tz_LOCK; static bool tz_inited= 0; /* @@ -1534,6 +1540,27 @@ tz_init_table_list(TABLE_LIST *tz_tabs) } } +#ifdef HAVE_PSI_INTERFACE +static PSI_mutex_key key_tz_LOCK; + +static PSI_mutex_info all_tz_mutexes[]= +{ + { & key_tz_LOCK, "tz_LOCK", PSI_FLAG_GLOBAL} +}; + +static void init_tz_psi_keys(void) +{ + const char* category= "sql"; + int count; + + if (PSI_server == NULL) + return; + + count= array_elements(all_tz_mutexes); + PSI_server->register_mutex(category, all_tz_mutexes, count); +} +#endif /* HAVE_PSI_INTERFACE */ + /* Initialize time zone support infrastructure. @@ -1565,7 +1592,6 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) { THD *thd; TABLE_LIST tz_tables[1+MY_TZ_TABLES_COUNT]; - Open_tables_state open_tables_state_backup; TABLE *table; Tz_names_entry *tmp_tzname; my_bool return_val= 1; @@ -1573,6 +1599,10 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) int res; DBUG_ENTER("my_tz_init"); +#ifdef HAVE_PSI_INTERFACE + init_tz_psi_keys(); +#endif + /* To be able to run this from boot, we allocate a temporary THD */ @@ -1580,24 +1610,23 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) DBUG_RETURN(1); thd->thread_stack= (char*) &thd; thd->store_globals(); - lex_start(thd); /* Init all memory structures that require explicit destruction */ - if (hash_init(&tz_names, &my_charset_latin1, 20, - 0, 0, (hash_get_key) my_tz_names_get_key, 0, 0)) + if (my_hash_init(&tz_names, &my_charset_latin1, 20, + 0, 0, (my_hash_get_key) my_tz_names_get_key, 0, 0)) { sql_print_error("Fatal error: OOM while initializing time zones"); goto end; } - if (hash_init(&offset_tzs, &my_charset_latin1, 26, 0, 0, - (hash_get_key)my_offset_tzs_get_key, 0, 0)) + if (my_hash_init(&offset_tzs, &my_charset_latin1, 26, 0, 0, + (my_hash_get_key)my_offset_tzs_get_key, 0, 0)) { sql_print_error("Fatal error: OOM while initializing time zones"); - hash_free(&tz_names); + my_hash_free(&tz_names); goto end; } - init_alloc_root(&tz_storage, 32 * 1024, 0); - VOID(pthread_mutex_init(&tz_LOCK, MY_MUTEX_INIT_FAST)); + init_sql_alloc(&tz_storage, 32 * 1024, 0); + mysql_mutex_init(key_tz_LOCK, &tz_LOCK, MY_MUTEX_INIT_FAST); tz_inited= 1; /* Add 'SYSTEM' time zone to tz_names hash */ @@ -1639,20 +1668,29 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) tz_init_table_list(tz_tables+1); tz_tables[0].next_global= tz_tables[0].next_local= &tz_tables[1]; tz_tables[1].prev_global= &tz_tables[0].next_global; + init_mdl_requests(tz_tables); /* We need to open only mysql.time_zone_leap_second, but we try to open all time zone tables to see if they exist. */ - if (open_system_tables_for_read(thd, tz_tables, &open_tables_state_backup)) + if (open_and_lock_tables(thd, tz_tables, FALSE, + MYSQL_OPEN_IGNORE_FLUSH | MYSQL_LOCK_IGNORE_TIMEOUT)) { sql_print_warning("Can't open and lock time zone table: %s " - "trying to live without them", thd->main_da.message()); + "trying to live without them", thd->stmt_da->message()); /* We will try emulate that everything is ok */ return_val= time_zone_tables_exist= 0; goto end_with_setting_default_tz; } + for (TABLE_LIST *tl= tz_tables; tl; tl= tl->next_global) + { + tl->table->use_all_columns(); + /* Force close at the end of the function to free memory. */ + tl->table->m_needs_reopen= TRUE; + } + /* Now we are going to load leap seconds descriptions that are shared between all time zones that use them. We are using index for getting @@ -1668,14 +1706,11 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) } table= tz_tables[0].table; - /* - It is OK to ignore ha_index_init()/ha_index_end() return values since - mysql.time_zone* tables are MyISAM and these operations always succeed - for MyISAM. - */ - (void)table->file->ha_index_init(0, 1); - table->use_all_columns(); + if (table->file->ha_index_init(0, 1)) + goto end_with_close; + + table->use_all_columns(); tz_leapcnt= 0; res= table->file->index_first(table->record[0]); @@ -1739,10 +1774,7 @@ end_with_setting_default_tz: end_with_close: if (time_zone_tables_exist) - { - thd->version--; /* Force close to free memory */ - close_system_tables(thd, &open_tables_state_backup); - } + close_mysql_tables(thd); end_with_cleanup: @@ -1759,6 +1791,10 @@ end: my_pthread_setspecific_ptr(THR_THD, 0); my_pthread_setspecific_ptr(THR_MALLOC, 0); } + + default_tz= default_tz_name ? global_system_variables.time_zone + : my_tz_SYSTEM; + DBUG_RETURN(return_val); } @@ -1775,9 +1811,9 @@ void my_tz_free() if (tz_inited) { tz_inited= 0; - VOID(pthread_mutex_destroy(&tz_LOCK)); - hash_free(&offset_tzs); - hash_free(&tz_names); + mysql_mutex_destroy(&tz_LOCK); + my_hash_free(&offset_tzs); + my_hash_free(&tz_names); free_root(&tz_storage, MYF(0)); } } @@ -1845,12 +1881,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) tz_tables= tz_tables->next_local; table->field[0]->store(tz_name->ptr(), tz_name->length(), &my_charset_latin1); - /* - It is OK to ignore ha_index_init()/ha_index_end() return values since - mysql.time_zone* tables are MyISAM and these operations always succeed - for MyISAM. - */ - (void)table->file->ha_index_init(0, 1); + if (table->file->ha_index_init(0, 1)) + goto end; if (table->file->index_read_map(table->record[0], table->field[0]->ptr, HA_WHOLE_KEY, HA_READ_KEY_EXACT)) @@ -1878,7 +1910,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) table= tz_tables->table; tz_tables= tz_tables->next_local; table->field[0]->store((longlong) tzid, TRUE); - (void)table->file->ha_index_init(0, 1); + if (table->file->ha_index_init(0, 1)) + goto end; if (table->file->index_read_map(table->record[0], table->field[0]->ptr, HA_WHOLE_KEY, HA_READ_KEY_EXACT)) @@ -1905,7 +1938,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) table= tz_tables->table; tz_tables= tz_tables->next_local; table->field[0]->store((longlong) tzid, TRUE); - (void)table->file->ha_index_init(0, 1); + if (table->file->ha_index_init(0, 1)) + goto end; res= table->file->index_read_map(table->record[0], table->field[0]->ptr, (key_part_map)1, HA_READ_KEY_EXACT); @@ -1976,7 +2010,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) */ table= tz_tables->table; table->field[0]->store((longlong) tzid, TRUE); - (void)table->file->ha_index_init(0, 1); + if (table->file->ha_index_init(0, 1)) + goto end; res= table->file->index_read_map(table->record[0], table->field[0]->ptr, (key_part_map)1, HA_READ_KEY_EXACT); @@ -2111,8 +2146,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) end: - if (table) - (void)table->file->ha_index_end(); + if (table && table->file->inited) + (void) table->file->ha_index_end(); DBUG_RETURN(return_val); } @@ -2249,14 +2284,14 @@ my_tz_find(THD *thd, const String *name) if (!name || name->is_empty()) DBUG_RETURN(0); - VOID(pthread_mutex_lock(&tz_LOCK)); + mysql_mutex_lock(&tz_LOCK); if (!str_to_offset(name->ptr(), name->length(), &offset)) { - if (!(result_tz= (Time_zone_offset *)hash_search(&offset_tzs, - (const uchar *)&offset, - sizeof(long)))) + if (!(result_tz= (Time_zone_offset *)my_hash_search(&offset_tzs, + (const uchar *)&offset, + sizeof(long)))) { DBUG_PRINT("info", ("Creating new Time_zone_offset object")); @@ -2272,16 +2307,18 @@ my_tz_find(THD *thd, const String *name) else { result_tz= 0; - if ((tmp_tzname= (Tz_names_entry *)hash_search(&tz_names, - (const uchar *)name->ptr(), - name->length()))) + if ((tmp_tzname= (Tz_names_entry *)my_hash_search(&tz_names, + (const uchar *) + name->ptr(), + name->length()))) result_tz= tmp_tzname->tz; else if (time_zone_tables_exist) { TABLE_LIST tz_tables[MY_TZ_TABLES_COUNT]; - Open_tables_state open_tables_state_backup; + Open_tables_backup open_tables_state_backup; tz_init_table_list(tz_tables); + init_mdl_requests(tz_tables); if (!open_system_tables_for_read(thd, tz_tables, &open_tables_state_backup)) { @@ -2291,7 +2328,7 @@ my_tz_find(THD *thd, const String *name) } } - VOID(pthread_mutex_unlock(&tz_LOCK)); + mysql_mutex_unlock(&tz_LOCK); DBUG_RETURN(result_tz); } @@ -2485,7 +2522,6 @@ scan_tz_dir(char * name_end) int main(int argc, char **argv) { -#ifndef __NETWARE__ MY_INIT(argv[0]); if (argc != 2 && argc != 3) @@ -2544,10 +2580,6 @@ main(int argc, char **argv) free_root(&tz_storage, MYF(0)); } -#else - fprintf(stderr, "This tool has not been ported to NetWare\n"); -#endif /* __NETWARE__ */ - return 0; } |