msvcp110: Add _Cnd_{do_broadcast,register,unregister}_at_thread_exit implementation.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
oldstable
Piotr Caban 2016-09-27 13:29:00 +02:00 committed by Alexandre Julliard
parent f2267802d0
commit 4dc7f609e7
5 changed files with 112 additions and 12 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}