mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 09:15:11 +00:00
msvcp120: Added _Call_once implementation.
This commit is contained in:
parent
6bb558034c
commit
a7a3cd84b5
|
@ -3727,8 +3727,8 @@
|
|||
@ cdecl -ret64 -arch=arm ?xsputn@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@MAA_JPB_W_J@Z(ptr wstr int64) basic_streambuf_wchar_xsputn
|
||||
@ thiscall -ret64 -arch=i386 ?xsputn@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@MAE_JPB_W_J@Z(ptr wstr int64) basic_streambuf_wchar_xsputn
|
||||
@ cdecl -arch=win64 ?xsputn@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@MEAA_JPEB_W_J@Z(ptr ptr long) basic_streambuf_wchar_xsputn
|
||||
@ stub _Call_once
|
||||
@ stub _Call_onceEx
|
||||
@ cdecl _Call_once(ptr ptr)
|
||||
@ cdecl _Call_onceEx(ptr ptr ptr)
|
||||
@ stub _Cnd_broadcast
|
||||
@ stub _Cnd_destroy
|
||||
@ stub _Cnd_do_broadcast_at_thread_exit
|
||||
|
|
|
@ -3668,8 +3668,8 @@
|
|||
@ cdecl -ret64 -arch=arm ?xsputn@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@MAA_JPB_W_J@Z(ptr wstr int64) basic_streambuf_wchar_xsputn
|
||||
@ thiscall -ret64 -arch=i386 ?xsputn@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@MAE_JPB_W_J@Z(ptr wstr int64) basic_streambuf_wchar_xsputn
|
||||
@ cdecl -arch=win64 ?xsputn@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@MEAA_JPEB_W_J@Z(ptr ptr long) basic_streambuf_wchar_xsputn
|
||||
@ stub _Call_once
|
||||
@ stub _Call_onceEx
|
||||
@ cdecl _Call_once(ptr ptr)
|
||||
@ cdecl _Call_onceEx(ptr ptr ptr)
|
||||
@ stub _Cnd_broadcast
|
||||
@ stub _Cnd_destroy
|
||||
@ stub _Cnd_do_broadcast_at_thread_exit
|
||||
|
|
|
@ -43,6 +43,8 @@ static int (__cdecl *p_isleadbyte)(int);
|
|||
static MSVCRT_long (__cdecl *p__Xtime_diff_to_millis2)(const xtime*, const xtime*);
|
||||
static int (__cdecl *p_xtime_get)(xtime*, int);
|
||||
static _Cvtvec* (__cdecl *p__Getcvt)(_Cvtvec*);
|
||||
static void (CDECL *p__Call_once)(int *once, void (CDECL *func)(void));
|
||||
static void (CDECL *p__Call_onceEx)(int *once, void (CDECL *func)(void*), void *argv);
|
||||
|
||||
static HMODULE msvcp;
|
||||
|
||||
|
@ -60,6 +62,8 @@ static BOOL init(void)
|
|||
p__Xtime_diff_to_millis2 = (void*)GetProcAddress(msvcp, "_Xtime_diff_to_millis2");
|
||||
p_xtime_get = (void*)GetProcAddress(msvcp, "xtime_get");
|
||||
p__Getcvt = (void*)GetProcAddress(msvcp, "_Getcvt");
|
||||
p__Call_once = (void*)GetProcAddress(msvcp, "_Call_once");
|
||||
p__Call_onceEx = (void*)GetProcAddress(msvcp, "_Call_onceEx");
|
||||
|
||||
msvcr = GetModuleHandleA("msvcr120.dll");
|
||||
p_setlocale = (void*)GetProcAddress(msvcr, "setlocale");
|
||||
|
@ -190,12 +194,63 @@ static void test__Getcvt(void)
|
|||
}
|
||||
}
|
||||
|
||||
static int cnt;
|
||||
static int once;
|
||||
|
||||
static void __cdecl call_once_func(void)
|
||||
{
|
||||
ok(!once, "once != 0\n");
|
||||
cnt += 0x10000;
|
||||
}
|
||||
|
||||
static void __cdecl call_once_ex_func(void *arg)
|
||||
{
|
||||
int *i = arg;
|
||||
|
||||
ok(!once, "once != 0\n");
|
||||
(*i)++;
|
||||
}
|
||||
|
||||
DWORD WINAPI call_once_thread(void *arg)
|
||||
{
|
||||
p__Call_once(&once, call_once_func);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD WINAPI call_once_ex_thread(void *arg)
|
||||
{
|
||||
p__Call_onceEx(&once, call_once_ex_func, &cnt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test__Call_once(void)
|
||||
{
|
||||
HANDLE h[4];
|
||||
int i;
|
||||
|
||||
for(i=0; i<4; i++)
|
||||
h[i] = CreateThread(NULL, 0, call_once_thread, &once, 0, NULL);
|
||||
ok(WaitForMultipleObjects(4, h, TRUE, INFINITE) == WAIT_OBJECT_0,
|
||||
"error waiting for all threads to finish\n");
|
||||
ok(cnt == 0x10000, "cnt = %x\n", cnt);
|
||||
ok(once == 1, "once = %x\n", once);
|
||||
|
||||
once = cnt = 0;
|
||||
for(i=0; i<4; i++)
|
||||
h[i] = CreateThread(NULL, 0, call_once_ex_thread, &once, 0, NULL);
|
||||
ok(WaitForMultipleObjects(4, h, TRUE, INFINITE) == WAIT_OBJECT_0,
|
||||
"error waiting for all threads to finish\n");
|
||||
ok(cnt == 1, "cnt = %x\n", cnt);
|
||||
ok(once == 1, "once = %x\n", once);
|
||||
}
|
||||
|
||||
START_TEST(msvcp120)
|
||||
{
|
||||
if(!init()) return;
|
||||
test__Xtime_diff_to_millis2();
|
||||
test_xtime_get();
|
||||
test__Getcvt();
|
||||
test__Call_once();
|
||||
|
||||
FreeLibrary(msvcp);
|
||||
}
|
||||
|
|
|
@ -3668,8 +3668,8 @@
|
|||
@ cdecl -ret64 -arch=arm ?xsputn@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@MAA_JPB_W_J@Z(ptr wstr int64) msvcp120.?xsputn@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@MAA_JPB_W_J@Z
|
||||
@ thiscall -ret64 -arch=i386 ?xsputn@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@MAE_JPB_W_J@Z(ptr wstr int64) msvcp120.?xsputn@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@MAE_JPB_W_J@Z
|
||||
@ cdecl -arch=win64 ?xsputn@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@MEAA_JPEB_W_J@Z(ptr ptr long) msvcp120.?xsputn@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@MEAA_JPEB_W_J@Z
|
||||
@ stub _Call_once
|
||||
@ stub _Call_onceEx
|
||||
@ cdecl _Call_once(ptr ptr) msvcp120._Call_once
|
||||
@ cdecl _Call_onceEx(ptr ptr ptr) msvcp120._Call_onceEx
|
||||
@ stub _Cnd_broadcast
|
||||
@ stub _Cnd_destroy
|
||||
@ stub _Cnd_do_broadcast_at_thread_exit
|
||||
|
|
|
@ -630,6 +630,41 @@ void __asm_dummy_vtables(void) {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if _MSVCP_VER >= 110
|
||||
static CRITICAL_SECTION call_once_cs;
|
||||
static CRITICAL_SECTION_DEBUG call_once_cs_debug =
|
||||
{
|
||||
0, 0, &call_once_cs,
|
||||
{ &call_once_cs_debug.ProcessLocksList, &call_once_cs_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": call_once_cs") }
|
||||
};
|
||||
static CRITICAL_SECTION call_once_cs = { &call_once_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
void __cdecl _Call_onceEx(int *once, void (__cdecl *func)(void*), void *argv)
|
||||
{
|
||||
TRACE("%p %p %p\n", once, func, argv);
|
||||
|
||||
EnterCriticalSection(&call_once_cs);
|
||||
if(!*once) {
|
||||
/* FIXME: handle exceptions */
|
||||
func(argv);
|
||||
*once = 1;
|
||||
}
|
||||
LeaveCriticalSection(&call_once_cs);
|
||||
}
|
||||
|
||||
void __cdecl call_once_func_wrapper(void *func)
|
||||
{
|
||||
((void (__cdecl*)(void))func)();
|
||||
}
|
||||
|
||||
void __cdecl _Call_once(int *once, void (__cdecl *func)(void))
|
||||
{
|
||||
TRACE("%p %p\n", once, func);
|
||||
_Call_onceEx(once, call_once_func_wrapper, func);
|
||||
}
|
||||
#endif
|
||||
|
||||
void init_misc(void *base)
|
||||
{
|
||||
#ifdef __x86_64__
|
||||
|
|
Loading…
Reference in a new issue