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