Module: wine Branch: master Commit: 2d9e894d285937716a4541c7fab9152fdf0b495f URL: http://source.winehq.org/git/wine.git/?a=commit;h=2d9e894d285937716a4541c7fa...
Author: Jacek Caban jacek@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@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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);