[PATCH] msvcrt: handle of thread created by _beginthread should not be closed on thread detach.
Paul Gofman
gofmanp at gmail.com
Sat Jan 30 19:08:19 CST 2016
Handle should be closed if _endthread is called or thread function exits. If thread is terminated
by ExitThread, thread handle remains valid.
Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
dlls/msvcrt/main.c | 1 -
dlls/msvcrt/tests/misc.c | 37 +++++++++++++++++++++++++++++++++++++
dlls/msvcrt/thread.c | 13 +++++++++++++
3 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/dlls/msvcrt/main.c b/dlls/msvcrt/main.c
index 6973dca..a930a32 100644
--- a/dlls/msvcrt/main.c
+++ b/dlls/msvcrt/main.c
@@ -67,7 +67,6 @@ static inline void msvcrt_free_tls_mem(void)
if (tls)
{
- CloseHandle(tls->handle);
MSVCRT_free(tls->efcvt_buffer);
MSVCRT_free(tls->asctime_buffer);
MSVCRT_free(tls->wasctime_buffer);
diff --git a/dlls/msvcrt/tests/misc.c b/dlls/msvcrt/tests/misc.c
index c568361..44bd676 100644
--- a/dlls/msvcrt/tests/misc.c
+++ b/dlls/msvcrt/tests/misc.c
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <math.h>
#include "msvcrt.h"
+#include <process.h>
static inline float __port_infinity(void)
{
@@ -540,6 +541,41 @@ static void test_math_functions(void)
ok(errno == 0xdeadbeef, "errno = %d\n", errno);
}
+static void __cdecl test_thread_func(void *end_thread_type)
+{
+ if (end_thread_type == (void*)1)
+ _endthread();
+ else if (end_thread_type == (void*)2)
+ ExitThread(0);
+}
+
+static void test_thread_handle_close(void)
+{
+ HANDLE hThread;
+ DWORD ret;
+
+ hThread = (HANDLE)_beginthread(test_thread_func, 0, (void*)0);
+ Sleep(200);
+ ret = WaitForSingleObject(hThread, INFINITE);
+ ok(ret == WAIT_FAILED, "ret = %d\n", ret);
+ ret = CloseHandle(hThread);
+ ok(!ret, "ret = %d\n", ret);
+
+ hThread = (HANDLE)_beginthread(test_thread_func, 0, (void*)1);
+ Sleep(200);
+ ret = WaitForSingleObject(hThread, INFINITE);
+ ok(ret == WAIT_FAILED, "ret = %d\n", ret);
+ ret = CloseHandle(hThread);
+ ok(!ret, "ret = %d\n", ret);
+
+ hThread = (HANDLE)_beginthread(test_thread_func, 0, (void*)2);
+ Sleep(200);
+ ret = WaitForSingleObject(hThread, INFINITE);
+ ok(ret == WAIT_OBJECT_0, "ret = %d\n", ret);
+ ret = CloseHandle(hThread);
+ ok(ret, "ret = %d\n", ret);
+}
+
START_TEST(misc)
{
int arg_c;
@@ -568,4 +604,5 @@ START_TEST(misc)
test__invalid_parameter();
test_qsort_s();
test_math_functions();
+ test_thread_handle_close();
}
diff --git a/dlls/msvcrt/thread.c b/dlls/msvcrt/thread.c
index 5e62354..1f01fc5 100644
--- a/dlls/msvcrt/thread.c
+++ b/dlls/msvcrt/thread.c
@@ -69,6 +69,9 @@ static DWORD CALLBACK _beginthread_trampoline(LPVOID arg)
MSVCRT_free(arg);
local_trampoline.start_address(local_trampoline.arglist);
+
+ CloseHandle(data->handle);
+ data->handle = NULL;
return 0;
}
@@ -136,8 +139,18 @@ MSVCRT_uintptr_t CDECL _beginthreadex(
*/
void CDECL _endthread(void)
{
+ thread_data_t *tls;
+
TRACE("(void)\n");
+ tls = TlsGetValue(msvcrt_tls_index);
+ if (tls && tls->handle)
+ {
+ CloseHandle(tls->handle);
+ tls->handle = NULL;
+ } else
+ ERR("tls=%p tls->handle=%#x\n", tls, tls->handle);
+
/* FIXME */
ExitThread(0);
}
--
2.5.0
More information about the wine-patches
mailing list