Piotr Caban : msvcp110: Add _Cnd_{do_broadcast, register, unregister}_at_thread_exit implementation.
Module: wine Branch: master Commit: 4dc7f609e7d70ba2e28163ab5656b45339d95f11 URL: http://source.winehq.org/git/wine.git/?a=commit;h=4dc7f609e7d70ba2e28163ab56... Author: Piotr Caban <piotr(a)codeweavers.com> Date: Tue Sep 27 13:29:00 2016 +0200 msvcp110: Add _Cnd_{do_broadcast,register,unregister}_at_thread_exit implementation. Signed-off-by: Piotr Caban <piotr(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/msvcp110/msvcp110.spec | 6 +-- dlls/msvcp120/msvcp120.spec | 6 +-- dlls/msvcp120_app/msvcp120_app.spec | 6 +-- dlls/msvcp140/msvcp140.spec | 6 +-- dlls/msvcp90/misc.c | 100 ++++++++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 12 deletions(-) diff --git a/dlls/msvcp110/msvcp110.spec b/dlls/msvcp110/msvcp110.spec index 8affc67..02ffa9b 100644 --- a/dlls/msvcp110/msvcp110.spec +++ b/dlls/msvcp110/msvcp110.spec @@ -3731,12 +3731,12 @@ @ cdecl _Call_onceEx(ptr ptr ptr) @ cdecl _Cnd_broadcast(ptr) @ cdecl _Cnd_destroy(ptr) -@ stub _Cnd_do_broadcast_at_thread_exit +@ cdecl _Cnd_do_broadcast_at_thread_exit() @ cdecl _Cnd_init(ptr) -@ stub _Cnd_register_at_thread_exit +@ cdecl _Cnd_register_at_thread_exit(ptr ptr ptr) @ cdecl _Cnd_signal(ptr) @ cdecl _Cnd_timedwait(ptr ptr ptr) -@ stub _Cnd_unregister_at_thread_exit +@ cdecl _Cnd_unregister_at_thread_exit(ptr) @ cdecl _Cnd_wait(ptr ptr) @ stub _Cosh @ extern _Denorm diff --git a/dlls/msvcp120/msvcp120.spec b/dlls/msvcp120/msvcp120.spec index 3cb81fe..7b8a243 100644 --- a/dlls/msvcp120/msvcp120.spec +++ b/dlls/msvcp120/msvcp120.spec @@ -3672,12 +3672,12 @@ @ cdecl _Call_onceEx(ptr ptr ptr) @ cdecl _Cnd_broadcast(ptr) @ cdecl _Cnd_destroy(ptr) -@ stub _Cnd_do_broadcast_at_thread_exit +@ cdecl _Cnd_do_broadcast_at_thread_exit() @ cdecl _Cnd_init(ptr) -@ stub _Cnd_register_at_thread_exit +@ cdecl _Cnd_register_at_thread_exit(ptr ptr ptr) @ cdecl _Cnd_signal(ptr) @ cdecl _Cnd_timedwait(ptr ptr ptr) -@ stub _Cnd_unregister_at_thread_exit +@ cdecl _Cnd_unregister_at_thread_exit(ptr) @ cdecl _Cnd_wait(ptr ptr) @ stub _Cosh @ extern _Denorm diff --git a/dlls/msvcp120_app/msvcp120_app.spec b/dlls/msvcp120_app/msvcp120_app.spec index b799564..9ce5fea 100644 --- a/dlls/msvcp120_app/msvcp120_app.spec +++ b/dlls/msvcp120_app/msvcp120_app.spec @@ -3672,12 +3672,12 @@ @ cdecl _Call_onceEx(ptr ptr ptr) msvcp120._Call_onceEx @ cdecl _Cnd_broadcast(ptr) msvcp120._Cnd_broadcast @ cdecl _Cnd_destroy(ptr) msvcp120._Cnd_destroy -@ stub _Cnd_do_broadcast_at_thread_exit +@ cdecl _Cnd_do_broadcast_at_thread_exit() msvcp120._Cnd_do_broadcast_at_thread_exit @ cdecl _Cnd_init(ptr) msvcp120._Cnd_init -@ stub _Cnd_register_at_thread_exit +@ cdecl _Cnd_register_at_thread_exit(ptr ptr ptr) msvcp120._Cnd_register_at_thread_exit @ cdecl _Cnd_signal(ptr) msvcp120._Cnd_signal @ cdecl _Cnd_timedwait(ptr ptr ptr) msvcp120._Cnd_timedwait -@ stub _Cnd_unregister_at_thread_exit +@ cdecl _Cnd_unregister_at_thread_exit(ptr) msvcp120._Cnd_unregister_at_thread_exit @ cdecl _Cnd_wait(ptr ptr) msvcp120._Cnd_wait @ stub _Cosh @ extern _Denorm msvcp120._Denorm diff --git a/dlls/msvcp140/msvcp140.spec b/dlls/msvcp140/msvcp140.spec index cad39e9..c8e16fa 100644 --- a/dlls/msvcp140/msvcp140.spec +++ b/dlls/msvcp140/msvcp140.spec @@ -3624,13 +3624,13 @@ @ cdecl _Cnd_broadcast(ptr) _Cnd_broadcast @ cdecl _Cnd_destroy(ptr) _Cnd_destroy @ stub _Cnd_destroy_in_situ -@ stub _Cnd_do_broadcast_at_thread_exit +@ cdecl _Cnd_do_broadcast_at_thread_exit() @ cdecl _Cnd_init(ptr) _Cnd_init @ cdecl _Cnd_init_in_situ(ptr) -@ stub _Cnd_register_at_thread_exit +@ cdecl _Cnd_register_at_thread_exit(ptr ptr ptr) @ cdecl _Cnd_signal(ptr) _Cnd_signal @ cdecl _Cnd_timedwait(ptr ptr ptr) _Cnd_timedwait -@ stub _Cnd_unregister_at_thread_exit +@ cdecl _Cnd_unregister_at_thread_exit(ptr) @ cdecl _Cnd_wait(ptr ptr) _Cnd_wait @ stub _Copy_file @ stub _Cosh diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c index 41f2eeb..885ec6f 100644 --- a/dlls/msvcp90/misc.c +++ b/dlls/msvcp90/misc.c @@ -662,6 +662,105 @@ void __cdecl _Cnd_destroy(_Cnd_arg_t cnd) MSVCRT_operator_delete(CND_T_FROM_ARG(cnd)); } } + +static struct { + int used; + int size; + + struct _to_broadcast { + DWORD thread_id; + _Cnd_arg_t cnd; + _Mtx_arg_t mtx; + int *p; + } *to_broadcast; +} broadcast_at_thread_exit; + +static CRITICAL_SECTION broadcast_at_thread_exit_cs; +static CRITICAL_SECTION_DEBUG broadcast_at_thread_exit_cs_debug = +{ + 0, 0, &broadcast_at_thread_exit_cs, + { &broadcast_at_thread_exit_cs_debug.ProcessLocksList, &broadcast_at_thread_exit_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": broadcast_at_thread_exit_cs") } +}; +static CRITICAL_SECTION broadcast_at_thread_exit_cs = { &broadcast_at_thread_exit_cs_debug, -1, 0, 0, 0, 0 }; + +void __cdecl _Cnd_register_at_thread_exit(_Cnd_arg_t cnd, _Mtx_arg_t mtx, int *p) +{ + struct _to_broadcast *add; + + TRACE("(%p %p %p)\n", cnd, mtx, p); + + EnterCriticalSection(&broadcast_at_thread_exit_cs); + if(!broadcast_at_thread_exit.size) { + broadcast_at_thread_exit.to_broadcast = HeapAlloc(GetProcessHeap(), + 0, 8*sizeof(broadcast_at_thread_exit.to_broadcast[0])); + if(!broadcast_at_thread_exit.to_broadcast) { + LeaveCriticalSection(&broadcast_at_thread_exit_cs); + return; + } + broadcast_at_thread_exit.size = 8; + } else if(broadcast_at_thread_exit.size == broadcast_at_thread_exit.used) { + add = HeapReAlloc(GetProcessHeap(), 0, broadcast_at_thread_exit.to_broadcast, + broadcast_at_thread_exit.size*2*sizeof(broadcast_at_thread_exit.to_broadcast[0])); + if(!add) { + LeaveCriticalSection(&broadcast_at_thread_exit_cs); + return; + } + broadcast_at_thread_exit.to_broadcast = add; + broadcast_at_thread_exit.size *= 2; + } + + add = broadcast_at_thread_exit.to_broadcast + broadcast_at_thread_exit.used++; + add->thread_id = GetCurrentThreadId(); + add->cnd = cnd; + add->mtx = mtx; + add->p = p; + LeaveCriticalSection(&broadcast_at_thread_exit_cs); +} + +void __cdecl _Cnd_unregister_at_thread_exit(_Mtx_arg_t mtx) +{ + int i; + + TRACE("(%p)\n", mtx); + + EnterCriticalSection(&broadcast_at_thread_exit_cs); + for(i=0; i<broadcast_at_thread_exit.used; i++) { + if(broadcast_at_thread_exit.to_broadcast[i].mtx != mtx) + continue; + + memmove(broadcast_at_thread_exit.to_broadcast+i, broadcast_at_thread_exit.to_broadcast+i+1, + (broadcast_at_thread_exit.used-i-1)*sizeof(broadcast_at_thread_exit.to_broadcast[0])); + broadcast_at_thread_exit.used--; + i--; + } + LeaveCriticalSection(&broadcast_at_thread_exit_cs); +} + +void __cdecl _Cnd_do_broadcast_at_thread_exit(void) +{ + int i, id = GetCurrentThreadId(); + + TRACE("()\n"); + + EnterCriticalSection(&broadcast_at_thread_exit_cs); + for(i=0; i<broadcast_at_thread_exit.used; i++) { + if(broadcast_at_thread_exit.to_broadcast[i].thread_id != id) + continue; + + _Mtx_unlock(broadcast_at_thread_exit.to_broadcast[i].mtx); + _Cnd_broadcast(broadcast_at_thread_exit.to_broadcast[i].cnd); + if(broadcast_at_thread_exit.to_broadcast[i].p) + *broadcast_at_thread_exit.to_broadcast[i].p = 1; + + memmove(broadcast_at_thread_exit.to_broadcast+i, broadcast_at_thread_exit.to_broadcast+i+1, + (broadcast_at_thread_exit.used-i-1)*sizeof(broadcast_at_thread_exit.to_broadcast[0])); + broadcast_at_thread_exit.used--; + i--; + } + LeaveCriticalSection(&broadcast_at_thread_exit_cs); +} + #endif #if _MSVCP_VER == 100 @@ -1195,6 +1294,7 @@ void free_misc(void) #if _MSVCP_VER >= 110 if(keyed_event) NtClose(keyed_event); + HeapFree(GetProcessHeap(), 0, broadcast_at_thread_exit.to_broadcast); #endif }
participants (1)
-
Alexandre Julliard