From 0eaf4d8d7e879b32d5e1e0c7ecb409bc4d4cb060 Mon Sep 17 00:00:00 2001
From: unknown <monty@narttu.mysql.fi>
Date: Sun, 17 Aug 2003 14:10:15 +0300
Subject: [PATCH] Fix mutex handling in SHOW_VARIABLES (key_buffer_size was not
 properly protected) Changed some non fatal myisamchk error messages to
 warnings

myisam/myisamchk.c:
  Change error -> warning
sql/handler.cc:
  Add mutex around keybuff_size usage
sql/mysql_priv.h:
  Indentation update
sql/set_var.cc:
  Add mutex around longlong variable usage
sql/sql_parse.cc:
  Fix mutex handling in SHOW_VARIABLES
sql/sql_show.cc:
  Fix mutex handling in SHOW_VARIABLES
---
 myisam/myisamchk.c |  9 +++++----
 sql/handler.cc     | 17 ++++++++++++++---
 sql/mysql_priv.h   |  3 ++-
 sql/set_var.cc     | 22 ++++++++++++++++++++--
 sql/sql_parse.cc   |  5 +++--
 sql/sql_show.cc    | 12 +++++-------
 6 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c
index 4fadfd2fc5d..a0b4515f1dd 100644
--- a/myisam/myisamchk.c
+++ b/myisam/myisamchk.c
@@ -1400,21 +1400,22 @@ static int mi_sort_records(MI_CHECK *param,
 
   if (!(((ulonglong) 1 << sort_key) & share->state.key_map))
   {
-    mi_check_print_error(param,"Can't sort table '%s' on key %d;  No such key",
+    mi_check_print_warning(param,
+			   "Can't sort table '%s' on key %d;  No such key",
 		name,sort_key+1);
     param->error_printed=0;
     DBUG_RETURN(0);				/* Nothing to do */
   }
   if (keyinfo->flag & HA_FULLTEXT)
   {
-    mi_check_print_error(param,"Can't sort table '%s' on FULLTEXT key %d",
-		name,sort_key+1);
+    mi_check_print_warning(param,"Can't sort table '%s' on FULLTEXT key %d",
+			   name,sort_key+1);
     param->error_printed=0;
     DBUG_RETURN(0);				/* Nothing to do */
   }
   if (share->data_file_type == COMPRESSED_RECORD)
   {
-    mi_check_print_error(param,"Can't sort read-only table '%s'", name);
+    mi_check_print_warning(param,"Can't sort read-only table '%s'", name);
     param->error_printed=0;
     DBUG_RETURN(0);				/* Nothing to do */
   }
diff --git a/sql/handler.cc b/sql/handler.cc
index 505f64dff43..96611301bfa 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1020,14 +1020,25 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
 
 void ha_key_cache(void)
 {
-  if (keybuff_size)
-    (void) init_key_cache((ulong) keybuff_size);
+  /*
+    The following mutex is not really needed as long as keybuff_size is
+    treated as a long value, but we use the mutex here to guard for future
+    changes.
+  */
+  pthread_mutex_lock(&LOCK_global_system_variables);
+  long tmp= keybuff_size;
+  pthread_mutex_unlock(&LOCK_global_system_variables);
+  if (tmp)
+    (void) init_key_cache(tmp);
 }
 
 
 void ha_resize_key_cache(void)
 {
-  (void) resize_key_cache((ulong) keybuff_size);
+  pthread_mutex_lock(&LOCK_global_system_variables);
+  long tmp= keybuff_size;
+  pthread_mutex_unlock(&LOCK_global_system_variables);
+  (void) resize_key_cache(tmp);
 }
 
 
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 0a4728ef325..e31038d7fee 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -507,7 +507,8 @@ void mysqld_list_processes(THD *thd,const char *user,bool verbose);
 int mysqld_show_status(THD *thd);
 int mysqld_show_variables(THD *thd,const char *wild);
 int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
-		enum enum_var_type value_type);
+		enum enum_var_type value_type,
+		pthread_mutex_t *mutex);
 
 /* sql_handler.cc */
 int mysql_ha_open(THD *thd, TABLE_LIST *tables);
diff --git a/sql/set_var.cc b/sql/set_var.cc
index b3238d1c0ec..6dc36e312cb 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -729,10 +729,12 @@ void fix_max_relay_log_size(THD *thd, enum_var_type type)
 bool sys_var_long_ptr::update(THD *thd, set_var *var)
 {
   ulonglong tmp= var->value->val_int();
+  pthread_mutex_lock(&LOCK_global_system_variables);
   if (option_limits)
     *value= (ulong) getopt_ull_limit_value(tmp, option_limits);
   else
     *value= (ulong) tmp;
+  pthread_mutex_unlock(&LOCK_global_system_variables);
   return 0;
 }
 
@@ -746,17 +748,21 @@ void sys_var_long_ptr::set_default(THD *thd, enum_var_type type)
 bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var)
 {
   ulonglong tmp= var->value->val_int();
+  pthread_mutex_lock(&LOCK_global_system_variables);
   if (option_limits)
     *value= (ulonglong) getopt_ull_limit_value(tmp, option_limits);
   else
     *value= (ulonglong) tmp;
+  pthread_mutex_unlock(&LOCK_global_system_variables);
   return 0;
 }
 
 
 void sys_var_ulonglong_ptr::set_default(THD *thd, enum_var_type type)
 {
+  pthread_mutex_lock(&LOCK_global_system_variables);
   *value= (ulonglong) option_limits->def_value;
+  pthread_mutex_unlock(&LOCK_global_system_variables);
 }
 
 
@@ -1000,9 +1006,21 @@ Item *sys_var::item(THD *thd, enum_var_type var_type)
   case SHOW_LONG:
     return new Item_uint((int32) *(ulong*) value_ptr(thd, var_type));
   case SHOW_LONGLONG:
-    return new Item_int(*(longlong*) value_ptr(thd, var_type));
+  {
+    longlong value;
+    pthread_mutex_lock(&LOCK_global_system_variables);
+    value= *(longlong*) value_ptr(thd, var_type);
+    pthread_mutex_unlock(&LOCK_global_system_variables);
+    return new Item_int(value);
+  }
   case SHOW_HA_ROWS:
-    return new Item_int((longlong) *(ha_rows*) value_ptr(thd, var_type));
+  {
+    ha_rows value;
+    pthread_mutex_lock(&LOCK_global_system_variables);
+    value= *(ha_rows*) value_ptr(thd, var_type);
+    pthread_mutex_unlock(&LOCK_global_system_variables);
+    return new Item_int((longlong) value);
+  }
   case SHOW_MY_BOOL:
     return new Item_int((int32) *(my_bool*) value_ptr(thd, var_type),1);
   case SHOW_CHAR:
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 70c0f772d7d..780c97654f5 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2146,11 +2146,12 @@ mysql_execute_command(void)
     break;
   case SQLCOM_SHOW_STATUS:
     res= mysqld_show(thd,(lex->wild ? lex->wild->ptr() : NullS),status_vars,
-		     OPT_GLOBAL);
+		     OPT_GLOBAL, &LOCK_status);
     break;
   case SQLCOM_SHOW_VARIABLES:
     res= mysqld_show(thd, (lex->wild ? lex->wild->ptr() : NullS),
-		     init_vars, lex->option_type);
+		     init_vars, lex->option_type,
+		     &LOCK_global_system_variables);
     break;
   case SQLCOM_SHOW_LOGS:
   {
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index d591a44accf..489635bd85f 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1158,7 +1158,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
 
 
 int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
-		enum enum_var_type value_type)
+		enum enum_var_type value_type,
+		pthread_mutex_t *mutex)
 {
   char buff[8192];
   String packet2(buff,sizeof(buff));
@@ -1171,8 +1172,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
   if (send_fields(thd,field_list,1))
     DBUG_RETURN(1); /* purecov: inspected */
 
-  /* pthread_mutex_lock(&THR_LOCK_keycache); */
-  pthread_mutex_lock(&LOCK_status);
+  pthread_mutex_lock(mutex);
   for (; variables->name; variables++)
   {
     if (!(wild && wild[0] && wild_case_compare(variables->name,wild)))
@@ -1413,14 +1413,12 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
         goto err;                               /* purecov: inspected */
     }
   }
-  pthread_mutex_unlock(&LOCK_status);
-  /* pthread_mutex_unlock(&THR_LOCK_keycache); */
+  pthread_mutex_unlock(&mutex);
   send_eof(&thd->net);
   DBUG_RETURN(0);
 
  err:
-  pthread_mutex_unlock(&LOCK_status);
-  /* pthread_mutex_unlock(&THR_LOCK_keycache); */
+  pthread_mutex_unlock(&mutex);
   DBUG_RETURN(1);
 }
 
-- 
2.30.9