[Commits] 4a3c87a: vix of plugin loading & memory allocating

Oleksandr Byelkin sanja at mariadb.com
Mon May 23 18:20:17 EEST 2016


revision-id: 4a3c87a72ccae6dca10e2128ee5f12c191c682e4 (mariadb-10.2.0-45-g4a3c87a)
parent(s): e81a2b2d31d0d53d7f0468e6db1d9041da2f0516
committer: Oleksandr Byelkin
timestamp: 2016-05-23 17:20:17 +0200
message:

vix of plugin loading & memory allocating

---
 sql/session_tracker.cc | 35 +++++++++++++++++++++++++++++------
 sql/set_var.cc         |  5 +++++
 sql/set_var.h          |  1 +
 sql/sql_plugin.cc      | 28 +++++++++++++++++++++++++---
 sql/sql_string.h       |  4 +++-
 sql/sys_vars.ic        |  8 +++++---
 6 files changed, 68 insertions(+), 13 deletions(-)

diff --git a/sql/session_tracker.cc b/sql/session_tracker.cc
index 75dbb1f..3b4d491 100644
--- a/sql/session_tracker.cc
+++ b/sql/session_tracker.cc
@@ -58,6 +58,7 @@ class Session_sysvars_tracker : public State_tracker
 
   struct sysvar_node_st {
     sys_var *m_svar;
+    bool *test_load;
     bool m_changed;
   };
 
@@ -81,7 +82,7 @@ class Session_sysvars_tracker : public State_tracker
       my_hash_init(&m_registered_sysvars,
                    &my_charset_bin,
 		   4, 0, 0, (my_hash_get_key) sysvars_get_key,
-		   my_free, HASH_UNIQUE);
+		   my_free, MYF(HASH_UNIQUE | HASH_THREAD_SPECIFIC));
     }
     void free_hash()
     {
@@ -314,7 +315,8 @@ bool Session_sysvars_tracker::vars_list::insert(sysvar_node_st *node,
 {
   if (!node)
   {
-    if (!(node= (sysvar_node_st *) my_malloc(sizeof(sysvar_node_st), MY_WME)))
+    if (!(node= (sysvar_node_st *) my_malloc(sizeof(sysvar_node_st),
+                                             MYF(MY_WME | MY_THREAD_SPECIFIC))))
     {
       reset();
       return true;
@@ -322,6 +324,7 @@ bool Session_sysvars_tracker::vars_list::insert(sysvar_node_st *node,
   }
 
   node->m_svar= (sys_var *)svar;
+  node->test_load= node->m_svar->test_load;
   node->m_changed= false;
   if (my_hash_insert(&m_registered_sysvars, (uchar *) node))
   {
@@ -457,7 +460,8 @@ static my_bool name_array_filler(void *ptr, void *data_ptr)
   Session_sysvars_tracker::sysvar_node_st *node=
     (Session_sysvars_tracker::sysvar_node_st *)ptr;
   name_array_filler_data *data= (struct name_array_filler_data *)data_ptr;
-  data->names[data->idx++]= &node->m_svar->name;
+  if (*node->test_load)
+    data->names[data->idx++]= &node->m_svar->name;
   return FALSE;
 }
 
@@ -508,18 +512,29 @@ bool Session_sysvars_tracker::vars_list::construct_var_list(char *buf,
     return true;
 
   data.idx= 0;
+
+  mysql_mutex_lock(&LOCK_plugin);
   my_hash_iterate(&m_registered_sysvars, &name_array_filler, &data);
-  DBUG_ASSERT(data.idx == m_registered_sysvars.records);
+  DBUG_ASSERT(data.idx <= m_registered_sysvars.records);
 
-  my_qsort(data.names, m_registered_sysvars.records, sizeof(LEX_CSTRING *),
+
+  if (m_registered_sysvars.records == 0)
+  {
+    mysql_mutex_unlock(&LOCK_plugin);
+    buf[0]= '\0';
+    return false;
+  }
+
+  my_qsort(data.names, data.idx, sizeof(LEX_CSTRING *),
            &name_array_sorter);
 
-  for(uint i= 0; i < m_registered_sysvars.records; i++)
+  for(uint i= 0; i < data.idx; i++)
   {
     LEX_CSTRING *nm= data.names[i];
     size_t ln= nm->length + 1;
     if (ln > left)
     {
+      mysql_mutex_unlock(&LOCK_plugin);
       my_safe_afree(data.names, names_size);
       return true;
     }
@@ -528,6 +543,7 @@ bool Session_sysvars_tracker::vars_list::construct_var_list(char *buf,
     buf+= ln;
     left-= ln;
   }
+  mysql_mutex_unlock(&LOCK_plugin);
 
   buf--; buf[0]= '\0';
   my_safe_afree(data.names, names_size);
@@ -648,12 +664,19 @@ bool Session_sysvars_tracker::store(THD *thd, String *buf)
   {
     if (node->m_changed)
     {
+      mysql_mutex_lock(&LOCK_plugin);
+      if (!*node->test_load)
+      {
+        mysql_mutex_lock(&LOCK_plugin);
+        continue;
+      }
       sys_var *svar= node->m_svar;
       show.name= svar->name.str;
       show.value= (char *) svar;
 
       value= get_one_variable(thd, &show, OPT_SESSION, SHOW_SYS, NULL,
                               &charset, val_buf, &val_length);
+      mysql_mutex_lock(&LOCK_plugin);
 
       length= net_length_size(svar->name.length) +
               svar->name.length +
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 0189afd..5f2bc93 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -115,6 +115,9 @@ void sys_var_end()
   DBUG_VOID_RETURN;
 }
 
+
+static bool static_test_load= TRUE;
+
 /**
   sys_var constructor
 
@@ -184,6 +187,8 @@ sys_var::sys_var(sys_var_chain *chain, const char *name_arg,
   else
     chain->first= this;
   chain->last= this;
+
+  test_load= &static_test_load;
 }
 
 bool sys_var::update(THD *thd, set_var *var)
diff --git a/sql/set_var.h b/sql/set_var.h
index cd534c0..16111ad 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -63,6 +63,7 @@ class sys_var: protected Value_source // for double_from_string_with_check
 public:
   sys_var *next;
   LEX_CSTRING name;
+  bool *test_load;
   enum flag_enum { GLOBAL, SESSION, ONLY_SESSION, SCOPE_MASK=1023,
                    READONLY=1024, ALLOCATED=2048, PARSE_EARLY=4096,
                    NO_SET_STATEMENT=8192, AUTO_SET=16384};
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 0f1d7fe..0342a88 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -269,6 +269,7 @@ struct st_bookmark
   uint name_len;
   int offset;
   uint version;
+  bool loaded;
   char key[1];
 };
 
@@ -1177,6 +1178,13 @@ static bool plugin_add(MEM_ROOT *tmp_root,
   DBUG_RETURN(errs > 0 || oks + dupes == 0);
 }
 
+static void plugin_variables_deinit(struct st_plugin_int *plugin)
+{
+
+  for (sys_var *var= plugin->system_vars; var; var= var->next)
+    (*var->test_load)= FALSE;
+  mysql_del_sys_var_chain(plugin->system_vars);
+}
 
 static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check)
 {
@@ -1228,8 +1236,7 @@ static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check)
   if (ref_check && plugin->ref_count)
     sql_print_error("Plugin '%s' has ref_count=%d after deinitialization.",
                     plugin->name.str, plugin->ref_count);
-
-  mysql_del_sys_var_chain(plugin->system_vars);
+  plugin_variables_deinit(plugin);
 }
 
 static void plugin_del(struct st_plugin_int *plugin)
@@ -1449,7 +1456,7 @@ static int plugin_initialize(MEM_ROOT *tmp_root, struct st_plugin_int *plugin,
 
 err:
   if (ret)
-    mysql_del_sys_var_chain(plugin->system_vars);
+    plugin_variables_deinit(plugin);
 
   mysql_mutex_lock(&LOCK_plugin);
   plugin->state= state;
@@ -3951,6 +3958,14 @@ my_bool mark_changed(int, const struct my_option *opt, char *)
 }
 
 /**
+  It is always false to mark global plugin variable unloaded just to be
+  safe because we have no way now to know truth about them.
+
+  TODO: make correct mechanism for global plugin variables
+*/
+static bool static_unload= FALSE;
+
+/**
   Create and register system variables supplied from the plugin and
   assigns initial values from corresponding command line arguments.
 
@@ -4027,9 +4042,13 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
 
         tmp_backup[tmp->nbackups++].save(&o->name);
         if ((var= find_bookmark(tmp->name.str, o->name, o->flags)))
+        {
           varname= var->key + 1;
+          var->loaded= TRUE;
+        }
         else
         {
+          var= NULL;
           len= tmp->name.length + strlen(o->name) + 2;
           varname= (char*) alloc_root(mem_root, len);
           strxmov(varname, tmp->name.str, "-", o->name, NullS);
@@ -4037,6 +4056,9 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
           convert_dash_to_underscore(varname, len-1);
         }
         v= new (mem_root) sys_var_pluginvar(&chain, varname, tmp, o);
+        v->test_load= (var ? &var->loaded : &static_unload);
+        DBUG_ASSERT(static_unload == FALSE);
+
         if (!(o->flags & PLUGIN_VAR_NOCMDOPT))
         {
           // update app_type, used for I_S.SYSTEM_VARIABLES
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 10f3c4a..feab807 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -359,7 +359,9 @@ class String
     if (ALIGN_SIZE(arg_length+1) < Alloced_length)
     {
       char *new_ptr;
-      if (!(new_ptr=(char*) my_realloc(Ptr,arg_length,MYF(0))))
+      if (!(new_ptr=(char*)
+            my_realloc(Ptr, arg_length,MYF((thread_specific ?
+                                            MY_THREAD_SPECIFIC : 0)))))
       {
 	Alloced_length = 0;
 	real_alloc(arg_length);
diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic
index 519e7ac..dd3bec3 100644
--- a/sql/sys_vars.ic
+++ b/sql/sys_vars.ic
@@ -853,6 +853,7 @@ class Sys_var_extstor: public sys_var
   }
   void session_save_default(THD *thd, set_var *var)
   {
+    DBUG_ASSERT(thd != NULL);
     var->save_result.string_value=
       make_value(thd, defvalue_len(thd),
                  &Sys_var_extstor::defvalue_construct);
@@ -865,13 +866,14 @@ class Sys_var_extstor: public sys_var
   }
   uchar *session_value_ptr(THD *thd, const LEX_STRING *base)
   {
+    DBUG_ASSERT(thd != NULL);
     LEX_STRING res= make_value(thd, value_len(thd),
                                &Sys_var_extstor::value_construct);
     return (uchar *)res.str;
   }
   uchar *global_value_ptr(THD *thd, const LEX_STRING *base)
   {
-    LEX_STRING res= make_value(thd, defvalue_len(thd),
+    LEX_STRING res= make_value(NULL, defvalue_len(NULL),
                                &Sys_var_extstor::defvalue_construct);
     return (uchar *)res.str;
   }
@@ -929,7 +931,7 @@ class Sys_var_dbug: public Sys_var_extstor
   virtual bool value_construct(THD *thd __attribute__((unused)),
                                char *val, size_t len)
   { DBUG_EXPLAIN(val, len); return false; }
-  virtual size_t defvalue_len(THD *thd __attribute__((unused)))
+  virtual size_t defvalue_len(THD *)
   { return 256; }
   virtual bool defvalue_construct(THD *thd __attribute__((unused)),
                                   char *val, size_t len)
@@ -1005,7 +1007,7 @@ class Sys_var_sesvartrack: public Sys_var_extstor
   { return sysvartrack_value_len(thd); }
   virtual bool value_construct(THD *thd, char *val, size_t len)
   { return sysvartrack_value_construct(thd, val, len); }
-  virtual size_t defvalue_len(THD *thd __attribute__((unused)))
+  virtual size_t defvalue_len(THD *)
   { return global_val.length + 1; }
   virtual bool defvalue_construct(THD *thd __attribute__((unused)),
                                   char *val, size_t len)


More information about the commits mailing list