From b7dda3c35af8b371640349ad09d2ebd7ba34255c Mon Sep 17 00:00:00 2001 From: Daniel Lehman Date: Wed, 28 Oct 2015 11:41:57 -0700 Subject: [PATCH 3/3] msvcp120: implement _Thrd_create/join Signed-off-by: Daniel Lehman --- 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 | 23 +++++++++++++++++++++++ 5 files changed, 62 insertions(+), 7 deletions(-) diff --git a/dlls/msvcp110/msvcp110.spec b/dlls/msvcp110/msvcp110.spec index e3da7e9..cd91627 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 64db8b2..bbed585 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 6dea8a3..ab8be45 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*); static HMODULE msvcp; #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y) @@ -275,6 +279,10 @@ static BOOL init(void) "_Thrd_sleep"); SET(p__Thrd_current, "_Thrd_current"); + SET(p__Thrd_create, + "_Thrd_create"); + SET(p__Thrd_join, + "_Thrd_join"); msvcr = GetModuleHandleA("msvcr120.dll"); p_setlocale = (void*)GetProcAddress(msvcr, "setlocale"); @@ -1142,9 +1150,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; @@ -1205,6 +1221,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 4f1a469..4ba2720 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 5575b01..47accb1 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); @@ -730,4 +734,23 @@ _Thrd_t __cdecl _Thrd_current(void) TRACE("(%p %u)\n", ret.hnd, ret.id); return ret; } + +int __cdecl _Thrd_join(_Thrd_t thr, int *unk) +{ + DWORD ret; + + TRACE("(%p %u %p)\n", thr.hnd, thr.id, unk); + ret = WaitForSingleObject(thr.hnd, INFINITE); + if (unk) + GetExitCodeThread(thr.hnd, (DWORD *)unk); + CloseHandle(thr.hnd); + return ret == WAIT_OBJECT_0 ? 0 : _THRD_ERROR; +} + +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 -- 1.9.5