From f3a0ac8d53813e5d44b8ab3a9b38b894f20309fe Mon Sep 17 00:00:00 2001 From: Daniel Lehman Date: Wed, 28 Oct 2015 11:41:57 -0700 Subject: [PATCH] msvcp120: Implement _Thrd_create/join. Signed-off-by: Daniel Lehman Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard --- dlls/msvcp110/msvcp110.spec | 4 ++-- dlls/msvcp120/msvcp120.spec | 4 ++-- dlls/msvcp120/tests/msvcp120.c | 34 ++++++++++++++++++++++++++++- dlls/msvcp120_app/msvcp120_app.spec | 4 ++-- dlls/msvcp90/misc.c | 24 ++++++++++++++++++++ 5 files changed, 63 insertions(+), 7 deletions(-) diff --git a/dlls/msvcp110/msvcp110.spec b/dlls/msvcp110/msvcp110.spec index 96ad84c52f8..a739dd4c88b 100644 --- a/dlls/msvcp110/msvcp110.spec +++ b/dlls/msvcp110/msvcp110.spec @@ -3856,12 +3856,12 @@ @ cdecl _Strcoll(ptr ptr ptr ptr ptr) @ stub _Strxfrm @ stub _Thrd_abort -@ stub _Thrd_create +@ cdecl _Thrd_create(ptr ptr ptr) @ cdecl _Thrd_current() @ stub _Thrd_detach @ cdecl _Thrd_equal(ptr ptr) @ stub _Thrd_exit -@ stub _Thrd_join +@ cdecl _Thrd_join(ptr long) @ cdecl _Thrd_lt(ptr ptr) @ cdecl _Thrd_sleep(ptr) @ stub _Thrd_start diff --git a/dlls/msvcp120/msvcp120.spec b/dlls/msvcp120/msvcp120.spec index 32be6ea2f0d..e24268d9985 100644 --- a/dlls/msvcp120/msvcp120.spec +++ b/dlls/msvcp120/msvcp120.spec @@ -3803,12 +3803,12 @@ @ cdecl _Strcoll(ptr ptr ptr ptr ptr) @ stub _Strxfrm @ stub _Thrd_abort -@ stub _Thrd_create +@ cdecl _Thrd_create(ptr ptr ptr) @ cdecl _Thrd_current() @ stub _Thrd_detach @ cdecl _Thrd_equal(ptr ptr) @ stub _Thrd_exit -@ stub _Thrd_join +@ cdecl _Thrd_join(ptr long) @ cdecl _Thrd_lt(ptr ptr) @ cdecl _Thrd_sleep(ptr) @ stub _Thrd_start diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c index db140435326..3f02051cb67 100644 --- a/dlls/msvcp120/tests/msvcp120.c +++ b/dlls/msvcp120/tests/msvcp120.c @@ -139,10 +139,14 @@ typedef struct #define TIMEDELTA 150 /* 150 ms uncertainty allowed */ +typedef int (__cdecl *_Thrd_start_t)(void*); + static int (__cdecl *p__Thrd_equal)(_Thrd_t, _Thrd_t); static int (__cdecl *p__Thrd_lt)(_Thrd_t, _Thrd_t); static void (__cdecl *p__Thrd_sleep)(const xtime*); static _Thrd_t (__cdecl *p__Thrd_current)(void); +static int (__cdecl *p__Thrd_create)(_Thrd_t*, _Thrd_start_t, void*); +static int (__cdecl *p__Thrd_join)(_Thrd_t, int*); #ifdef __i386__ static ULONGLONG (__cdecl *p_i386_Thrd_current)(void); @@ -296,6 +300,10 @@ static BOOL init(void) "_Thrd_lt"); SET(p__Thrd_sleep, "_Thrd_sleep"); + SET(p__Thrd_create, + "_Thrd_create"); + SET(p__Thrd_join, + "_Thrd_join"); msvcr = GetModuleHandleA("msvcr120.dll"); p_setlocale = (void*)GetProcAddress(msvcr, "setlocale"); @@ -1163,9 +1171,17 @@ static void test_tr2_sys__Last_write_time(void) ok(ret == 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret); } +static int __cdecl thrd_thread(void *arg) +{ + _Thrd_t *thr = arg; + + *thr = p__Thrd_current(); + return 0x42; +} + static void test_thrd(void) { - int ret, i; + int ret, i, r; struct test { _Thrd_t a; _Thrd_t b; @@ -1226,6 +1242,22 @@ static void test_thrd(void) ok(ta.hnd == tb.hnd, "got a %p b %p\n", ta.hnd, tb.hnd); ok(!CloseHandle(ta.hnd), "handle %p not closed\n", ta.hnd); ok(!CloseHandle(tb.hnd), "handle %p not closed\n", tb.hnd); + + /* test for create/join */ + if (0) /* crash on Windows */ + { + p__Thrd_create(NULL, thrd_thread, NULL); + p__Thrd_create(&ta, NULL, NULL); + } + r = -1; + ret = p__Thrd_create(&ta, thrd_thread, (void*)&tb); + ok(!ret, "failed to create thread, got %d\n", ret); + ret = p__Thrd_join(ta, &r); + ok(!ret, "failed to join thread, got %d\n", ret); + ok(ta.id == tb.id, "expected %d, got %d\n", ta.id, tb.id); + ok(ta.hnd != tb.hnd, "same handles, got %p\n", ta.hnd); + ok(r == 0x42, "expected 0x42, got %d\n", r); + ok(!CloseHandle(ta.hnd), "handle %p not closed\n", ta.hnd); } START_TEST(msvcp120) diff --git a/dlls/msvcp120_app/msvcp120_app.spec b/dlls/msvcp120_app/msvcp120_app.spec index fc77cfe2b22..d0debd18b64 100644 --- a/dlls/msvcp120_app/msvcp120_app.spec +++ b/dlls/msvcp120_app/msvcp120_app.spec @@ -3803,12 +3803,12 @@ @ cdecl _Strcoll(ptr ptr ptr ptr ptr) msvcp120._Strcoll @ stub _Strxfrm @ stub _Thrd_abort -@ stub _Thrd_create +@ cdecl _Thrd_create(ptr ptr ptr) msvcp120._Thrd_create @ cdecl _Thrd_current() msvcp120._Thrd_current @ stub _Thrd_detach @ cdecl _Thrd_equal(ptr ptr) msvcp120._Thrd_equal @ stub _Thrd_exit -@ stub _Thrd_join +@ cdecl _Thrd_join(ptr long) msvcp120._Thrd_join @ cdecl _Thrd_lt(ptr ptr) msvcp120._Thrd_lt @ cdecl _Thrd_sleep(ptr) msvcp120._Thrd_sleep @ stub _Thrd_start diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c index 4bcc716333d..25b3f23cb11 100644 --- a/dlls/msvcp90/misc.c +++ b/dlls/msvcp90/misc.c @@ -691,6 +691,10 @@ typedef struct DWORD id; } _Thrd_t; +typedef int (__cdecl *_Thrd_start_t)(void*); + +#define _THRD_ERROR 4 + int __cdecl _Thrd_equal(_Thrd_t a, _Thrd_t b) { TRACE("(%p %u %p %u)\n", a.hnd, a.id, b.hnd, b.id); @@ -750,4 +754,24 @@ ULONGLONG __cdecl _Thrd_current(void) return ret.ull; } #endif + +int __cdecl _Thrd_join(_Thrd_t thr, int *code) +{ + TRACE("(%p %u %p)\n", thr.hnd, thr.id, code); + if (WaitForSingleObject(thr.hnd, INFINITE)) + return _THRD_ERROR; + + if (code) + GetExitCodeThread(thr.hnd, (DWORD *)code); + + CloseHandle(thr.hnd); + return 0; +} + +int __cdecl _Thrd_create(_Thrd_t *thr, _Thrd_start_t proc, void *arg) +{ + TRACE("(%p %p %p)\n", thr, proc, arg); + thr->hnd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)proc, arg, 0, &thr->id); + return !thr->hnd; +} #endif