diff --git a/dlls/msvcp110/msvcp110.spec b/dlls/msvcp110/msvcp110.spec index d2275109c0b..96ad84c52f8 100644 --- a/dlls/msvcp110/msvcp110.spec +++ b/dlls/msvcp110/msvcp110.spec @@ -3857,7 +3857,7 @@ @ stub _Strxfrm @ stub _Thrd_abort @ stub _Thrd_create -@ stub _Thrd_current +@ cdecl _Thrd_current() @ stub _Thrd_detach @ cdecl _Thrd_equal(ptr ptr) @ stub _Thrd_exit diff --git a/dlls/msvcp120/msvcp120.spec b/dlls/msvcp120/msvcp120.spec index f3161144cac..32be6ea2f0d 100644 --- a/dlls/msvcp120/msvcp120.spec +++ b/dlls/msvcp120/msvcp120.spec @@ -3804,7 +3804,7 @@ @ stub _Strxfrm @ stub _Thrd_abort @ stub _Thrd_create -@ stub _Thrd_current +@ cdecl _Thrd_current() @ stub _Thrd_detach @ cdecl _Thrd_equal(ptr ptr) @ stub _Thrd_exit diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c index 6cf8053a3db..db140435326 100644 --- a/dlls/msvcp120/tests/msvcp120.c +++ b/dlls/msvcp120/tests/msvcp120.c @@ -142,6 +142,20 @@ typedef struct 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); + +#ifdef __i386__ +static ULONGLONG (__cdecl *p_i386_Thrd_current)(void); +_Thrd_t __cdecl i386_Thrd_current(void) +{ + union { + _Thrd_t thr; + ULONGLONG ull; + } r; + r.ull = p_i386_Thrd_current(); + return r.thr; +} +#endif static HMODULE msvcp; #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y) @@ -220,6 +234,8 @@ static BOOL init(void) "?_Last_write_time@sys@tr2@std@@YA_JPEBD@Z"); SET(p_tr2_sys__Last_write_time_set, "?_Last_write_time@sys@tr2@std@@YAXPEBD_J@Z"); + SET(p__Thrd_current, + "_Thrd_current"); } else { SET(p_tr2_sys__File_size, "?_File_size@sys@tr2@std@@YA_KPBD@Z"); @@ -265,6 +281,14 @@ static BOOL init(void) "?_Last_write_time@sys@tr2@std@@YA_JPBD@Z"); SET(p_tr2_sys__Last_write_time_set, "?_Last_write_time@sys@tr2@std@@YAXPBD_J@Z"); +#ifdef __i386__ + SET(p_i386_Thrd_current, + "_Thrd_current"); + p__Thrd_current = i386_Thrd_current; +#else + SET(p__Thrd_current, + "_Thrd_current"); +#endif } SET(p__Thrd_equal, "_Thrd_equal"); @@ -1151,6 +1175,7 @@ static void test_thrd(void) const HANDLE hnd2 = (HANDLE)0xdeadbeef; xtime xt, before, after; MSVCRT_long diff; + _Thrd_t ta, tb; struct test testeq[] = { { {0, 0}, {0, 0}, 1 }, @@ -1191,6 +1216,16 @@ static void test_thrd(void) p_xtime_get(&after, 1); diff = p__Xtime_diff_to_millis2(&after, &before); ok(diff > 2000 - TIMEDELTA, "got %d\n", diff); + + /* test for current */ + ta = p__Thrd_current(); + tb = p__Thrd_current(); + ok(ta.id == tb.id, "got a %d b %d\n", ta.id, tb.id); + ok(ta.id == GetCurrentThreadId(), "expected %d, got %d\n", GetCurrentThreadId(), ta.id); + /* these can be different if new threads are created at same time */ + 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); } START_TEST(msvcp120) diff --git a/dlls/msvcp120_app/msvcp120_app.spec b/dlls/msvcp120_app/msvcp120_app.spec index b5d423bd374..fc77cfe2b22 100644 --- a/dlls/msvcp120_app/msvcp120_app.spec +++ b/dlls/msvcp120_app/msvcp120_app.spec @@ -3804,7 +3804,7 @@ @ stub _Strxfrm @ stub _Thrd_abort @ stub _Thrd_create -@ stub _Thrd_current +@ cdecl _Thrd_current() msvcp120._Thrd_current @ stub _Thrd_detach @ cdecl _Thrd_equal(ptr ptr) msvcp120._Thrd_equal @ stub _Thrd_exit diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c index ccf1d047260..4bcc716333d 100644 --- a/dlls/msvcp90/misc.c +++ b/dlls/msvcp90/misc.c @@ -714,4 +714,40 @@ void __cdecl _Thrd_yield(void) TRACE("()\n"); Sleep(0); } + +static _Thrd_t thread_current(void) +{ + _Thrd_t ret; + + if(DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), + GetCurrentProcess(), &ret.hnd, 0, FALSE, DUPLICATE_SAME_ACCESS)) { + CloseHandle(ret.hnd); + } else { + ret.hnd = 0; + } + ret.id = GetCurrentThreadId(); + + TRACE("(%p %u)\n", ret.hnd, ret.id); + return ret; +} + +#ifndef __i386__ +_Thrd_t __cdecl _Thrd_current(void) +{ + return thread_current(); +} +#else +ULONGLONG __cdecl _Thrd_current(void) +{ + union { + _Thrd_t thr; + ULONGLONG ull; + } ret; + + C_ASSERT(sizeof(_Thrd_t) <= sizeof(ULONGLONG)); + + ret.thr = thread_current(); + return ret.ull; +} +#endif #endif