msvcp120: Implement _Thrd_create/join.

Signed-off-by: Daniel Lehman <dlehman@esri.com>
Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Daniel Lehman 2015-10-28 11:41:57 -07:00 committed by Alexandre Julliard
parent 498d8861e0
commit f3a0ac8d53
5 changed files with 63 additions and 7 deletions

View File

@ -3856,12 +3856,12 @@
@ cdecl _Strcoll(ptr ptr ptr ptr ptr) @ cdecl _Strcoll(ptr ptr ptr ptr ptr)
@ stub _Strxfrm @ stub _Strxfrm
@ stub _Thrd_abort @ stub _Thrd_abort
@ stub _Thrd_create @ cdecl _Thrd_create(ptr ptr ptr)
@ cdecl _Thrd_current() @ cdecl _Thrd_current()
@ stub _Thrd_detach @ stub _Thrd_detach
@ cdecl _Thrd_equal(ptr ptr) @ cdecl _Thrd_equal(ptr ptr)
@ stub _Thrd_exit @ stub _Thrd_exit
@ stub _Thrd_join @ cdecl _Thrd_join(ptr long)
@ cdecl _Thrd_lt(ptr ptr) @ cdecl _Thrd_lt(ptr ptr)
@ cdecl _Thrd_sleep(ptr) @ cdecl _Thrd_sleep(ptr)
@ stub _Thrd_start @ stub _Thrd_start

View File

@ -3803,12 +3803,12 @@
@ cdecl _Strcoll(ptr ptr ptr ptr ptr) @ cdecl _Strcoll(ptr ptr ptr ptr ptr)
@ stub _Strxfrm @ stub _Strxfrm
@ stub _Thrd_abort @ stub _Thrd_abort
@ stub _Thrd_create @ cdecl _Thrd_create(ptr ptr ptr)
@ cdecl _Thrd_current() @ cdecl _Thrd_current()
@ stub _Thrd_detach @ stub _Thrd_detach
@ cdecl _Thrd_equal(ptr ptr) @ cdecl _Thrd_equal(ptr ptr)
@ stub _Thrd_exit @ stub _Thrd_exit
@ stub _Thrd_join @ cdecl _Thrd_join(ptr long)
@ cdecl _Thrd_lt(ptr ptr) @ cdecl _Thrd_lt(ptr ptr)
@ cdecl _Thrd_sleep(ptr) @ cdecl _Thrd_sleep(ptr)
@ stub _Thrd_start @ stub _Thrd_start

View File

@ -139,10 +139,14 @@ typedef struct
#define TIMEDELTA 150 /* 150 ms uncertainty allowed */ #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_equal)(_Thrd_t, _Thrd_t);
static int (__cdecl *p__Thrd_lt)(_Thrd_t, _Thrd_t); static int (__cdecl *p__Thrd_lt)(_Thrd_t, _Thrd_t);
static void (__cdecl *p__Thrd_sleep)(const xtime*); static void (__cdecl *p__Thrd_sleep)(const xtime*);
static _Thrd_t (__cdecl *p__Thrd_current)(void); 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__ #ifdef __i386__
static ULONGLONG (__cdecl *p_i386_Thrd_current)(void); static ULONGLONG (__cdecl *p_i386_Thrd_current)(void);
@ -296,6 +300,10 @@ static BOOL init(void)
"_Thrd_lt"); "_Thrd_lt");
SET(p__Thrd_sleep, SET(p__Thrd_sleep,
"_Thrd_sleep"); "_Thrd_sleep");
SET(p__Thrd_create,
"_Thrd_create");
SET(p__Thrd_join,
"_Thrd_join");
msvcr = GetModuleHandleA("msvcr120.dll"); msvcr = GetModuleHandleA("msvcr120.dll");
p_setlocale = (void*)GetProcAddress(msvcr, "setlocale"); 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); 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) static void test_thrd(void)
{ {
int ret, i; int ret, i, r;
struct test { struct test {
_Thrd_t a; _Thrd_t a;
_Thrd_t b; _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(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(ta.hnd), "handle %p not closed\n", ta.hnd);
ok(!CloseHandle(tb.hnd), "handle %p not closed\n", tb.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) START_TEST(msvcp120)

View File

@ -3803,12 +3803,12 @@
@ cdecl _Strcoll(ptr ptr ptr ptr ptr) msvcp120._Strcoll @ cdecl _Strcoll(ptr ptr ptr ptr ptr) msvcp120._Strcoll
@ stub _Strxfrm @ stub _Strxfrm
@ stub _Thrd_abort @ stub _Thrd_abort
@ stub _Thrd_create @ cdecl _Thrd_create(ptr ptr ptr) msvcp120._Thrd_create
@ cdecl _Thrd_current() msvcp120._Thrd_current @ cdecl _Thrd_current() msvcp120._Thrd_current
@ stub _Thrd_detach @ stub _Thrd_detach
@ cdecl _Thrd_equal(ptr ptr) msvcp120._Thrd_equal @ cdecl _Thrd_equal(ptr ptr) msvcp120._Thrd_equal
@ stub _Thrd_exit @ stub _Thrd_exit
@ stub _Thrd_join @ cdecl _Thrd_join(ptr long) msvcp120._Thrd_join
@ cdecl _Thrd_lt(ptr ptr) msvcp120._Thrd_lt @ cdecl _Thrd_lt(ptr ptr) msvcp120._Thrd_lt
@ cdecl _Thrd_sleep(ptr) msvcp120._Thrd_sleep @ cdecl _Thrd_sleep(ptr) msvcp120._Thrd_sleep
@ stub _Thrd_start @ stub _Thrd_start

View File

@ -691,6 +691,10 @@ typedef struct
DWORD id; DWORD id;
} _Thrd_t; } _Thrd_t;
typedef int (__cdecl *_Thrd_start_t)(void*);
#define _THRD_ERROR 4
int __cdecl _Thrd_equal(_Thrd_t a, _Thrd_t b) int __cdecl _Thrd_equal(_Thrd_t a, _Thrd_t b)
{ {
TRACE("(%p %u %p %u)\n", a.hnd, a.id, b.hnd, b.id); 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; return ret.ull;
} }
#endif #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 #endif