List:Commits« Previous MessageNext Message »
From:Vladislav Vaintroub Date:August 22 2008 12:19pm
Subject:bzr commit into mysql-5.1 branch (vvaintroub:2716) Bug#38522
View as plain text  
#At file:///C:/bzr/bt51_38522/

 2716 Vladislav Vaintroub	2008-08-22
      Bug#38522: 5 seconds delay when closing application using embedded server
      
      The problem here is that embedded server starts handle_thread manager 
      thread  on mysql_library_init() does not stop it on mysql_library_end().
      At shutdown, my_thread_global_end() waits for thread count to become 0,
      but since we did not stop the thread it will give up after 5 seconds.
      
      Solution is to move shutdown for handle_manager thread from kill_server()
      (mysqld specific) to clean_up() that is used by both embedded and mysqld.
      
      This patch also contains some refactorings - to avoid duplicate code,
      start_handle_manager() and stop_handle_manager() functions are introduced.
      Unused variables are eliminated. handle_manager does not rely on global
      variable abort_loop anymore to stop (abort_loop is not set for embedded).
modified:
  libmysqld/lib_sql.cc
  sql/mysql_priv.h
  sql/mysqld.cc
  sql/sql_manager.cc

per-file messages:
  libmysqld/lib_sql.cc
    Code to start handle_manager thread is factored out into start_handle_manager()
  sql/mysql_priv.h
    - new functions start_handle_manager() and stop_handle_manager()
    - move manager_thread_in_use  variable to sql_manager.cc and made
    it static
    - remove manager_status, as it is unused
  sql/mysqld.cc
    Code to start/stop handle_manager thread is factored out into start_handle_manager()
    and stop_handle_manager()
  sql/sql_manager.cc
    - new functions start_handle_manager() and stop_handle_manager().
    - removed unused status and manager status variable.
    - don't rely on global abort_loop variable to stop the thread,
    (not set in embedded), use static abort_manager that is set
    by stop_handle_manager()
=== modified file 'libmysqld/lib_sql.cc'
--- a/libmysqld/lib_sql.cc	2008-08-13 18:50:08 +0000
+++ b/libmysqld/lib_sql.cc	2008-08-22 12:18:50 +0000
@@ -538,12 +538,7 @@ int init_embedded_server(int argc, char 
 
   (void) thr_setconcurrency(concurrency);	// 10 by default
 
-  if (flush_time && flush_time != ~(ulong) 0L)
-  {
-    pthread_t hThread;
-    if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
-      sql_print_error("Warning: Can't create thread to manage maintenance");
-  }
+  start_handle_manager();
 
   // FIXME initialize binlog_filter and rpl_filter if not already done
   //       corresponding delete is in clean_up()

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2008-08-12 10:26:23 +0000
+++ b/sql/mysql_priv.h	2008-08-22 12:18:50 +0000
@@ -1766,10 +1766,9 @@ int mysql_load(THD *thd, sql_exchange *e
 int write_record(THD *thd, TABLE *table, COPY_INFO *info);
 
 /* sql_manager.cc */
-extern ulong volatile manager_status;
-extern bool volatile manager_thread_in_use, mqh_used;
-extern pthread_t manager_thread;
-pthread_handler_t handle_manager(void *arg);
+extern bool volatile  mqh_used;
+void start_handle_manager();
+void stop_handle_manager();
 bool mysql_manager_submit(void (*action)());
 
 

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2008-06-19 14:02:32 +0000
+++ b/sql/mysqld.cc	2008-08-22 12:18:50 +0000
@@ -783,16 +783,6 @@ static void close_connections(void)
   kill_cached_threads++;
   flush_thread_cache();
 
-  /* kill flush thread */
-  (void) pthread_mutex_lock(&LOCK_manager);
-  if (manager_thread_in_use)
-  {
-    DBUG_PRINT("quit", ("killing manager thread: 0x%lx",
-                        (ulong)manager_thread));
-   (void) pthread_cond_signal(&COND_manager);
-  }
-  (void) pthread_mutex_unlock(&LOCK_manager);
-
   /* kill connection thread */
 #if !defined(__WIN__) && !defined(__NETWARE__)
   DBUG_PRINT("quit", ("waiting for select thread: 0x%lx",
@@ -1195,6 +1185,7 @@ void clean_up(bool print_message)
   if (cleanup_done++)
     return; /* purecov: inspected */
 
+  stop_handle_manager();
   release_ddl_log();
 
   /*
@@ -4026,17 +4017,6 @@ server.");
 
 #ifndef EMBEDDED_LIBRARY
 
-static void create_maintenance_thread()
-{
-  if (flush_time && flush_time != ~(ulong) 0L)
-  {
-    pthread_t hThread;
-    if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
-      sql_print_warning("Can't create thread to manage maintenance");
-  }
-}
-
-
 static void create_shutdown_thread()
 {
 #ifdef __WIN__
@@ -4351,7 +4331,7 @@ we force server id to 2, but this MySQL 
   execute_ddl_log_recovery();
 
   create_shutdown_thread();
-  create_maintenance_thread();
+  start_handle_manager();
 
   if (Events::init(opt_noacl))
     unireg_abort(1);

=== modified file 'sql/sql_manager.cc'
--- a/sql/sql_manager.cc	2007-05-10 09:59:39 +0000
+++ b/sql/sql_manager.cc	2008-08-22 12:18:50 +0000
@@ -23,8 +23,9 @@
 
 #include "mysql_priv.h"
 
-ulong volatile manager_status;
-bool volatile manager_thread_in_use;
+
+static bool volatile manager_thread_in_use;
+static bool abort_manager;
 
 pthread_t manager_thread;
 pthread_mutex_t LOCK_manager;
@@ -63,7 +64,6 @@ bool mysql_manager_submit(void (*action)
 pthread_handler_t handle_manager(void *arg __attribute__((unused)))
 {
   int error = 0;
-  ulong status;
   struct timespec abstime;
   bool reset_flush_time = TRUE;
   struct handler_cb *cb= NULL;
@@ -72,7 +72,6 @@ pthread_handler_t handle_manager(void *a
 
   pthread_detach_this_thread();
   manager_thread = pthread_self();
-  manager_status = 0;
   manager_thread_in_use = 1;
 
   for (;;)
@@ -87,16 +86,14 @@ pthread_handler_t handle_manager(void *a
 	set_timespec(abstime, flush_time);
         reset_flush_time = FALSE;
       }
-      while (!manager_status && (!error || error == EINTR) && !abort_loop)
+      while ((!error || error == EINTR) && !abort_manager)
         error= pthread_cond_timedwait(&COND_manager, &LOCK_manager, &abstime);
     }
     else
     {
-      while (!manager_status && (!error || error == EINTR) && !abort_loop)
+      while ((!error || error == EINTR) && !abort_manager)
         error= pthread_cond_wait(&COND_manager, &LOCK_manager);
     }
-    status = manager_status;
-    manager_status = 0;
     if (cb == NULL)
     {
       cb= cb_list;
@@ -104,7 +101,7 @@ pthread_handler_t handle_manager(void *a
     }
     pthread_mutex_unlock(&LOCK_manager);
 
-    if (abort_loop)
+    if (abort_manager)
       break;
 
     if (error == ETIMEDOUT || error == ETIME)
@@ -121,11 +118,41 @@ pthread_handler_t handle_manager(void *a
       my_free((uchar*)cb, MYF(0));
       cb= next;
     }
-
-    if (status)
-      DBUG_PRINT("error", ("manager did not handle something: %lx", status));
   }
   manager_thread_in_use = 0;
   my_thread_end();
   DBUG_RETURN(NULL);
 }
+
+
+/* Start handle manager thread */
+void start_handle_manager()
+{
+  DBUG_ENTER("start_handle_manager");
+  abort_manager = false;
+  if (flush_time && flush_time != ~(ulong) 0L)
+  {
+    pthread_t hThread;
+    if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
+      sql_print_warning("Can't create handle_manager thread");
+  }
+  DBUG_VOID_RETURN;
+}
+
+
+/* Initiate shutdown of handle manager thread */
+void stop_handle_manager()
+{
+  DBUG_ENTER("stop_handle_manager");
+  abort_manager = true;
+  pthread_mutex_lock(&LOCK_manager);
+  if (manager_thread_in_use)
+  {
+    DBUG_PRINT("quit", ("initiate shutdown of handle manager thread: 0x%lx",
+                        (ulong)manager_thread));
+   pthread_cond_signal(&COND_manager);
+  }
+  pthread_mutex_unlock(&LOCK_manager);
+  DBUG_VOID_RETURN;
+}
+

Thread
bzr commit into mysql-5.1 branch (vvaintroub:2716) Bug#38522Vladislav Vaintroub22 Aug