diff options
Diffstat (limited to '')
-rw-r--r-- | mysys/my_winthread.c | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/mysys/my_winthread.c b/mysys/my_winthread.c new file mode 100644 index 00000000..b74804fb --- /dev/null +++ b/mysys/my_winthread.c @@ -0,0 +1,179 @@ +/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 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> + +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, const pthread_attr_t *attr, + pthread_handler func, void *param) +{ + uintptr_t handle; + struct thread_start_parameter *par; + unsigned int stack_size; + int error_no; + 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, (uint *)thread_id); + if (!handle) + goto error_return; + DBUG_PRINT("info", ("thread id=%lu",*thread_id)); + + /* Do not need thread handle, close it */ + CloseHandle((HANDLE)handle); + DBUG_RETURN(0); + +error_return: + error_no= errno; + DBUG_PRINT("error", + ("Can't create thread to handle request (error %d)",error_no)); + DBUG_RETURN(error_no); +} + + +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; + } + + if (!GetExitCodeThread(handle, &ret)) + { + errno= EINVAL; + goto error_return; + } + + if (value_ptr) + *value_ptr= (void *)(size_t)ret; + + 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. +*/ + +static BOOL CALLBACK init_once_callback(my_pthread_once_t *once_control, PVOID param, PVOID *context) +{ + typedef void(*void_f)(void); + ((void_f)param)(); + return TRUE; +} + +int my_pthread_once(my_pthread_once_t *once_control, void (*func)(void)) +{ + InitOnceExecuteOnce(once_control, init_once_callback, func, NULL); + return 0; +} +#endif |