From 41d95c504976746e4d117a4f97e18004f36eb70e Mon Sep 17 00:00:00 2001
From: Konstantin Osipov <kostja@sun.com>
Date: Thu, 10 Jun 2010 15:43:32 +0400
Subject: [PATCH] A pre-requisite for WL#5419 "LOCK_open scalability: make
 tdc_refresh_version an atomic counter". Backport the trivial changes from
 mysql-trunk-iplus.

---
 libmysqld/lib_sql.cc        |  1 -
 sql/event_scheduler.cc      |  1 -
 sql/ha_ndbcluster.cc        |  1 -
 sql/ha_ndbcluster_binlog.cc |  5 ++---
 sql/slave.cc                |  1 -
 sql/sql_base.cc             | 21 +++++++++++----------
 sql/sql_base.h              |  2 +-
 sql/sql_connect.cc          |  1 -
 sql/sql_insert.cc           |  1 -
 sql/sql_manager.cc          |  2 +-
 sql/sql_parse.cc            |  1 -
 sql/table.h                 |  2 +-
 12 files changed, 16 insertions(+), 23 deletions(-)

diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index e727122293c..b36a97759d2 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -634,7 +634,6 @@ void *create_embedded_thd(int client_flag)
     thd->variables.option_bits |= OPTION_BIG_SELECTS;
   thd->proc_info=0;				// Remove 'login'
   thd->command=COM_SLEEP;
-  thd->version=refresh_version;
   thd->set_time();
   thd->init_for_queries();
   thd->client_capabilities= client_flag;
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index 33b9a1cafda..c646642dbba 100755
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -203,7 +203,6 @@ pre_init_event_thread(THD* thd)
   */
 
   thd->proc_info= "Initialized";
-  thd->version= refresh_version;
   thd->set_time();
 
   /* Do not use user-supplied timeout value for system threads. */
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 099763b3fe9..68b98c79a50 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -9510,7 +9510,6 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
   if (thd->store_globals())
     goto ndb_util_thread_fail;
   thd->init_for_queries();
-  thd->version=refresh_version;
   thd->main_security_ctx.host_or_ip= "";
   thd->client_capabilities = 0;
   my_net_init(&thd->net, 0);
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index d38544f9b9f..0db7956fe28 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -3678,7 +3678,6 @@ pthread_handler_t ndb_binlog_thread_func(void *arg)
   thd->init_for_queries();
   thd->command= COM_DAEMON;
   thd->system_thread= SYSTEM_THREAD_NDBCLUSTER_BINLOG;
-  thd->version= refresh_version;
   thd->main_security_ctx.host_or_ip= "";
   thd->client_capabilities= 0;
   my_net_init(&thd->net, 0);
@@ -3965,9 +3964,9 @@ restart:
          !ndb_binlog_running))
       break; /* Shutting down server */
 
-    if (ndb_binlog_index && ndb_binlog_index->s->version < refresh_version)
+    if (ndb_binlog_index && ndb_binlog_index->s->needs_reopen())
     {
-      if (ndb_binlog_index->s->version < refresh_version)
+      if (ndb_binlog_index->s->needs_reopen())
       {
         close_thread_tables(thd);
         ndb_binlog_index= 0;
diff --git a/sql/slave.cc b/sql/slave.cc
index 6ebdea4a42a..bcb01d77e15 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -2055,7 +2055,6 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
     thd_proc_info(thd, "Waiting for the next event in relay log");
   else
     thd_proc_info(thd, "Waiting for master update");
-  thd->version=refresh_version;
   thd->set_time();
   /* Do not use user-supplied timeout value for system threads. */
   thd->variables.lock_wait_timeout= LONG_TIMEOUT;
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 47d709e8225..c227fd12f5b 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -440,7 +440,7 @@ static void table_def_unuse_table(TABLE *table)
   DBUG_ASSERT(table->in_use);
 
   /* We shouldn't put the table to 'unused' list if the share is old. */
-  DBUG_ASSERT(table->s->version == refresh_version);
+  DBUG_ASSERT(! table->s->needs_reopen());
 
   table->in_use= 0;
   /* Remove table from the list of tables used in this share. */
@@ -562,7 +562,9 @@ found:
     DBUG_RETURN(0);
   }
 
-  if (!share->ref_count++ && share->prev)
+  ++share->ref_count;
+
+  if (share->ref_count == 1 && share->prev)
   {
     /*
       Share was not used before and it was in the old_unused_share list
@@ -700,8 +702,7 @@ void release_table_share(TABLE_SHARE *share)
   DBUG_ASSERT(share->ref_count);
   if (!--share->ref_count)
   {
-    if (share->version != refresh_version ||
-        table_def_shutdown_in_progress)
+    if (share->needs_reopen() || table_def_shutdown_in_progress)
       my_hash_delete(&table_def_cache, (uchar*) share);
     else
     {
@@ -836,7 +837,7 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild)
     I_P_List_iterator<TABLE, TABLE_share> it(share->used_tables);
     while (it++)
       ++(*start_list)->in_use;
-    (*start_list)->locked= (share->version == 0) ? 1 : 0;
+    (*start_list)->locked= 0;                   /* Obsolete. */
     start_list= &(*start_list)->next;
     *start_list=0;
   }
@@ -1071,7 +1072,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
       {
         TABLE_SHARE *share=(TABLE_SHARE*) my_hash_element(&table_def_cache,
                                                           idx);
-        if (share->version != refresh_version)
+        if (share->needs_reopen())
         {
           found= TRUE;
           break;
@@ -1083,7 +1084,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
       for (TABLE_LIST *table= tables; table; table= table->next_local)
       {
         TABLE_SHARE *share= get_cached_table_share(table->db, table->table_name);
-        if (share && share->version != refresh_version)
+        if (share && share->needs_reopen())
         {
 	  found= TRUE;
           break;
@@ -2979,7 +2980,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
   }
 #endif
 
-  if (share->version != refresh_version)
+  if (share->needs_reopen())
   {
     if (!(flags & MYSQL_OPEN_IGNORE_FLUSH))
     {
@@ -8608,7 +8609,7 @@ my_bool mysql_rm_tmp_tables(void)
     all not used tables.
 */
 
-void flush_tables()
+void tdc_flush_unused_tables()
 {
   mysql_mutex_lock(&LOCK_open);
   while (unused_tables)
@@ -8820,7 +8821,7 @@ tdc_wait_for_old_versions(THD *thd, MDL_request_list *mdl_requests,
 
       if ((share= get_cached_table_share(mdl_request->key.db_name(),
                                          mdl_request->key.name())) &&
-          share->version != refresh_version)
+          share->needs_reopen())
         break;
     }
     if (!mdl_request)
diff --git a/sql/sql_base.h b/sql/sql_base.h
index 928b8339f15..38194f94a37 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -233,7 +233,6 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
 			    const char *table_name);
 void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table);
 void remove_db_from_cache(const char *db);
-void flush_tables();
 bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
 
 /* Functions to work with system tables. */
@@ -263,6 +262,7 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
 bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias,
                    char *cache_key, uint cache_key_length,
                    MEM_ROOT *mem_root, uint flags);
+void tdc_flush_unused_tables();
 TABLE *find_table_for_mdl_upgrade(TABLE *list, const char *db,
                                   const char *table_name,
                                   bool no_error);
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index c0081c13366..481715098b7 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -1083,7 +1083,6 @@ static void prepare_new_connection_state(THD* thd)
     embedded server library.
     TODO: refactor this to avoid code duplication there
   */
-  thd->version= refresh_version;
   thd->proc_info= 0;
   thd->command= COM_SLEEP;
   thd->set_time();
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 998d3c53e04..24a418f8f25 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1814,7 +1814,6 @@ public:
     thd.security_ctx->user=thd.security_ctx->priv_user=(char*) delayed_user;
     thd.security_ctx->host=(char*) my_localhost;
     thd.current_tablenr=0;
-    thd.version=refresh_version;
     thd.command=COM_DELAYED_INSERT;
     thd.lex->current_select= 0; 		// for my_message_sql
     thd.lex->sql_command= SQLCOM_INSERT;        // For innodb::store_lock()
diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc
index e9c9402a89a..2189b1e124f 100644
--- a/sql/sql_manager.cc
+++ b/sql/sql_manager.cc
@@ -108,7 +108,7 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused)))
 
     if (error == ETIMEDOUT || error == ETIME)
     {
-      flush_tables();
+      tdc_flush_unused_tables();
       error = 0;
       reset_flush_time = TRUE;
     }
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 1b1016233f8..6ff631ad7c7 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -497,7 +497,6 @@ static void handle_bootstrap_impl(THD *thd)
 #endif /* EMBEDDED_LIBRARY */
 
   thd_proc_info(thd, 0);
-  thd->version=refresh_version;
   thd->security_ctx->priv_user=
     thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
   thd->security_ctx->priv_host[0]=0;
diff --git a/sql/table.h b/sql/table.h
index 52fc0f1a7d9..30cac15f8d1 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -740,7 +740,7 @@ struct TABLE_SHARE
   /*
     Must all TABLEs be reopened?
   */
-  inline bool needs_reopen()
+  inline bool needs_reopen() const
   {
     return version != refresh_version;
   }