rpcrt4: Create one protseq object per used protocol sequence, not per RpcServerUseProtseq* function call.
diff --git a/dlls/rpcrt4/rpc_server.c b/dlls/rpcrt4/rpc_server.c
index fbd7233..77f3c35 100644
--- a/dlls/rpcrt4/rpc_server.c
+++ b/dlls/rpcrt4/rpc_server.c
@@ -500,10 +500,6 @@
if (status != RPC_S_OK)
return status;
- EnterCriticalSection(&server_cs);
- list_add_head(&protseqs, &ps->entry);
- LeaveCriticalSection(&server_cs);
-
if (std_listen)
{
status = RPCRT4_start_listen_protseq(ps, FALSE);
@@ -604,6 +600,8 @@
/***********************************************************************
* alloc_serverprotoseq (internal)
+ *
+ * Must be called with server_cs held.
*/
static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps)
{
@@ -628,9 +626,37 @@
(*ps)->mgr_mutex = NULL;
(*ps)->server_ready_event = NULL;
+ list_add_head(&protseqs, &(*ps)->entry);
+
+ TRACE("new protseq %p created for %s\n", *ps, Protseq);
+
return RPC_S_OK;
}
+/* Finds a given protseq or creates a new one if one doesn't already exist */
+static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps)
+{
+ RPC_STATUS status;
+ RpcServerProtseq *cps;
+
+ EnterCriticalSection(&server_cs);
+
+ LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry)
+ if (!strcmp(cps->Protseq, Protseq))
+ {
+ TRACE("found existing protseq object for %s\n", Protseq);
+ *ps = cps;
+ LeaveCriticalSection(&server_cs);
+ return S_OK;
+ }
+
+ status = alloc_serverprotoseq(MaxCalls, Protseq, ps);
+
+ LeaveCriticalSection(&server_cs);
+
+ return status;
+}
+
/***********************************************************************
* RpcServerUseProtseqEpExA (RPCRT4.@)
*/
@@ -645,7 +671,7 @@
debugstr_a(szep), SecurityDescriptor,
lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
- status = alloc_serverprotoseq(MaxCalls, RPCRT4_strdupA(szps), &ps);
+ status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupA(szps), &ps);
if (status != RPC_S_OK)
return status;
@@ -666,7 +692,7 @@
debugstr_w( Endpoint ), SecurityDescriptor,
lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
- status = alloc_serverprotoseq(MaxCalls, RPCRT4_strdupWtoA(Protseq), &ps);
+ status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupWtoA(Protseq), &ps);
if (status != RPC_S_OK)
return status;