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>
This commit is contained in:
parent
f2267802d0
commit
4dc7f609e7
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue