MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Vladislav Vaintroub Date:September 30 2009 3:40pm
Subject:bzr commit into mysql-next-mr-wtf branch (vvaintroub:2884)
View as plain text  
#At file:///H:/bzr/mysql-next-mr/ based on revid:vvaintroub@stripped

 2884 Vladislav Vaintroub	2009-09-30
      Backport of this changeset 
      http://lists.mysql.com/commits/59686
      
      Cleanup pthread_self(), pthread_create(), pthread_join() implementation on Windows.
      Prior implementation is was unnecessarily complicated and even differs in embedded
      and non-embedded case.
            
      Improvements in this patch:
      * pthread_t is now the unique thread ID, instead of HANDLE returned by beginthread
            
      This simplifies pthread_self() to be just straight GetCurrentThreadId().
      prior it was much  art involved in passing the beginthread() handle from the caller
      to the TLS structure in the child thread ( did not work for the main thread of
      course)
            
      * remove MySQL specific my_thread_init()/my_thread_end() from pthread_create.
      No automagic is done on Unix on pthread_create(). Having the same on Windows will 
      improve portability and avoid extra #ifdef's
            
      * remove redefinition of getpid() - it was defined as GetCurrentThreadId()

    modified:
      include/config-win.h
      include/my_pthread.h
      libmysqld/CMakeLists.txt
      mysys/my_thr_init.c
      mysys/my_wincond.c
      mysys/my_winthread.c
      sql/mysqld.cc
      sql/sql_connect.cc
      sql/sql_insert.cc
=== modified file 'include/config-win.h'
--- a/include/config-win.h	2009-09-11 20:26:35 +0000
+++ b/include/config-win.h	2009-09-30 15:40:12 +0000
@@ -27,6 +27,9 @@
 #include <fcntl.h>
 #include <io.h>
 #include <malloc.h>
+#include <sys/stat.h>
+#include <process.h>     /* getpid()*/
+
 
 #define HAVE_SMEM 1
 

=== modified file 'include/my_pthread.h'
--- a/include/my_pthread.h	2009-09-30 01:22:57 +0000
+++ b/include/my_pthread.h	2009-09-30 15:40:12 +0000
@@ -31,7 +31,7 @@ extern "C" {
 
 #if defined(__WIN__)
 typedef CRITICAL_SECTION pthread_mutex_t;
-typedef HANDLE		 pthread_t;
+typedef DWORD		 pthread_t;
 typedef struct thread_attr {
     DWORD dwStackSize ;
     DWORD dwCreatingFlag ;
@@ -64,8 +64,7 @@ typedef struct {
 
 
 typedef int pthread_mutexattr_t;
-#define win_pthread_self my_thread_var->pthread_self
-#define pthread_self() win_pthread_self
+#define pthread_self() GetCurrentThreadId()
 #define pthread_handler_t EXTERNC void * __cdecl
 typedef void * (__cdecl *pthread_handler)(void *);
 
@@ -99,7 +98,7 @@ struct timespec {
   (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
 }
 
-void win_pthread_init(void);
+
 int win_pthread_mutex_trylock(pthread_mutex_t *mutex);
 int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *);
 int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
@@ -116,11 +115,11 @@ int pthread_attr_destroy(pthread_attr_t 
 struct tm *localtime_r(const time_t *timep,struct tm *tmp);
 struct tm *gmtime_r(const time_t *timep,struct tm *tmp);
 
+void pthread_exit(void *a);
+int pthread_join(pthread_t thread, void **value_ptr);
 
-void pthread_exit(void *a);	 /* was #define pthread_exit(A) ExitThread(A)*/
 
 #define ETIMEDOUT 145		    /* Win32 doesn't have this */
-#define getpid() GetCurrentThreadId()
 #define HAVE_LOCALTIME_R		1
 #define _REENTRANT			1
 #define HAVE_PTHREAD_ATTR_SETSTACKSIZE	1
@@ -145,7 +144,6 @@ void pthread_exit(void *a);	 /* was #def
 #define my_pthread_setprio(A,B)  SetThreadPriority(GetCurrentThread(), (B))
 #define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH)
 
-#define pthread_join(A,B) (WaitForSingleObject((A), INFINITE) != WAIT_OBJECT_0)
 
 /* Dummy defines for easier code */
 #define pthread_attr_setdetachstate(A,B) pthread_dummy(0)

=== modified file 'libmysqld/CMakeLists.txt'
--- a/libmysqld/CMakeLists.txt	2009-09-30 13:35:01 +0000
+++ b/libmysqld/CMakeLists.txt	2009-09-30 15:40:12 +0000
@@ -130,7 +130,7 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libm
            ../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc
            ../sql/partition_info.cc ../sql/sql_connect.cc 
            ../sql/scheduler.cc ../sql/event_parse_data.cc
-           ./sql/sql_signal.cc
+           ../sql/sql_signal.cc
            ${GEN_SOURCES}
            ${LIB_SOURCES})
 

=== modified file 'mysys/my_thr_init.c'
--- a/mysys/my_thr_init.c	2009-09-30 01:22:57 +0000
+++ b/mysys/my_thr_init.c	2009-09-30 15:40:12 +0000
@@ -42,7 +42,9 @@ pthread_mutexattr_t my_fast_mutexattr;
 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
 pthread_mutexattr_t my_errorcheck_mutexattr;
 #endif
-
+#ifdef _MSC_VER
+static void install_sigabrt_handler();
+#endif
 #ifdef TARGET_OS_LINUX
 
 /*
@@ -145,15 +147,18 @@ my_bool my_thread_global_init(void)
   pthread_mutex_init(&THR_LOCK_threads,MY_MUTEX_INIT_FAST);
   pthread_mutex_init(&THR_LOCK_time,MY_MUTEX_INIT_FAST);
   pthread_cond_init(&THR_COND_threads, NULL);
-#if defined( __WIN__) || defined(OS2)
-  win_pthread_init();
-#endif
+
 #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
   pthread_mutex_init(&LOCK_localtime_r,MY_MUTEX_INIT_SLOW);
 #endif
 #ifndef HAVE_GETHOSTBYNAME_R
   pthread_mutex_init(&LOCK_gethostbyname_r,MY_MUTEX_INIT_SLOW);
 #endif
+
+#ifdef _MSC_VER
+  install_sigabrt_handler();
+#endif
+
   if (my_thread_init())
   {
     my_thread_global_end();			/* Clean up */
@@ -268,11 +273,7 @@ my_bool my_thread_init(void)
     goto end;
   }
   pthread_setspecific(THR_KEY_mysys,tmp);
-#if defined(__WIN__) && defined(EMBEDDED_LIBRARY)
-  tmp->pthread_self= (pthread_t) getpid();
-#else
   tmp->pthread_self= pthread_self();
-#endif
   pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
   pthread_cond_init(&tmp->suspend, NULL);
   tmp->init= 1;
@@ -398,4 +399,30 @@ static uint get_thread_lib(void)
   return THD_LIB_OTHER;
 }
 
+#ifdef _WIN32
+/*
+  In Visual Studio 2005 and later, default SIGABRT handler will overwrite
+  any unhandled exception filter set by the application  and will try to
+  call JIT debugger. This is not what we want, this we calling __debugbreak
+  to stop in debugger, if process is being debugged or to generate 
+  EXCEPTION_BREAKPOINT and then handle_segfault will do its magic.
+*/
+
+#if (_MSC_VER >= 1400)
+static void my_sigabrt_handler(int sig)
+{
+  __debugbreak();
+}
+#endif /*_MSC_VER >=1400 */
+
+static void install_sigabrt_handler(void)
+{
+#if (_MSC_VER >=1400)
+  /*abort() should not override our exception filter*/
+  _set_abort_behavior(0,_CALL_REPORTFAULT);
+  signal(SIGABRT,my_sigabrt_handler);
+#endif /* _MSC_VER >=1400 */
+}
+#endif
+
 #endif /* THREAD */

=== modified file 'mysys/my_wincond.c'
--- a/mysys/my_wincond.c	2007-05-10 09:59:39 +0000
+++ b/mysys/my_wincond.c	2009-09-30 15:40:12 +0000
@@ -16,12 +16,11 @@
 /*****************************************************************************
 ** The following is a simple implementation of posix conditions
 *****************************************************************************/
+#if defined(_WIN32)
 
 #undef SAFE_MUTEX			/* Avoid safe_mutex redefinitions */
 #include "mysys_priv.h"
-#if defined(THREAD) && defined(__WIN__)
 #include <m_string.h>
-#undef getpid
 #include <process.h>
 #include <sys/timeb.h>
 

=== modified file 'mysys/my_winthread.c'
--- a/mysys/my_winthread.c	2009-09-30 01:22:57 +0000
+++ b/mysys/my_winthread.c	2009-09-30 15:40:12 +0000
@@ -14,33 +14,23 @@
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
 /*****************************************************************************
-** Simulation of posix threads calls for WIN95 and NT
+** Simulation of posix threads calls for Windows
 *****************************************************************************/
-
+#if defined (_WIN32)
 /* SAFE_MUTEX will not work until the thread structure is up to date */
 #undef SAFE_MUTEX
-
 #include "mysys_priv.h"
-#if defined(THREAD) && defined(__WIN__)
-#include <m_string.h>
-#undef getpid
 #include <process.h>
+#include <signal.h>
 
-static pthread_mutex_t THR_LOCK_thread;
+static void install_sigabrt_handler(void);
 
-struct pthread_map
+struct thread_start_parameter
 {
-  HANDLE pthreadself;
   pthread_handler func;
-  void *param;
+  void *arg;
 };
 
-void win_pthread_init(void)
-{
-  pthread_mutex_init(&THR_LOCK_thread,MY_MUTEX_INIT_FAST);
-}
-
-
 /**
    Adapter to @c pthread_mutex_trylock()
 
@@ -62,72 +52,81 @@ win_pthread_mutex_trylock(pthread_mutex_
   return EBUSY;
 }
 
-
-/*
-** We have tried to use '_beginthreadex' instead of '_beginthread' here
-** but in this case the program leaks about 512 characters for each
-** created thread !
-** As we want to save the created thread handler for other threads to
-** use and to be returned by pthread_self() (instead of the Win32 pseudo
-** handler), we have to go trough pthread_start() to catch the returned handler
-** in the new thread.
-*/
-
-pthread_handler_t pthread_start(void *param)
-{
-  pthread_handler func=((struct pthread_map *) param)->func;
-  void *func_param=((struct pthread_map *) param)->param;
-  my_thread_init();			/* Will always succeed in windows */
-  pthread_mutex_lock(&THR_LOCK_thread);	  /* Wait for beginthread to return */
-  win_pthread_self=((struct pthread_map *) param)->pthreadself;
-  pthread_mutex_unlock(&THR_LOCK_thread);
-  free((char*) param);			  /* Free param from create */
-  pthread_exit((void*) (*func)(func_param));
-  return 0;				  /* Safety */
+static unsigned int __stdcall pthread_start(void *p)
+{
+  struct thread_start_parameter *par= (struct thread_start_parameter *)p;
+  pthread_handler func= par->func;
+  void *arg= par->arg;
+  free(p);
+  (*func)(arg);
+  return 0;
 }
 
 
 int pthread_create(pthread_t *thread_id, pthread_attr_t *attr,
-		   pthread_handler func, void *param)
+     pthread_handler func, void *param)
 {
-  HANDLE hThread;
-  struct pthread_map *map;
+  uintptr_t handle;
+  struct thread_start_parameter *par;
+  unsigned int  stack_size;
   DBUG_ENTER("pthread_create");
 
-  if (!(map=malloc(sizeof(*map))))
-    DBUG_RETURN(-1);
-  map->func=func;
-  map->param=param;
-  pthread_mutex_lock(&THR_LOCK_thread);
-#ifdef __BORLANDC__
-  hThread=(HANDLE)_beginthread((void(_USERENTRY *)(void *)) pthread_start,
-			       attr->dwStackSize ? attr->dwStackSize :
-			       65535, (void*) map);
-#else
-  hThread=(HANDLE)_beginthread((void( __cdecl *)(void *)) pthread_start,
-			       attr->dwStackSize ? attr->dwStackSize :
-			       65535, (void*) map);
-#endif
-  DBUG_PRINT("info", ("hThread=%lu",(long) hThread));
-  *thread_id=map->pthreadself=hThread;
-  pthread_mutex_unlock(&THR_LOCK_thread);
+  par= (struct thread_start_parameter *)malloc(sizeof(*par));
+  if (!par)
+   goto error_return;
+
+  par->func= func;
+  par->arg= param;
+  stack_size= attr?attr->dwStackSize:0;
+
+  handle= _beginthreadex(NULL, stack_size , pthread_start, par, 0, thread_id);
+  if (!handle)
+    goto error_return;
+  DBUG_PRINT("info", ("thread id=%u",*thread_id));
 
-  if (hThread == (HANDLE) -1)
-  {
-    int error=errno;
-    DBUG_PRINT("error",
-	       ("Can't create thread to handle request (error %d)",error));
-    DBUG_RETURN(error ? error : -1);
-  }
-  VOID(SetThreadPriority(hThread, attr->priority)) ;
+  /* Do not need thread handle, close it */
+  CloseHandle((HANDLE)handle);
   DBUG_RETURN(0);
+
+error_return:
+  DBUG_PRINT("error",
+         ("Can't create thread to handle request (error %d)",errno));
+  DBUG_RETURN(-1);
 }
 
 
 void pthread_exit(void *a)
 {
-  _endthread();
+  _endthreadex(0);
 }
 
+int pthread_join(pthread_t thread, void **value_ptr)
+{
+  DWORD  ret;
+  HANDLE handle;
+
+  handle= OpenThread(SYNCHRONIZE, FALSE, thread);
+  if (!handle)
+  {
+    errno= EINVAL;
+    goto error_return;
+  }
+
+  ret= WaitForSingleObject(handle, INFINITE);
+
+  if(ret != WAIT_OBJECT_0)
+  {
+    errno= EINVAL;
+    goto error_return;
+  }
+
+  CloseHandle(handle);
+  return 0;
+
+error_return:
+  if(handle)
+    CloseHandle(handle);
+  return -1;
+}
 
 #endif

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2009-09-23 13:57:39 +0000
+++ b/sql/mysqld.cc	2009-09-30 15:40:12 +0000
@@ -805,7 +805,10 @@ static void set_server_version(void);
 static int init_thread_environment();
 static char *get_relative_path(const char *path);
 static int fix_paths(void);
-pthread_handler_t handle_connections_sockets(void *arg);
+void handle_connections_sockets();
+#ifdef _WIN32
+pthread_handler_t handle_connections_sockets_thread(void *arg);
+#endif
 pthread_handler_t kill_server_thread(void *arg);
 static void bootstrap(FILE *file);
 static bool read_init_file(char *file_name);
@@ -2034,29 +2037,7 @@ static BOOL WINAPI console_event_handler
 }
 
 
-/*
-  In Visual Studio 2005 and later, default SIGABRT handler will overwrite
-  any unhandled exception filter set by the application  and will try to
-  call JIT debugger. This is not what we want, this we calling __debugbreak
-  to stop in debugger, if process is being debugged or to generate 
-  EXCEPTION_BREAKPOINT and then handle_segfault will do its magic.
-*/
-
-#if (_MSC_VER >= 1400)
-static void my_sigabrt_handler(int sig)
-{
-  __debugbreak();
-}
-#endif /*_MSC_VER >=1400 */
 
-void win_install_sigabrt_handler(void)
-{
-#if (_MSC_VER >=1400)
-  /*abort() should not override our exception filter*/
-  _set_abort_behavior(0,_CALL_REPORTFAULT);
-  signal(SIGABRT,my_sigabrt_handler);
-#endif /* _MSC_VER >=1400 */
-}
 
 #ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
 #define DEBUGGER_ATTACH_TIMEOUT 120
@@ -2135,7 +2116,6 @@ LONG WINAPI my_unhandler_exception_filte
 
 static void init_signals(void)
 {
-  win_install_sigabrt_handler();
   if(opt_console)
     SetConsoleCtrlHandler(console_event_handler,TRUE);
 
@@ -4132,7 +4112,8 @@ static void create_shutdown_thread()
 #ifdef __WIN__
   hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name);
   pthread_t hThread;
-  if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0))
+  if (pthread_create(&hThread,&connection_attrib, 
+                     handle_connections_sockets_thread, 0))
     sql_print_warning("Can't create thread to handle shutdown requests");
 
   // On "Stop Service" we have to do regular shutdown
@@ -4177,7 +4158,7 @@ static void handle_connections_methods()
   {
     handler_count++;
     if (pthread_create(&hThread,&connection_attrib,
-		       handle_connections_sockets, 0))
+                       handle_connections_sockets_thread, 0))
     {
       sql_print_warning("Can't create thread to handle TCP/IP");
       handler_count--;
@@ -4506,18 +4487,11 @@ we force server id to 2, but this MySQL 
   pthread_cond_signal(&COND_server_started);
   pthread_mutex_unlock(&LOCK_server_started);
 
-#if defined(__NT__) || defined(HAVE_SMEM)
+#if defined(_WIN32) || defined(HAVE_SMEM)
   handle_connections_methods();
 #else
-#ifdef __WIN__
-  if (!have_tcpip || opt_disable_networking)
-  {
-    sql_print_error("TCP/IP unavailable or disabled with --skip-networking; no available interfaces");
-    unireg_abort(1);
-  }
-#endif
-  handle_connections_sockets(0);
-#endif /* __NT__ */
+  handle_connections_sockets();
+#endif /* _WIN32 || HAVE_SMEM */
 
   /* (void) pthread_attr_destroy(&connection_attrib); */
   
@@ -4992,7 +4966,7 @@ inline void kill_broken_server()
 	/* Handle new connections and spawn new process to handle them */
 
 #ifndef EMBEDDED_LIBRARY
-pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
+void handle_connections_sockets()
 {
   my_socket sock,new_sock;
   uint error_count=0;
@@ -5195,13 +5169,19 @@ pthread_handler_t handle_connections_soc
 
     create_new_thread(thd);
   }
+  DBUG_VOID_RETURN;
+}
+
 
+#ifdef _WIN32
+pthread_handler_t handle_connections_sockets_thread(void *arg)
+{
+  my_thread_init();
+  handle_connections_sockets();
   decrement_handler_count();
-  DBUG_RETURN(0);
+  return 0;
 }
 
-
-#ifdef __NT__
 pthread_handler_t handle_connections_namedpipes(void *arg)
 {
   HANDLE hConnectedPipe;

=== modified file 'sql/sql_connect.cc'
--- a/sql/sql_connect.cc	2009-09-10 09:18:29 +0000
+++ b/sql/sql_connect.cc	2009-09-30 15:40:12 +0000
@@ -39,10 +39,6 @@
 #define MIN_HANDSHAKE_SIZE      6
 #endif /* HAVE_OPENSSL */
 
-#ifdef __WIN__
-extern void win_install_sigabrt_handler();
-#endif
-
 /*
   Get structure for logging connection data for the current user
 */
@@ -612,13 +608,8 @@ void thd_init_client_charset(THD *thd, u
 bool init_new_connection_handler_thread()
 {
   pthread_detach_this_thread();
-#if defined(__WIN__)
-  win_install_sigabrt_handler();
-#else
-  /* Win32 calls this in pthread_create */
   if (my_thread_init())
     return 1;
-#endif /* __WIN__ */
   return 0;
 }
 

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2009-09-17 09:20:11 +0000
+++ b/sql/sql_insert.cc	2009-09-30 15:40:12 +0000
@@ -2498,7 +2498,6 @@ pthread_handler_t handle_delayed_insert(
     since it does not find one in the list.
   */
   pthread_mutex_lock(&di->mutex);
-#if !defined( __WIN__) /* Win32 calls this in pthread_create */
   if (my_thread_init())
   {
     /* Can't use my_error since store_globals has not yet been called */
@@ -2506,13 +2505,9 @@ pthread_handler_t handle_delayed_insert(
                                    ER(ER_OUT_OF_RESOURCES), NULL);
     goto end;
   }
-#endif
-
   handle_delayed_insert_impl(thd, di);
 
-#ifndef __WIN__
 end:
-#endif
   /*
     di should be unlinked from the thread handler list and have no active
     clients


Attachment: [text/bzr-bundle] bzr/vvaintroub@mysql.com-20090930154012-rah1uxrfy7rt5r5m.bundle
Thread
bzr commit into mysql-next-mr-wtf branch (vvaintroub:2884)Vladislav Vaintroub30 Sep