List:Commits« Previous MessageNext Message »
From:Sergey Vojtovich Date:November 10 2011 9:53am
Subject:bzr push into mysql-5.5 branch (sergey.vojtovich:3600 to 3601)
View as plain text  
 3601 Sergey Vojtovich	2011-11-10 [merge]
      (no message)

    modified:
      sql/sql_class.h
      sql/sql_plugin.cc
 3600 Sneha Modi	2011-11-10
       Bug#11754170:45729: TEST CASE FOR BUG#28211 IS DISABLED IN QUERY_CACHE.TEST
            
            A patch for this bug has already been pushed. A minor change is made here.
            The database to be used after re-enabling the disabled code is 'TEST'.
            But instead, 'MYSQL' was being used. 
            This is the minor change that is being made here.

    modified:
      mysql-test/r/query_cache.result
      mysql-test/t/query_cache.test
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2011-10-27 14:14:41 +0000
+++ b/sql/sql_class.h	2011-11-10 06:43:34 +0000
@@ -410,8 +410,9 @@ typedef struct system_variables
   */ 
   ulong dynamic_variables_version;
   char* dynamic_variables_ptr;
-  uint dynamic_variables_head;  /* largest valid variable offset */
-  uint dynamic_variables_size;  /* how many bytes are in use */
+  uint dynamic_variables_head;    /* largest valid variable offset */
+  uint dynamic_variables_size;    /* how many bytes are in use */
+  LIST *dynamic_variables_allocs; /* memory hunks for PLUGIN_VAR_MEMALLOC */
   
   ulonglong max_heap_table_size;
   ulonglong tmp_table_size;

=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc	2011-08-15 18:12:11 +0000
+++ b/sql/sql_plugin.cc	2011-11-10 06:43:34 +0000
@@ -255,6 +255,13 @@ static bool register_builtin(struct st_m
 static void unlock_variables(THD *thd, struct system_variables *vars);
 static void cleanup_variables(THD *thd, struct system_variables *vars);
 static void plugin_vars_free_values(sys_var *vars);
+static bool plugin_var_memalloc_session_update(THD *thd,
+                                               struct st_mysql_sys_var *var,
+                                               char **dest, const char *value);
+static bool plugin_var_memalloc_global_update(THD *thd,
+                                              struct st_mysql_sys_var *var,
+                                              char **dest, const char *value);
+static void plugin_var_memalloc_free(struct system_variables *vars);
 static void restore_pluginvar_names(sys_var *first);
 static void plugin_opt_set_limits(struct my_option *,
                                   const struct st_mysql_sys_var *);
@@ -2300,13 +2307,7 @@ static void update_func_longlong(THD *th
 static void update_func_str(THD *thd, struct st_mysql_sys_var *var,
                              void *tgt, const void *save)
 {
-  char *old= *(char **) tgt;
-  *(char **)tgt= *(char **) save;
-  if (var->flags & PLUGIN_VAR_MEMALLOC)
-  {
-    *(char **)tgt= my_strdup(*(char **) save, MYF(0));
-    my_free(old);
-  }
+  *(char **) tgt= *(char **) save;
 }
 
 
@@ -2565,11 +2566,13 @@ static uchar *intern_sys_var_ptr(THD* th
       if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
           pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC)
       {
-         char **pp= (char**) (thd->variables.dynamic_variables_ptr +
-                             *(int*)(pi->plugin_var + 1));
-         if ((*pp= *(char**) (global_system_variables.dynamic_variables_ptr +
-                             *(int*)(pi->plugin_var + 1))))
-           *pp= my_strdup(*pp, MYF(MY_WME|MY_FAE));
+         int varoff= *(int *) (pi->plugin_var + 1);
+         char **thdvar= (char **) (thd->variables.
+                                   dynamic_variables_ptr + varoff);
+         char **sysvar= (char **) (global_system_variables.
+                                   dynamic_variables_ptr + varoff);
+         *thdvar= NULL;
+         plugin_var_memalloc_session_update(thd, NULL, thdvar, *sysvar);
       }
     }
 
@@ -2675,33 +2678,8 @@ static void unlock_variables(THD *thd, s
 */
 static void cleanup_variables(THD *thd, struct system_variables *vars)
 {
-  st_bookmark *v;
-  sys_var_pluginvar *pivar;
-  sys_var *var;
-  int flags;
-  uint idx;
-
-  mysql_rwlock_rdlock(&LOCK_system_variables_hash);
-  for (idx= 0; idx < bookmark_hash.records; idx++)
-  {
-    v= (st_bookmark*) my_hash_element(&bookmark_hash, idx);
-    if (v->version > vars->dynamic_variables_version ||
-        !(var= intern_find_sys_var(v->key + 1, v->name_len)) ||
-        !(pivar= var->cast_pluginvar()) ||
-        v->key[0] != (pivar->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
-      continue;
-
-    flags= pivar->plugin_var->flags;
-
-    if ((flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
-        flags & PLUGIN_VAR_THDLOCAL && flags & PLUGIN_VAR_MEMALLOC)
-    {
-      char **ptr= (char**) pivar->real_value_ptr(thd, OPT_SESSION);
-      my_free(*ptr);
-      *ptr= NULL;
-    }
-  }
-  mysql_rwlock_unlock(&LOCK_system_variables_hash);
+  if (thd)
+    plugin_var_memalloc_free(&thd->variables);
 
   DBUG_ASSERT(vars->table_plugin == NULL);
 
@@ -2796,6 +2774,136 @@ static SHOW_TYPE pluginvar_show_type(st_
 }
 
 
+/**
+  Set value for thread local variable with PLUGIN_VAR_MEMALLOC flag.
+
+  @param[in]     thd   Thread context.
+  @param[in]     var   Plugin variable.
+  @param[in,out] dest  Destination memory pointer.
+  @param[in]     value '\0'-terminated new value.
+
+  Most plugin variable values are stored on dynamic_variables_ptr.
+  Releasing memory occupied by these values is as simple as freeing
+  dynamic_variables_ptr.
+
+  An exception to the rule are PLUGIN_VAR_MEMALLOC variables, which
+  are stored on individual memory hunks. All of these hunks has to
+  be freed when it comes to cleanup.
+
+  It may happen that a plugin was uninstalled and descriptors of
+  it's variables are lost. In this case it is impossible to locate
+  corresponding values.
+
+  In addition to allocating and setting variable value, new element
+  is added to dynamic_variables_allocs list. When thread is done, it
+  has to call plugin_var_memalloc_free() to release memory used by
+  PLUGIN_VAR_MEMALLOC variables.
+
+  If var is NULL, variable update function is not called. This is
+  needed when we take snapshot of system variables during thread
+  initialization.
+
+  @note List element and variable value are stored on the same memory
+  hunk. List element is followed by variable value.
+
+  @return Completion status
+  @retval false Success
+  @retval true  Failure
+*/
+
+static bool plugin_var_memalloc_session_update(THD *thd,
+                                               struct st_mysql_sys_var *var,
+                                               char **dest, const char *value)
+
+{
+  LIST *old_element= NULL;
+  struct system_variables *vars= &thd->variables;
+  DBUG_ENTER("plugin_var_memalloc_session_update");
+
+  if (value)
+  {
+    size_t length= strlen(value) + 1;
+    LIST *element;
+    if (!(element= (LIST *) my_malloc(sizeof(LIST) + length, MYF(MY_WME))))
+      DBUG_RETURN(true);
+    memcpy(element + 1, value, length);
+    value= (const char *) (element + 1);
+    vars->dynamic_variables_allocs= list_add(vars->dynamic_variables_allocs,
+                                             element);
+  }
+
+  if (*dest)
+    old_element= (LIST *) (*dest - sizeof(LIST));
+
+  if (var)
+    var->update(thd, var, (void **) dest, (const void *) &value);
+  else
+    *dest= (char *) value;
+
+  if (old_element)
+  {
+    vars->dynamic_variables_allocs= list_delete(vars->dynamic_variables_allocs,
+                                                old_element);
+    my_free(old_element);
+  }
+  DBUG_RETURN(false);
+}
+
+
+/**
+  Free all elements allocated by plugin_var_memalloc_session_update().
+
+  @param[in]     vars  system variables structure
+
+  @see plugin_var_memalloc_session_update
+*/
+
+static void plugin_var_memalloc_free(struct system_variables *vars)
+{
+  LIST *next, *root;
+  DBUG_ENTER("plugin_var_memalloc_free");
+  for (root= vars->dynamic_variables_allocs; root; root= next)
+  {
+    next= root->next;
+    my_free(root);
+  }
+  vars->dynamic_variables_allocs= NULL;
+  DBUG_VOID_RETURN;
+}
+
+
+/**
+  Set value for global variable with PLUGIN_VAR_MEMALLOC flag.
+
+  @param[in]     thd   Thread context.
+  @param[in]     var   Plugin variable.
+  @param[in,out] dest  Destination memory pointer.
+  @param[in]     value '\0'-terminated new value.
+
+  @return Completion status
+  @retval false Success
+  @retval true  Failure
+*/
+
+static bool plugin_var_memalloc_global_update(THD *thd,
+                                              struct st_mysql_sys_var *var,
+                                              char **dest, const char *value)
+{
+  char *old_value= *dest;
+  DBUG_ENTER("plugin_var_memalloc_global_update");
+
+  if (value && !(value= my_strdup(value, MYF(MY_WME))))
+    DBUG_RETURN(true);
+
+  var->update(thd, var, (void **) dest, (const void *) &value);
+
+  if (old_value)
+    my_free(old_value);
+
+  DBUG_RETURN(false);
+}
+
+
 bool sys_var_pluginvar::check_update_type(Item_result type)
 {
   switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
@@ -2880,6 +2988,7 @@ bool sys_var_pluginvar::do_check(THD *th
 
 bool sys_var_pluginvar::session_update(THD *thd, set_var *var)
 {
+  bool rc= false;
   DBUG_ASSERT(!is_readonly());
   DBUG_ASSERT(plugin_var->flags & PLUGIN_VAR_THDLOCAL);
   DBUG_ASSERT(thd == current_thd);
@@ -2889,13 +2998,20 @@ bool sys_var_pluginvar::session_update(T
   const void *src= var->value ? (void*)&var->save_result
                               : (void*)real_value_ptr(thd, OPT_GLOBAL);
   mysql_mutex_unlock(&LOCK_global_system_variables);
-  plugin_var->update(thd, plugin_var, tgt, src);
 
-  return false;
+  if ((plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
+      plugin_var->flags & PLUGIN_VAR_MEMALLOC)
+    rc= plugin_var_memalloc_session_update(thd, plugin_var, (char **) tgt,
+                                           *(const char **) src);
+  else 
+    plugin_var->update(thd, plugin_var, tgt, src);
+
+  return rc;
 }
 
 bool sys_var_pluginvar::global_update(THD *thd, set_var *var)
 {
+  bool rc= false;
   DBUG_ASSERT(!is_readonly());
   mysql_mutex_assert_owner(&LOCK_global_system_variables);
 
@@ -2952,9 +3068,14 @@ bool sys_var_pluginvar::global_update(TH
     }
   }
 
-  plugin_var->update(thd, plugin_var, tgt, src);
+  if ((plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
+      plugin_var->flags & PLUGIN_VAR_MEMALLOC)
+    rc= plugin_var_memalloc_global_update(thd, plugin_var, (char **) tgt,
+                                          *(const char **) src);
+  else 
+    plugin_var->update(thd, plugin_var, tgt, src);
 
-  return false;
+  return rc;
 }
 
 

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.5 branch (sergey.vojtovich:3600 to 3601) Sergey Vojtovich11 Nov