summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <vvaintroub@mysql.com>2009-09-30 17:40:12 +0200
committerVladislav Vaintroub <vvaintroub@mysql.com>2009-09-30 17:40:12 +0200
commit9cf8d12c855e9713c5d3a170249c7d67935b2209 (patch)
treed211859561c812cd30d4143ce8099b8dc9cbaedf
parent28015993235d3a1a56f08de5b86c4e1ef59d4723 (diff)
downloadmariadb-git-9cf8d12c855e9713c5d3a170249c7d67935b2209.tar.gz
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()
-rw-r--r--include/config-win.h3
-rw-r--r--include/my_pthread.h12
-rw-r--r--libmysqld/CMakeLists.txt2
-rw-r--r--mysys/my_thr_init.c43
-rw-r--r--mysys/my_wincond.c3
-rw-r--r--mysys/my_winthread.c131
-rw-r--r--sql/mysqld.cc60
-rw-r--r--sql/sql_connect.cc9
-rw-r--r--sql/sql_insert.cc5
9 files changed, 130 insertions, 138 deletions
diff --git a/include/config-win.h b/include/config-win.h
index bcad4e04346..514a762d6d8 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -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
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 2928cb60c2d..b4fe1203d2b 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -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 *connect_att);
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 #define pthread_exit(A) ExitThread(A)*/
#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)
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
index 6e1ad17b808..bce14b38338 100644
--- a/libmysqld/CMakeLists.txt
+++ b/libmysqld/CMakeLists.txt
@@ -130,7 +130,7 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../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})
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 2c346145cf5..c59b2d51742 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -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 */
diff --git a/mysys/my_wincond.c b/mysys/my_wincond.c
index d1b07b61408..956d29a970b 100644
--- a/mysys/my_wincond.c
+++ b/mysys/my_wincond.c
@@ -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>
diff --git a/mysys/my_winthread.c b/mysys/my_winthread.c
index 543e1787fb6..9e8458b0799 100644
--- a/mysys/my_winthread.c
+++ b/mysys/my_winthread.c
@@ -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_t *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)
+static unsigned int __stdcall pthread_start(void *p)
{
- 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 */
+ 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;
- 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)) ;
+ 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));
+
+ /* 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
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index bb79f931fb3..3585539318d 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -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( DWORD type )
}
-/*
- 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_filter(EXCEPTION_POINTERS *ex_pointers)
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 server will not act as a slave.");
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_sockets(void *arg __attribute__((unused)))
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;
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 404d734559f..a87d201d9ed 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -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, uint cs_number)
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;
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 7d2513bd419..1ef4d5827ec 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -2498,7 +2498,6 @@ pthread_handler_t handle_delayed_insert(void *arg)
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(void *arg)
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