Module: wine
Branch: master
Commit: 2d9e894d285937716a4541c7fab9152fdf0b495f
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2d9e894d285937716a4541c7f…
Author: Jacek Caban <jacek(a)codeweavers.com>
Date: Wed Aug 2 15:51:09 2017 +0200
rpcrt4: Always protect ref access for connections associated with protseq in RPCRT4_ReleaseConnection.
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
dlls/rpcrt4/rpc_transport.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c
index 48def49..5735b0f 100644
--- a/dlls/rpcrt4/rpc_transport.c
+++ b/dlls/rpcrt4/rpc_transport.c
@@ -3382,20 +3382,24 @@ RpcConnection *RPCRT4_GrabConnection(RpcConnection *connection)
void RPCRT4_ReleaseConnection(RpcConnection *connection)
{
- LONG ref = InterlockedDecrement(&connection->ref);
+ LONG ref;
- if (!ref && connection->protseq)
+ /* protseq stores a list of active connections, but does not own references to them.
+ * It may need to grab a connection from the list, which could lead to a race if
+ * connection is being released, but not yet removed from the list. We handle that
+ * by synchronizing on CS here. */
+ if (connection->protseq)
{
- /* protseq stores a list of active connections, but does not own references to them.
- * It may need to grab a connection from the list, which could lead to a race if
- * connection is being released, but not yet removed from the list. We handle that
- * by synchronizing on CS here. */
EnterCriticalSection(&connection->protseq->cs);
- ref = connection->ref;
+ ref = InterlockedDecrement(&connection->ref);
if (!ref)
list_remove(&connection->protseq_entry);
LeaveCriticalSection(&connection->protseq->cs);
}
+ else
+ {
+ ref = InterlockedDecrement(&connection->ref);
+ }
TRACE("%p ref=%u\n", connection, ref);