mariadb/mysys/my_winthread.c
Vladislav Vaintroub 14c2cfb568 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()
2009-09-30 17:40:12 +02:00

132 lines
3 KiB
C

/* Copyright (C) 2000 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*****************************************************************************
** 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"
#include <process.h>
#include <signal.h>
static void install_sigabrt_handler(void);
struct thread_start_parameter
{
pthread_handler func;
void *arg;
};
/**
Adapter to @c pthread_mutex_trylock()
@retval 0 Mutex was acquired
@retval EBUSY Mutex was already locked by a thread
*/
int
win_pthread_mutex_trylock(pthread_mutex_t *mutex)
{
if (TryEnterCriticalSection(mutex))
{
/* Don't allow recursive lock */
if (mutex->RecursionCount > 1){
LeaveCriticalSection(mutex);
return EBUSY;
}
return 0;
}
return EBUSY;
}
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)
{
uintptr_t handle;
struct thread_start_parameter *par;
unsigned int stack_size;
DBUG_ENTER("pthread_create");
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));
/* 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)
{
_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