Piotr Caban : msvcp110: Add _Cnd_{do_broadcast, register, unregister}_at_thread_exit implementation.
Alexandre Julliard
julliard at winehq.org
Tue Sep 27 11:08:51 CDT 2016
Module: wine
Branch: master
Commit: 4dc7f609e7d70ba2e28163ab5656b45339d95f11
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4dc7f609e7d70ba2e28163ab5656b45339d95f11
Author: Piotr Caban <piotr at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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
}
More information about the wine-cvs
mailing list