Dep/MySQL: Updated MySQL sources to version 5.5.9 (current GA)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2000 MySQL AB
|
||||
/* Copyright (C) 2000 MySQL AB, 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
|
||||
@@ -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,81 +52,101 @@ 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)
|
||||
int pthread_create(pthread_t *thread_id, const pthread_attr_t *attr,
|
||||
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);
|
||||
}
|
||||
|
||||
/* This is neaded to get the macro pthread_setspecific to work */
|
||||
|
||||
int win_pthread_setspecific(void *a,void *b,uint length)
|
||||
int pthread_join(pthread_t thread, void **value_ptr)
|
||||
{
|
||||
memcpy(a,b,length);
|
||||
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;
|
||||
}
|
||||
|
||||
int pthread_cancel(pthread_t thread)
|
||||
{
|
||||
|
||||
HANDLE handle= 0;
|
||||
BOOL ok= FALSE;
|
||||
|
||||
handle= OpenThread(THREAD_TERMINATE, FALSE, thread);
|
||||
if (handle)
|
||||
{
|
||||
ok= TerminateThread(handle,0);
|
||||
CloseHandle(handle);
|
||||
}
|
||||
if (ok)
|
||||
return 0;
|
||||
|
||||
errno= EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
One time initialization. For simplicity, we assume initializer thread
|
||||
@@ -145,8 +155,19 @@ int win_pthread_setspecific(void *a,void *b,uint length)
|
||||
int my_pthread_once(my_pthread_once_t *once_control,
|
||||
void (*init_routine)(void))
|
||||
{
|
||||
LONG state= InterlockedCompareExchange(once_control, MY_PTHREAD_ONCE_INPROGRESS,
|
||||
MY_PTHREAD_ONCE_INIT);
|
||||
LONG state;
|
||||
|
||||
/*
|
||||
Do "dirty" read to find out if initialization is already done, to
|
||||
save an interlocked operation in common case. Memory barriers are ensured by
|
||||
Visual C++ volatile implementation.
|
||||
*/
|
||||
if (*once_control == MY_PTHREAD_ONCE_DONE)
|
||||
return 0;
|
||||
|
||||
state= InterlockedCompareExchange(once_control, MY_PTHREAD_ONCE_INPROGRESS,
|
||||
MY_PTHREAD_ONCE_INIT);
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case MY_PTHREAD_ONCE_INIT:
|
||||
@@ -168,5 +189,4 @@ int my_pthread_once(my_pthread_once_t *once_control,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user