Piotr Caban : msvcrt: Close thread handle when _beginthread is used.
Alexandre Julliard
julliard at winehq.org
Wed May 25 11:28:12 CDT 2011
Module: wine
Branch: master
Commit: 2bcc9d452a19f2d11ec4b3e655a3c4456b02cc96
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2bcc9d452a19f2d11ec4b3e655a3c4456b02cc96
Author: Piotr Caban <piotr at codeweavers.com>
Date: Tue May 24 17:22:02 2011 +0200
msvcrt: Close thread handle when _beginthread is used.
---
dlls/msvcrt/main.c | 1 +
dlls/msvcrt/msvcrt.h | 2 +
dlls/msvcrt/thread.c | 59 ++++++++++++++++++++++++++++++++++---------------
3 files changed, 44 insertions(+), 18 deletions(-)
diff --git a/dlls/msvcrt/main.c b/dlls/msvcrt/main.c
index cca6189..f1ef67b 100644
--- a/dlls/msvcrt/main.c
+++ b/dlls/msvcrt/main.c
@@ -66,6 +66,7 @@ static inline void msvcrt_free_tls_mem(void)
thread_data_t *tls = TlsGetValue(msvcrt_tls_index);
if (tls)
{
+ CloseHandle(tls->handle);
HeapFree(GetProcessHeap(),0,tls->efcvt_buffer);
HeapFree(GetProcessHeap(),0,tls->asctime_buffer);
HeapFree(GetProcessHeap(),0,tls->wasctime_buffer);
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h
index 31fe719..8fc3b03 100644
--- a/dlls/msvcrt/msvcrt.h
+++ b/dlls/msvcrt/msvcrt.h
@@ -107,6 +107,8 @@ struct MSVCRT_tm {
extern DWORD msvcrt_tls_index;
struct __thread_data {
+ DWORD tid;
+ HANDLE handle;
int thread_errno;
MSVCRT_ulong thread_doserrno;
unsigned int random_seed; /* seed for rand() */
diff --git a/dlls/msvcrt/thread.c b/dlls/msvcrt/thread.c
index dc6edcd..2afb183 100644
--- a/dlls/msvcrt/thread.c
+++ b/dlls/msvcrt/thread.c
@@ -25,6 +25,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
/********************************************************************/
typedef struct {
+ HANDLE is_ready, thread;
MSVCRT__beginthread_start_routine_t start_address;
void *arglist;
} _beginthread_trampoline_t;
@@ -44,6 +45,8 @@ thread_data_t *msvcrt_get_thread_data(void)
if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) )))
_amsg_exit( _RT_THREAD );
if (!TlsSetValue( msvcrt_tls_index, ptr )) _amsg_exit( _RT_THREAD );
+ ptr->tid = GetCurrentThreadId();
+ ptr->handle = INVALID_HANDLE_VALUE;
ptr->random_seed = 1;
}
SetLastError( err );
@@ -56,13 +59,19 @@ thread_data_t *msvcrt_get_thread_data(void)
*/
static DWORD CALLBACK _beginthread_trampoline(LPVOID arg)
{
- _beginthread_trampoline_t local_trampoline;
+ _beginthread_trampoline_t local_trampoline, *trampoline = arg;
+ thread_data_t *data = msvcrt_get_thread_data();
+
+ if(!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(),
+ &trampoline->thread, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
+ trampoline->thread = NULL;
+ SetEvent(&trampoline->is_ready);
+ return 0;
+ }
- /* Maybe it's just being paranoid, but freeing arg right
- * away seems safer.
- */
- memcpy(&local_trampoline,arg,sizeof(local_trampoline));
- MSVCRT_free(arg);
+ memcpy(&local_trampoline, trampoline, sizeof(local_trampoline));
+ data->handle = local_trampoline.thread;
+ SetEvent(trampoline->is_ready);
local_trampoline.start_address(local_trampoline.arglist);
return 0;
@@ -76,21 +85,35 @@ MSVCRT_uintptr_t CDECL _beginthread(
unsigned int stack_size, /* [in] Stack size for new thread or 0 */
void *arglist) /* [in] Argument list to be passed to new thread or NULL */
{
- _beginthread_trampoline_t* trampoline;
+ _beginthread_trampoline_t trampoline;
+ HANDLE thread;
TRACE("(%p, %d, %p)\n", start_address, stack_size, arglist);
- /* Allocate the trampoline here so that it is still valid when the thread
- * starts... typically after this function has returned.
- * _beginthread_trampoline is responsible for freeing the trampoline
- */
- trampoline=MSVCRT_malloc(sizeof(*trampoline));
- trampoline->start_address = start_address;
- trampoline->arglist = arglist;
-
- /* FIXME */
- return (MSVCRT_uintptr_t)CreateThread(NULL, stack_size, _beginthread_trampoline,
- trampoline, 0, NULL);
+ trampoline.is_ready = CreateEventW(NULL, FALSE, FALSE, NULL);
+ if(!trampoline.is_ready) {
+ *MSVCRT__errno() = MSVCRT_EAGAIN;
+ return -1;
+ }
+ trampoline.start_address = start_address;
+ trampoline.arglist = arglist;
+
+ thread = CreateThread(NULL, stack_size, _beginthread_trampoline,
+ &trampoline, 0, NULL);
+ if(!thread) {
+ *MSVCRT__errno() = MSVCRT_EAGAIN;
+ return -1;
+ }
+ CloseHandle(thread);
+
+ WaitForSingleObject(trampoline.is_ready, INFINITE);
+ CloseHandle(trampoline.is_ready);
+
+ if(!trampoline.thread) {
+ *MSVCRT__errno() = MSVCRT_EAGAIN;
+ return -1;
+ }
+ return (MSVCRT_uintptr_t)trampoline.thread;
}
/*********************************************************************
More information about the wine-cvs
mailing list