MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Mats Kindahl Date:February 15 2010 2:02pm
Subject:bzr commit into mysql-5.5-next-mr branch (mats:3045) WL#5136
View as plain text  
#At file:///home/bzr/mkindahl/testing-next-mr-wl5136-stage/ based on revid:mikael@stripped

 3045 Mats Kindahl	2010-02-15 [merge]
      WL#5136: New thread pool design
      
      Merging in patch from pre-stage branch.
      
      This patch contain two parts:
      
      - Code changes to make the thread pool a plugin.
      
      - Code changes to server to provide scheduler callbacks.

    added:
      mysql-test/suite/sys_vars/t/thread_pool_size_basic-master.opt
      plugin/thread_pool/
      plugin/thread_pool/Makefile.am
      plugin/thread_pool/plug.in
      plugin/thread_pool/thread_pool_plugin.cc
      sql/sql_callback.h
    renamed:
      sql/scheduler_epoll.cc => plugin/thread_pool/epoll.cc
      sql/scheduler_poll.cc => plugin/thread_pool/poll.cc
      sql/scheduler_thread_pool.cc => plugin/thread_pool/thread_pool.cc
      sql/scheduler_thread_pool.h => plugin/thread_pool/thread_pool.h
    modified:
      configure.in
      include/mysql/plugin.h
      include/mysql/plugin.h.pp
      mysql-test/suite/rpl/combinations
      mysql-test/suite/sys_vars/r/thread_pool_size_basic.result
      mysql-test/suite/sys_vars/t/thread_pool_size_basic.test
      sql/Makefile.am
      sql/mysql_priv.h
      sql/mysqld.cc
      sql/scheduler.cc
      sql/scheduler.h
      sql/sql_class.cc
      sql/sql_connect.cc
      sql/sys_vars.cc
      plugin/thread_pool/epoll.cc
      plugin/thread_pool/poll.cc
      plugin/thread_pool/thread_pool.cc
      plugin/thread_pool/thread_pool.h
=== modified file 'configure.in'
--- a/configure.in	2010-02-10 07:47:10 +0000
+++ b/configure.in	2010-02-15 14:02:12 +0000
@@ -1,7 +1,7 @@
 dnl -*- ksh -*-
 dnl Process this file with autoconf to produce a configure script.
 
-# Copyright (C) 2008-2010 Sun Microsystems, Inc
+# Copyright (C) 2008-2009 Sun Microsystems, Inc
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -845,7 +845,7 @@ AC_CHECK_HEADERS(fcntl.h fenv.h float.h 
  sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
  unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \
  sys/ioctl.h malloc.h sys/malloc.h sys/ipc.h sys/shm.h linux/config.h \
- sys/prctl.h sys/resource.h sys/param.h port.h sys/epoll.h ieeefp.h \
+ sys/prctl.h sys/resource.h sys/param.h port.h ieeefp.h \
  execinfo.h)
 
 AC_CHECK_HEADERS([xfs/xfs.h])
@@ -2630,15 +2630,6 @@ then
   AC_DEFINE([HAVE_PTHREAD_ATTR_SETSCOPE], [1], [pthread_attr_setscope])
 fi
 
-# Check for Linux epoll(7).
-AC_MSG_CHECKING([for Linux epoll(7)])
-haveepoll=no
-AC_CHECK_FUNCS(epoll_ctl, [haveepoll=yes])
-if test "x$haveepoll" = "xyes" ; then
-  AC_DEFINE(HAVE_EPOLL, 1,
-    [System supports the epoll(7) system calls])
-fi
-
 # Check for bad includes
 AC_MSG_CHECKING("can netinet files be included")
 AC_TRY_COMPILE(

=== modified file 'include/mysql/plugin.h'
--- a/include/mysql/plugin.h	2010-01-28 00:01:26 +0000
+++ b/include/mysql/plugin.h	2010-02-15 14:02:12 +0000
@@ -566,6 +566,29 @@ unsigned long thd_get_thread_id(const MY
 */
 void thd_get_xid(const MYSQL_THD thd, MYSQL_XID *xid);
 
+struct scheduler_functions;
+
+/**
+  Set the thread scheduler to use for the server.
+
+  @param scheduler Pointer to scheduler callbacks to use.
+  @retval 0 Scheduler installed correctly.
+  @retval 1 Invalid value (NULL) used for scheduler.
+*/
+int thd_set_thread_scheduler(struct scheduler_functions *scheduler);
+
+/**
+  Restore the previous thread scheduler.
+
+  @note If no thread scheduler was installed previously with
+  thd_set_thread_scheduler, this function will report an error.
+
+  @retval 0 Scheduler installed correctly.
+  @retval 1 No scheduler installed.
+*/
+int thd_reset_thread_scheduler();
+
+
 /**
   Invalidate the query cache for a given table.
 

=== modified file 'include/mysql/plugin.h.pp'
--- a/include/mysql/plugin.h.pp	2010-02-04 05:27:55 +0000
+++ b/include/mysql/plugin.h.pp	2010-02-15 14:02:12 +0000
@@ -175,6 +175,9 @@ int mysql_tmpfile(const char *prefix);
 int thd_killed(const void* thd);
 unsigned long thd_get_thread_id(const void* thd);
 void thd_get_xid(const void* thd, MYSQL_XID *xid);
+struct scheduler_functions;
+int thd_set_thread_scheduler(struct scheduler_functions *scheduler);
+int thd_reset_thread_scheduler();
 void mysql_query_cache_invalidate4(void* thd,
                                    const char *key, unsigned int key_length,
                                    int using_trx);

=== modified file 'mysql-test/suite/rpl/combinations'
--- a/mysql-test/suite/rpl/combinations	2008-09-05 13:31:09 +0000
+++ b/mysql-test/suite/rpl/combinations	2010-02-11 09:41:40 +0000
@@ -6,3 +6,18 @@ binlog-format=statement
 
 [mix]
 binlog-format=mixed
+
+[stmt-thread_pool]
+binlog-format=statement
+plugin-dir=../plugin/thread_pool/.libs
+plugin-load=thread_pool=thread_pool.so
+
+[mix-thread_pool]
+binlog-format=mix
+plugin-dir=../plugin/thread_pool/.libs
+plugin-load=thread_pool=thread_pool.so
+
+[row-thread_pool]
+binlog-format=row
+plugin-dir=../plugin/thread_pool/.libs
+plugin-load=thread_pool=thread_pool.so

=== modified file 'mysql-test/suite/sys_vars/r/thread_pool_size_basic.result'
--- a/mysql-test/suite/sys_vars/r/thread_pool_size_basic.result	2010-01-18 15:43:30 +0000
+++ b/mysql-test/suite/sys_vars/r/thread_pool_size_basic.result	2010-02-11 09:41:40 +0000
@@ -7,6 +7,10 @@ COUNT(@@GLOBAL.thread_pool_size)
 SET @@GLOBAL.thread_pool_size=0;
 ERROR HY000: Variable 'thread_pool_size' is a read only variable
 Expected error  ER_INCORRECT_GLOBAL_LOCAL_VAR
+# Set from command line in .opt file
+SELECT @@GLOBAL.thread_pool_size;
+@@GLOBAL.thread_pool_size
+12
 SELECT COUNT(@@GLOBAL.thread_pool_size);
 COUNT(@@GLOBAL.thread_pool_size)
 1

=== added file 'mysql-test/suite/sys_vars/t/thread_pool_size_basic-master.opt'
--- a/mysql-test/suite/sys_vars/t/thread_pool_size_basic-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/thread_pool_size_basic-master.opt	2010-02-11 09:41:40 +0000
@@ -0,0 +1,4 @@
+--plugin-dir=../plugin/thread_pool/.libs
+--plugin-load=thread_pool=thread_pool.so
+--thread-pool-size=12
+

=== modified file 'mysql-test/suite/sys_vars/t/thread_pool_size_basic.test'
--- a/mysql-test/suite/sys_vars/t/thread_pool_size_basic.test	2010-01-19 17:07:12 +0000
+++ b/mysql-test/suite/sys_vars/t/thread_pool_size_basic.test	2010-02-15 14:02:12 +0000
@@ -43,6 +43,9 @@ SET @@GLOBAL.thread_pool_size=0;
 
 --ECHO Expected error  ER_INCORRECT_GLOBAL_LOCAL_VAR
 
+--echo # Set from command line in .opt file
+SELECT @@GLOBAL.thread_pool_size;
+
 SELECT COUNT(@@GLOBAL.thread_pool_size);
 --echo 1 Expected
 

=== added directory 'plugin/thread_pool'
=== added file 'plugin/thread_pool/Makefile.am'
--- a/plugin/thread_pool/Makefile.am	1970-01-01 00:00:00 +0000
+++ b/plugin/thread_pool/Makefile.am	2010-02-11 09:41:40 +0000
@@ -0,0 +1,33 @@
+# Copyright (C) 2006 MySQL AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+## Makefile.am for thread pool
+
+pkgplugindir =		$(pkglibdir)/plugin
+INCLUDES =              -I$(top_srcdir)/include \
+			-I$(top_srcdir)/sql \
+			-I$(top_srcdir)/regex \
+			-I$(srcdir)
+
+noinst_HEADERS = thread_pool.h 
+
+pkgplugin_LTLIBRARIES =	thread_pool.la
+
+thread_pool_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices
+thread_pool_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+thread_pool_la_CFLAGS =	$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+thread_pool_la_SOURCES = thread_pool_plugin.cc thread_pool.cc
+
+EXTRA_DIST=		CMakeLists.txt plug.in poll.cc epoll.cc

=== renamed file 'sql/scheduler_epoll.cc' => 'plugin/thread_pool/epoll.cc'
--- a/sql/scheduler_epoll.cc	2010-02-09 15:11:56 +0000
+++ b/plugin/thread_pool/epoll.cc	2010-02-15 14:02:12 +0000
@@ -46,7 +46,7 @@
 /*********************************************************************/
 #include <mysql_priv.h>
 #include "scheduler.h"
-#include "scheduler_thread_pool.h"
+#include "thread_pool.h"
 
 #include <time.h>
 #include <sys/epoll.h>

=== added file 'plugin/thread_pool/plug.in'
--- a/plugin/thread_pool/plug.in	1970-01-01 00:00:00 +0000
+++ b/plugin/thread_pool/plug.in	2010-02-15 14:02:12 +0000
@@ -0,0 +1,15 @@
+AC_CHECK_HEADERS(sys/epoll.h)
+
+# Check for Linux epoll(7).
+AC_MSG_CHECKING([for Linux epoll(7)])
+haveepoll=no
+AC_CHECK_FUNCS(epoll_ctl, [haveepoll=yes])
+AS_IF([test "x$haveepoll" = "xyes"],
+      [AC_DEFINE(HAVE_EPOLL, 1, [System supports the epoll(7) system calls])])
+
+# Check for Linux epoll(7). One Shot
+AC_MSG_CHECKING([for Linux epoll(7) support of EPOLLONESHOT])
+AC_CHECK_DECLS([EPOLLONESHOT], [], [], [[#include <sys/epoll.h>]])
+MYSQL_PLUGIN(thread_pool,[Thread Pool Plugin],
+        [Thread Pool Plugin])
+MYSQL_PLUGIN_DYNAMIC(thread_pool,   [thread_pool.la])

=== renamed file 'sql/scheduler_poll.cc' => 'plugin/thread_pool/poll.cc'
--- a/sql/scheduler_poll.cc	2010-02-09 15:11:56 +0000
+++ b/plugin/thread_pool/poll.cc	2010-02-15 14:02:12 +0000
@@ -49,8 +49,8 @@
 /* Includes */
 /*********************************************************************/
 #include <mysql_priv.h>
-#include "scheduler.h"
-#include "scheduler_thread_pool.h"
+#include <scheduler.h>
+#include "thread_pool.h"
 
 #include <time.h>
 #ifndef _WIN32

=== renamed file 'sql/scheduler_thread_pool.cc' => 'plugin/thread_pool/thread_pool.cc'
--- a/sql/scheduler_thread_pool.cc	2010-02-09 16:06:11 +0000
+++ b/plugin/thread_pool/thread_pool.cc	2010-02-15 14:02:12 +0000
@@ -30,13 +30,12 @@
 #define usleep(a) Sleep(max(1, a/1000))
 #endif
 
+#define MYSQL_SERVER
 #include <mysql_priv.h>
 #include <my_global.h>
 #include "probes_mysql.h"
 #include "scheduler.h"
-#include "scheduler_thread_pool.h"
-
-#ifdef HAVE_POOL_OF_THREADS
+#include "thread_pool.h"
 
 /*********************************************************************/
 /* Defines */
@@ -319,6 +318,9 @@ set_tp_psi_env(void)
 #define set_user_psi_env(thd) {}
 #define set_tp_psi_env() {}
 #endif
+
+ulong thread_pool_size= 0;
+
 /*********************************************************************/
 
 /*********************************************************************/
@@ -426,7 +428,7 @@ static inline void tp_thd_cleanup(THD *t
   if (close)
     close_connection(thd, errcode, 1);
 
-  thd->scheduler.pool_of_threads_context= NULL;
+  thd->scheduler.data= NULL;
 
   /*
     unlink_thd() does:
@@ -1344,12 +1346,9 @@ void thd_pool_end(void)
 
   DBUG_ENTER("thd_pool_end");
 
-  if (!have_thread_pool() ||
-      tp_shutdown == 1)
-  {
-    /* Either have no thread pool or it hasn't been started */
+  if (tp_shutdown == 1)
     DBUG_VOID_RETURN;
-  }
+
   tp_shutdown++;
   self= pthread_self();
 
@@ -1433,9 +1432,6 @@ bool thd_pool_init(void)
   tp_group_t *cur_group;
 
   DBUG_ENTER("thd_pool_init");
-  if (!have_thread_pool())
-    DBUG_RETURN(FALSE);
-
   if (init_tp_psi_keys())
     DBUG_RETURN(FALSE);
 
@@ -1630,18 +1626,18 @@ void thd_pool_add_connection(THD *thd)
        */
       thd->net.reading_or_writing= 1;
   
-      thd->scheduler.pool_of_threads_context= tp_client_low_level_init(
+      thd->scheduler.data= tp_client_low_level_init(
                 thd,
                 cur_group->group_low_level_cntx);
       DBUG_PRINT("info", ("Arming connection id %d", thd->thread_id));
-      if (thd->scheduler.pool_of_threads_context != NULL)
+      if (thd->scheduler.data != NULL)
       {
         if (tp_client_low_level_arm(
-           (tp_client_low_level_t)thd->scheduler.pool_of_threads_context) != 0)
+           (tp_client_low_level_t)thd->scheduler.data) != 0)
         {
           sql_print_error("tp_client_low_level_arm() failed");
           tp_client_low_level_end(
-            (tp_client_low_level_t)thd->scheduler.pool_of_threads_context);
+            (tp_client_low_level_t)thd->scheduler.data);
           tp_thd_cleanup(thd, TRUE, TRUE, 0);
         }
       }
@@ -1688,7 +1684,7 @@ void thd_pool_post_kill_notification(THD
   if (thd->net.vio != NULL)
   {
     my_tp_client_low_level_cntx=
-            (tp_client_low_level_t)thd->scheduler.pool_of_threads_context;
+            (tp_client_low_level_t)thd->scheduler.data;
     if (my_tp_client_low_level_cntx != NULL)
       tp_client_low_level_close(my_tp_client_low_level_cntx);
   }
@@ -1735,8 +1731,7 @@ void thd_pool_wait_begin(THD *thd, int w
       DBUG_VOID_RETURN;
   }
 
-  my_tp_client_low_level_cntx=
-          (tp_client_low_level_t)thd->scheduler.pool_of_threads_context;
+  my_tp_client_low_level_cntx= (tp_client_low_level_t) thd->scheduler.data;
 
   if (my_tp_client_low_level_cntx != NULL)
   {
@@ -1824,8 +1819,7 @@ void thd_pool_wait_end(THD *thd)
       DBUG_VOID_RETURN;
   }
 
-  my_tp_client_low_level_cntx=
-           (tp_client_low_level_t)thd->scheduler.pool_of_threads_context;
+  my_tp_client_low_level_cntx= (tp_client_low_level_t) thd->scheduler.data;
 
   if (my_tp_client_low_level_cntx != NULL)
   {
@@ -1855,9 +1849,9 @@ void thd_pool_wait_end(THD *thd)
 /*********************************************************************/
 
 #ifdef HAVE_EPOLL
-#include "scheduler_epoll.cc"
+#include "epoll.cc"
 #else
-#include "scheduler_poll.cc"
+#include "poll.cc"
 #endif
 
 #ifndef DBUG_OFF
@@ -2020,5 +2014,3 @@ get_highest_priority_query(tp_group_t *m
     DBUG_RETURN(client_cntx);
   DBUG_RETURN(NULL);
 }
-
-#endif

=== renamed file 'sql/scheduler_thread_pool.h' => 'plugin/thread_pool/thread_pool.h'
--- a/sql/scheduler_thread_pool.h	2010-02-04 08:41:15 +0000
+++ b/plugin/thread_pool/thread_pool.h	2010-02-15 14:02:12 +0000
@@ -40,5 +40,8 @@ void thd_pool_post_kill_notification(THD
 void thd_pool_wait_begin(THD *thd, int wait_type);
 void thd_pool_wait_end(THD *thd);
 void thd_pool_end(void);
+
+extern ulong thread_pool_size;
+
 #endif
 #endif

=== added file 'plugin/thread_pool/thread_pool_plugin.cc'
--- a/plugin/thread_pool/thread_pool_plugin.cc	1970-01-01 00:00:00 +0000
+++ b/plugin/thread_pool/thread_pool_plugin.cc	2010-02-11 09:41:40 +0000
@@ -0,0 +1,103 @@
+#define MYSQL_SERVER
+
+#include <mysql_priv.h>
+#include <mysql/plugin.h>
+#include <scheduler.h>
+#include "thread_pool.h"
+
+typedef struct st_mysql_sys_var SYS_VAR;
+
+/*
+  Pool of threads scheduler.
+
+  This is the scheduler we add if we have a pool of threads
+  implementation.
+
+  Linux: epoll
+  FreeBSD/Mac OS X: kqueue
+  Solaris: event_port
+  Windows: io completion ports (IOCP)
+*/
+
+static scheduler_functions pool_of_threads_scheduler=
+{
+  0,                                     // max_threads
+  thd_pool_init,                         // init
+  init_new_connection_handler_thread,    // init_new_connection_thread
+  thd_pool_add_connection,               // add_connection
+  thd_pool_wait_begin,                   // thd_wait_begin
+  thd_pool_wait_end,                     // thd_wait_end
+  NULL,                                  // post_kill_notification
+  NULL,                                  // end_thread
+  thd_pool_end,                          // end
+};
+
+/**
+  Thread pool initialization function.
+
+  Code to make this a daemon plugin. These plugins do not really do
+  anything, but it will allow options to be loaded and provide a value
+  to the thread scheduler.
+ */
+static int
+thread_pool_plugin_init(void *plugin __attribute__((unused)))
+{
+  DBUG_ENTER("thread_pool_plugin_init");
+  /*
+    We need to set this value dynamically since it is dependent on
+    what max_connections happens to have.
+   */
+  pool_of_threads_scheduler.max_threads=
+    max_connections + MAX_THREAD_GROUPS;
+  (void) thd_set_thread_scheduler(&pool_of_threads_scheduler);
+  DBUG_RETURN(0);
+}
+
+
+/**
+  Thread pool deinitialization function.
+ */
+static int thread_pool_plugin_deinit(void *ptr)
+{
+  DBUG_ENTER("thread_pool_plugin_deinit");
+  (void) thd_reset_thread_scheduler();
+  DBUG_RETURN(0);
+}
+
+
+static MYSQL_SYSVAR_ULONG(size, thread_pool_size,
+    PLUGIN_VAR_READONLY | PLUGIN_VAR_RQCMDARG,
+    "How many threads we should create to handle query requests",
+    NULL, NULL,                                 // check, update
+    16, 1, 16384, 1);                           // def, min, max, blk
+
+static SYS_VAR* thread_pool_system_vars[]= {
+  MYSQL_SYSVAR(size),
+  NULL,
+};
+
+struct st_mysql_daemon thread_pool_plugin=
+{ MYSQL_DAEMON_INTERFACE_VERSION  };
+
+
+/*
+  Plugin library descriptor
+*/
+
+mysql_declare_plugin(thread_pool)
+{
+  MYSQL_DAEMON_PLUGIN,
+  &thread_pool_plugin,
+  "thread_pool",
+  "Mikael Ronstrom, Kelly Long, Mats Kindahl",  // What order should be used?
+  "Threads pool implementation to handle multiple connections for each thread",
+  PLUGIN_LICENSE_GPL,
+  thread_pool_plugin_init,       /* plugin init */
+  thread_pool_plugin_deinit,     /* plugin deinit */
+  0x0009,                        /* 0.9: beta */
+  NULL,                          /* status variables */
+  thread_pool_system_vars,       /* system variables */
+  NULL                           /* config options */
+}
+mysql_declare_plugin_end;
+

=== modified file 'sql/Makefile.am'
--- a/sql/Makefile.am	2010-01-28 00:01:26 +0000
+++ b/sql/Makefile.am	2010-02-15 14:02:12 +0000
@@ -34,7 +34,6 @@ DTRACEFILES =           filesort.o \
                         mysqld.o \
                         net_serv.o \
                         scheduler.o \
-                        scheduler_thread_pool.o \
                         sp_head.o \
                         sql_cache.o \
                         sql_connect.o \
@@ -52,7 +51,6 @@ DTRACEFILES_DEPEND =    filesort.o \
                         mysqld.o \
                         net_serv.o \
                         scheduler.o \
-                        scheduler_thread_pool.o \
                         sp_head.o \
                         sql_cache.o \
                         sql_connect.o \
@@ -108,7 +106,7 @@ noinst_HEADERS =	item.h item_func.h item
 			tztime.h my_decimal.h keycaches.h \
 			sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \
 			parse_file.h sql_view.h	sql_trigger.h \
-			sql_array.h sql_cursor.h events.h scheduler.h scheduler_thread_pool.h \
+			sql_array.h sql_cursor.h events.h scheduler.h \
                         event_db_repository.h event_queue.h \
 			sql_plugin.h authors.h event_parse_data.h \
 			event_data_objects.h event_scheduler.h \
@@ -127,7 +125,7 @@ mysqld_SOURCES =	sql_lex.cc sql_handler.
 			lock.cc my_lock.c \
 			sql_string.cc sql_manager.cc sql_map.cc \
 			mysqld.cc password.c hash_filo.cc hostname.cc \
-			sql_connect.cc scheduler.cc scheduler_thread_pool.cc sql_parse.cc \
+			sql_connect.cc scheduler.cc sql_parse.cc \
 			keycaches.cc set_var.cc sql_yacc.yy sys_vars.cc \
 			sql_base.cc table.cc sql_select.cc sql_insert.cc \
 			sql_profile.cc \
@@ -190,7 +188,6 @@ BUILT_SOURCES =		$(BUILT_MAINT_SRC) lex_
 EXTRA_DIST =		udf_example.c udf_example.def $(BUILT_MAINT_SRC) \
 			nt_servc.cc nt_servc.h \
 			message.mc  message.h message.rc MSG00001.bin \
-			scheduler_epoll.cc scheduler_poll.cc \
 			CMakeLists.txt
 
 CLEANFILES =        	lex_hash.h sql_yacc.output link_sources

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2010-02-08 07:46:04 +0000
+++ b/sql/mysql_priv.h	2010-02-15 14:02:12 +0000
@@ -1990,7 +1990,7 @@ extern ulong binlog_cache_size, open_fil
 extern ulonglong max_binlog_cache_size;
 extern ulong max_binlog_size, max_relay_log_size;
 extern ulong opt_binlog_rows_event_max_size;
-extern ulong rpl_recovery_rank, thread_cache_size, thread_pool_size;
+extern ulong rpl_recovery_rank, thread_cache_size;
 extern ulong back_log;
 #endif /* MYSQL_SERVER */
 #if defined MYSQL_SERVER || defined INNODB_COMPATIBILITY_HOOKS
@@ -2111,7 +2111,6 @@ extern HASH open_cache, lock_db_cache;
 extern TABLE *unused_tables;
 extern const char* any_db;
 extern const LEX_STRING view_type;
-extern scheduler_functions thread_scheduler;
 extern TYPELIB thread_handling_typelib;
 extern uint8 uc_update_queries[SQLCOM_END+1];
 extern uint sql_command_flags[];

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2010-02-08 07:46:04 +0000
+++ b/sql/mysqld.cc	2010-02-15 14:02:12 +0000
@@ -28,9 +28,9 @@
 #include "events.h"
 #include "sql_audit.h"
 #include "probes_mysql.h"
-#include "scheduler_thread_pool.h"
 #include "scheduler.h"
 #include "debug_sync.h"
+#include "sql_callback.h"
 
 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
 #include "../storage/perfschema/pfs_server.h"
@@ -458,7 +458,7 @@ ulong open_files_limit, max_binlog_size,
 ulong slave_net_timeout, slave_trans_retries;
 uint slave_exec_mode_options;
 ulonglong slave_type_conversions_options;
-ulong thread_cache_size=0, thread_pool_size= 0;
+ulong thread_cache_size=0;
 ulong binlog_cache_size=0;
 ulonglong  max_binlog_cache_size=0;
 ulong query_cache_size=0;
@@ -889,8 +889,6 @@ my_bool opt_enable_shared_memory;
 HANDLE smem_event_connect_request= 0;
 #endif
 
-scheduler_functions thread_scheduler;
-
 my_bool opt_use_ssl  = 0;
 char *opt_ssl_ca= NULL, *opt_ssl_capath= NULL, *opt_ssl_cert= NULL,
      *opt_ssl_cipher= NULL, *opt_ssl_key= NULL;
@@ -1079,7 +1077,7 @@ static void close_connections(void)
       continue;
 
     tmp->killed= THD::KILL_CONNECTION;
-    thread_scheduler.post_kill_notification(tmp);
+    MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp));
     mysql_mutex_lock(&tmp->LOCK_thd_data);
     if (tmp->mysys_var)
     {
@@ -1487,7 +1485,7 @@ void clean_up(bool print_message)
   if (print_message && my_default_lc_messages && server_start_time)
     sql_print_information(ER_DEFAULT(ER_SHUTDOWN_COMPLETE),my_progname);
   cleanup_errmsgs();
-  thread_scheduler.end();
+  MYSQL_CALLBACK(thread_scheduler, end, ());
   finish_client_errs();
   DBUG_PRINT("quit", ("Error messages freed"));
   /* Tell main we are ready */
@@ -1767,7 +1765,7 @@ static void network_init(void)
   DBUG_ENTER("network_init");
   LINT_INIT(ret);
 
-  if (thread_scheduler.init())
+  if (MYSQL_CALLBACK_ELSE(thread_scheduler, init, (), 0))
     unireg_abort(1);			/* purecov: inspected */
 
   set_ports();
@@ -2015,7 +2013,7 @@ extern "C" sig_handler end_thread_signal
   if (thd && ! thd->bootstrap)
   {
     statistic_increment(killed_threads, &LOCK_status);
-    thread_scheduler.end_thread(thd,0);		/* purecov: inspected */
+    MYSQL_CALLBACK(thread_scheduler, end_thread, (thd,0)); /* purecov: inspected */
   }
   DBUG_VOID_RETURN;				/* purecov: deadcode */
 }
@@ -2623,7 +2621,7 @@ and this may fail.\n\n");
           (ulong) dflt_key_cache->key_cache_mem_size);
   fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
   fprintf(stderr, "max_used_connections=%lu\n", max_used_connections);
-  fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads);
+  fprintf(stderr, "max_threads=%u\n", thread_scheduler->max_threads);
   fprintf(stderr, "thread_count=%u\n", thread_count);
   fprintf(stderr, "connection_count=%u\n", connection_count);
   fprintf(stderr, "It is possible that mysqld could use up to \n\
@@ -2631,7 +2629,7 @@ key_buffer_size + (read_buffer_size + so
 bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size +
 		     (global_system_variables.read_buff_size +
 		      global_system_variables.sortbuff_size) *
-		     thread_scheduler.max_threads +
+		     thread_scheduler->max_threads +
                      max_connections * sizeof(THD)) / 1024);
   fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
 
@@ -2876,7 +2874,7 @@ pthread_handler_t signal_hand(void *arg 
     This should actually be '+ max_number_of_slaves' instead of +10,
     but the +10 should be quite safe.
   */
-  init_thr_alarm(thread_scheduler.max_threads +
+  init_thr_alarm(thread_scheduler->max_threads +
 		 global_system_variables.max_insert_delayed_threads + 10);
   if (thd_lib_detected != THD_LIB_LT && (test_flags & TEST_SIGINT))
   {
@@ -5290,7 +5288,7 @@ static void create_new_thread(THD *thd)
 
   thread_count++;
 
-  thread_scheduler.add_connection(thd);
+  MYSQL_CALLBACK(thread_scheduler, add_connection, (thd));
 
   DBUG_VOID_RETURN;
 }
@@ -7591,10 +7589,7 @@ static int get_options(int *argc_ptr, ch
   if (mysqld_chroot)
     set_root(mysqld_chroot);
   if (opt_bootstrap)
-    thread_handling= SCHEDULER_ONE_THREAD_PER_CONNECTION;
-  if (thread_handling == SCHEDULER_POOL_OF_THREADS &&
-      !have_thread_pool())
-    thread_handling= SCHEDULER_ONE_THREAD_PER_CONNECTION;
+    thread_handling= SCHEDULER_NO_THREADS;
 #else
   thread_handling = SCHEDULER_NO_THREADS;
   max_allowed_packet= global_system_variables.max_allowed_packet;
@@ -7625,19 +7620,14 @@ static int get_options(int *argc_ptr, ch
     return 1;
 
 #ifdef EMBEDDED_LIBRARY
-  one_thread_scheduler(&thread_scheduler);
+  one_thread_scheduler(thread_scheduler);
 #else
   switch (thread_handling) {
   case SCHEDULER_NO_THREADS:
-    one_thread_scheduler(&thread_scheduler);
+    one_thread_scheduler(thread_scheduler);
     break;
-#ifdef HAVE_POOL_OF_THREADS
-  case SCHEDULER_POOL_OF_THREADS:
-    pool_of_threads_scheduler(&thread_scheduler);
-    break;
-#endif
   default:
-     one_thread_per_connection_scheduler(&thread_scheduler);
+     one_thread_per_connection_scheduler(thread_scheduler);
     break;
   }
 #endif

=== modified file 'sql/scheduler.cc'
--- a/sql/scheduler.cc	2010-02-08 07:42:41 +0000
+++ b/sql/scheduler.cc	2010-02-15 14:02:12 +0000
@@ -22,7 +22,6 @@
 #endif
 
 #include <mysql_priv.h>
-#include "scheduler_thread_pool.h"
 #include "scheduler.h"
 
 /*
@@ -35,21 +34,21 @@ static void post_kill_dummy(THD* thd) {}
 static void end_dummy(void) {}
 static bool end_thread_dummy(THD *thd, bool cache_thread) { return 0; }
 
-/*
-  Initialize default scheduler with dummy functions so that setup functions
-  only need to declare those that are relvant for their usage
-*/
+static scheduler_functions basic_thread_scheduler=
+{
+  0,                                     // max_threads
+  init_dummy,                            // init
+  init_new_connection_handler_thread,    // init_new_connection_thread
+  0,                                     // add_connection
+  NULL,                                  // thd_wait_begin
+  NULL,                                  // thd_wait_end
+  post_kill_dummy,                       // post_kill_notification
+  end_thread_dummy,                      // end_thread
+  end_dummy,                             // end
+};
 
-scheduler_functions::scheduler_functions()
-  :init(init_dummy),
-   init_new_connection_thread(init_new_connection_handler_thread),
-   add_connection(0),                           // Must be defined
-   thd_wait_begin(NULL),
-   thd_wait_end(NULL),
-   post_kill_notification(post_kill_dummy),
-   end_thread(end_thread_dummy), end(end_dummy)
-{}
 
+scheduler_functions *thread_scheduler= &basic_thread_scheduler;
 
 /*
   End connection, in case when we are using 'no-threads'
@@ -90,33 +89,6 @@ void one_thread_scheduler(scheduler_func
 }
 
 
-#ifdef HAVE_POOL_OF_THREADS
-/*
-  pool_of_threads_scheduler
- 
-  This is the scheduler we add if we have a pool of threads implementation
-  Linux: epoll
-  FreeBSD/Mac OS X: kqueue
-  Solaris: event_port
-  Windows: io completion ports (IOCP)
-*/
-
-/*
-  Initialize scheduler for --thread-handling=pool-of-threads
-*/
-
-void pool_of_threads_scheduler(scheduler_functions *func)
-{
-  func->max_threads= max_connections + MAX_THREAD_GROUPS;
-  func->init= thd_pool_init;
-  func->add_connection= thd_pool_add_connection;
-  func->post_kill_notification= thd_pool_post_kill_notification;
-  func->thd_wait_begin= thd_pool_wait_begin;
-  func->thd_wait_end= thd_pool_wait_end;
-  func->end= thd_pool_end;
-}
-#endif
-
 /*
   Initialize scheduler for --thread-handling=one-thread-per-connection
 */
@@ -127,10 +99,7 @@ void pool_of_threads_scheduler(scheduler
 */
 
 thd_scheduler::thd_scheduler()
-  : m_psi(NULL)
-#ifdef HAVE_POOL_OF_THREADS
-    , pool_of_threads_context(NULL)
-#endif
+  : m_psi(NULL), data(NULL)
 {
 #ifndef DBUG_OFF
   dbug_explain[0]= '\0';
@@ -143,3 +112,39 @@ thd_scheduler::~thd_scheduler()
 {
 }
 
+
+static scheduler_functions *saved_thread_scheduler;
+static uint saved_thread_handling;
+
+extern "C"
+int thd_set_thread_scheduler(scheduler_functions *scheduler)
+{
+  DBUG_ASSERT(scheduler != 0);
+
+  if (scheduler == NULL)
+    return 1;
+
+  saved_thread_scheduler= thread_scheduler;
+  saved_thread_handling= thread_handling;
+  thread_scheduler= scheduler;
+  thread_handling= SCHEDULER_TYPES_COUNT;
+  return 0;
+}
+
+
+extern "C"
+int thd_reset_thread_scheduler()
+{
+  DBUG_ASSERT(saved_thread_scheduler != NULL);
+
+  if (saved_thread_scheduler == NULL)
+    return 1;
+
+  thread_scheduler= saved_thread_scheduler;
+  thread_handling= saved_thread_handling;
+  saved_thread_scheduler= 0;
+  return 0;
+}
+
+
+

=== modified file 'sql/scheduler.h'
--- a/sql/scheduler.h	2010-02-08 07:42:41 +0000
+++ b/sql/scheduler.h	2010-02-15 14:02:12 +0000
@@ -24,33 +24,12 @@
 #pragma interface
 #endif
 
-#if !defined(EMBEDDED_LIBRARY)
-#if defined (HAVE_EPOLL) || defined (HAVE_POLL) || defined (_WIN32)
-#  define HAVE_POOL_OF_THREADS 1
-#endif
-#endif
-
-#ifdef _WIN32
-  bool have_thread_pool();
-#else
-inline bool
-have_thread_pool()
-{
-#ifdef HAVE_POOL_OF_THREADS
-  return TRUE;
-#else
-  return FALSE;
-#endif
-}
-#endif
-
 class THD;
 
 /* Functions used when manipulating threads */
 
-class scheduler_functions
+struct scheduler_functions
 {
-public:
   uint max_threads;
   bool (*init)(void);
   bool (*init_new_connection_thread)(void);
@@ -60,26 +39,27 @@ public:
   void (*post_kill_notification)(THD *thd);
   bool (*end_thread)(THD *thd, bool cache_thread);
   void (*end)(void);
-  scheduler_functions();
 };
 
+
+/**
+  Scheduler types enumeration.
+
+  The default of --thread-handling is the first one in the
+  thread_handling_names array, this array has to be consistent with
+  the order in this array, so to change default one has to change the
+  first entry in this enum and the first entry in the
+  thread_handling_names array.
+
+  @note The last entry of the enumeration is also used to mark the
+  thread handling as dynamic. In this case the name of the thread
+  handling is fetched from the name of the plugin that implements it.
+*/
 enum scheduler_types
 {
-  /*
-    The default of --thread-handling is the first one in the
-    thread_handling_names array, this array has to be consistent with
-    the order in this array, so to change default one has to change
-    the first entry in this enum and the first entry in the
-    thread_handling_names array.
-  */
-#ifdef HAVE_POOL_OF_THREADS
-  SCHEDULER_POOL_OF_THREADS=0,
-  SCHEDULER_ONE_THREAD_PER_CONNECTION,
-#else
   SCHEDULER_ONE_THREAD_PER_CONNECTION=0,
-#endif
   SCHEDULER_NO_THREADS,
-  SCHEDULER_dummy		// Allow trailing comma on each of the above
+  SCHEDULER_TYPES_COUNT
 };
 
 void one_thread_per_connection_scheduler(scheduler_functions* func);
@@ -108,9 +88,7 @@ public:
   */
   PSI_thread *m_psi;
 
-#ifdef HAVE_POOL_OF_THREADS
-  void * pool_of_threads_context;   /* scheduler-specific data structure */
-#endif
+  void *data;                  /* scheduler-specific data structure */
 
 #  ifndef DBUG_OFF
   char dbug_explain[512];
@@ -121,7 +99,6 @@ public:
   ~thd_scheduler();
 };
 
-#ifdef HAVE_POOL_OF_THREADS
-void pool_of_threads_scheduler(scheduler_functions *func);
-#endif
+extern scheduler_functions *thread_scheduler;
+
 #endif

=== added file 'sql/sql_callback.h'
--- a/sql/sql_callback.h	1970-01-01 00:00:00 +0000
+++ b/sql/sql_callback.h	2010-02-15 14:02:12 +0000
@@ -0,0 +1,41 @@
+#ifndef SQL_CALLBACK_INCLUDED
+#define SQL_CALLBACK_INCLUDED
+
+/* Copyright (C) 2010 Sun Microsystems, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/**
+   Macro used for an internal callback.
+
+   The macro will check that the object exists and that the function
+   is defined. If that is the case, it will call the function with the
+   given parameters.
+
+   If the object or the function is not defined, the callback will be
+   considered successful (nothing needed to be done) and will
+   therefore return no error.
+ */
+
+#define MYSQL_CALLBACK(OBJ, FUNC, PARAMS)         \
+  do {                                            \
+    if ((OBJ) && ((OBJ)->FUNC))                   \
+      (OBJ)->FUNC PARAMS;                         \
+  } while (0)
+
+#define MYSQL_CALLBACK_ELSE(OBJ, FUNC, PARAMS, ELSE)    \
+  (((OBJ) && ((OBJ)->FUNC)) ? (OBJ)->FUNC PARAMS : (ELSE))
+
+
+#endif /* SQL_CALLBACK_INCLUDED */

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2010-02-05 09:22:17 +0000
+++ b/sql/sql_class.cc	2010-02-15 14:02:12 +0000
@@ -45,6 +45,7 @@
 #include "sp_rcontext.h"
 #include "sp_cache.h"
 #include "debug_sync.h"
+#include "sql_callback.h"
 
 /*
   The following is used to initialise Table_ident with a internal
@@ -1135,7 +1136,7 @@ void THD::awake(THD::killed_state state_
   {
     thr_alarm_kill(thread_id);
     if (!slave_thread)
-      thread_scheduler.post_kill_notification(this);
+      MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (this));
 #ifdef SIGNAL_WITH_VIO_CLOSE
     if (this != current_thd)
     {
@@ -3152,8 +3153,7 @@ extern "C" void thd_pool_wait_end(MYSQL_
 */
 extern "C" void thd_wait_begin(MYSQL_THD thd, thd_wait_type wait_type)
 {
-  if (thread_scheduler.thd_wait_begin != NULL)
-    thread_scheduler.thd_wait_begin(thd, wait_type);
+  MYSQL_CALLBACK(thread_scheduler, thd_wait_begin, (thd, wait_type));
 }
 
 /**
@@ -3164,8 +3164,7 @@ extern "C" void thd_wait_begin(MYSQL_THD
 */
 extern "C" void thd_wait_end(MYSQL_THD thd)
 {
-  if (thread_scheduler.thd_wait_end != NULL)
-    thread_scheduler.thd_wait_end(thd);
+  MYSQL_CALLBACK(thread_scheduler, thd_wait_end, (thd));
 }
 #else
 extern "C" void thd_wait_begin(MYSQL_THD thd, thd_wait_type wait_type)

=== modified file 'sql/sql_connect.cc'
--- a/sql/sql_connect.cc	2010-02-08 07:46:04 +0000
+++ b/sql/sql_connect.cc	2010-02-15 14:02:12 +0000
@@ -21,6 +21,7 @@
 #include "mysql_priv.h"
 #include "sql_audit.h"
 #include "probes_mysql.h"
+#include "sql_callback.h"
 
 #ifdef HAVE_OPENSSL
 /*
@@ -944,7 +945,7 @@ bool setup_connection_thread_globals(THD
   {
     close_connection(thd, ER_OUT_OF_RESOURCES, 1);
     statistic_increment(aborted_connects,&LOCK_status);
-    thread_scheduler.end_thread(thd, 0);
+    MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0));
     return 1;                                   // Error
   }
   return 0;
@@ -1120,11 +1121,11 @@ void do_handle_one_connection(THD *thd_a
 
   thd->thr_create_utime= my_micro_time();
 
-  if (thread_scheduler.init_new_connection_thread())
+  if (MYSQL_CALLBACK_ELSE(thread_scheduler, init_new_connection_thread, (), 0))
   {
     close_connection(thd, ER_OUT_OF_RESOURCES, 1);
     statistic_increment(aborted_connects,&LOCK_status);
-    thread_scheduler.end_thread(thd,0);
+    MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0));
     return;
   }
 
@@ -1178,7 +1179,7 @@ void do_handle_one_connection(THD *thd_a
    
 end_thread:
     close_connection(thd, 0, 1);
-    if (thread_scheduler.end_thread(thd,1))
+    if (MYSQL_CALLBACK_ELSE(thread_scheduler, end_thread, (thd, 1), 0))
       return;                                 // Probably no-threads
 
     /*

=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc	2010-02-09 15:13:01 +0000
+++ b/sql/sys_vars.cc	2010-02-15 14:02:12 +0000
@@ -1604,10 +1604,7 @@ static Sys_var_ulong Sys_trans_prealloc_
 
 static const char *thread_handling_names[]=
 {
-#ifdef HAVE_POOL_OF_THREADS
-  "pool-of-threads",
-#endif
-  "one-thread-per-connection", "no-threads",
+  "one-thread-per-connection", "no-threads", "loaded-dynamically",
   0
 };
 static Sys_var_enum Sys_thread_handling(
@@ -1950,15 +1947,6 @@ static Sys_var_ulong Sys_thread_cache_si
        GLOBAL_VAR(thread_cache_size), CMD_LINE(REQUIRED_ARG),
        VALID_RANGE(0, 16384), DEFAULT(0), BLOCK_SIZE(1));
 
-#ifdef HAVE_POOL_OF_THREADS
-static Sys_var_ulong Sys_thread_pool_size(
-       "thread_pool_size",
-       "How many threads we should create to handle query requests in "
-       "case of 'thread_handling=pool-of-threads'",
-       READ_ONLY GLOBAL_VAR(thread_pool_size), CMD_LINE(REQUIRED_ARG),
-       VALID_RANGE(1, 32), DEFAULT(16), BLOCK_SIZE(1));
-#endif
-
 //  Can't change the 'next' tx_isolation if we are already in a transaction
 static bool check_tx_isolation(sys_var *self, THD *thd, set_var *var)
 {


Attachment: [text/bzr-bundle] bzr/mats@sun.com-20100215140212-rq6mfidtiuu6ul06.bundle
Thread
bzr commit into mysql-5.5-next-mr branch (mats:3045) WL#5136Mats Kindahl15 Feb
  • Re: bzr commit into mysql-5.5-next-mr branch (mats:3045) WL#5136Sergei Golubchik15 Feb
    • Re: bzr commit into mysql-5.5-next-mr branch (mats:3045) WL#5136Mats Kindahl15 Feb
      • Re: bzr commit into mysql-5.5-next-mr branch (mats:3045) WL#5136Sergei Golubchik15 Feb
        • Re: bzr commit into mysql-5.5-next-mr branch (mats:3045) WL#5136Mats Kindahl15 Feb
          • Re: bzr commit into mysql-5.5-next-mr branch (mats:3045) WL#5136Sergei Golubchik15 Feb
            • Re: bzr commit into mysql-5.5-next-mr branch (mats:3045) WL#5136Mats Kindahl15 Feb