summaryrefslogtreecommitdiff
path: root/mysys/my_winthread.c
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
commit14c2cfb568e081ef66e4b6aadfc9611dd0f4be88 (patch)
treed211859561c812cd30d4143ce8099b8dc9cbaedf /mysys/my_winthread.c
parenteaba74fee5611369c02e50eb6da707f8f29cf302 (diff)
downloadmariadb-git-14c2cfb568e081ef66e4b6aadfc9611dd0f4be88.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()
Diffstat (limited to 'mysys/my_winthread.c')
-rw-r--r--mysys/my_winthread.c131
1 files changed, 65 insertions, 66 deletions
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