rpcrt4: Create one protseq object per used protocol sequence, not per RpcServerUseProtseq* function call.

Robert Shearman rob at codeweavers.com
Fri Nov 10 06:13:57 CST 2006


---
  dlls/rpcrt4/rpc_server.c |   38 ++++++++++++++++++++++++++++++++------
  1 files changed, 32 insertions(+), 6 deletions(-)

This should result in a slight performance improvement for code that 
calls RpcServerUseProtseq* a lot (e.g. COM code) as it will now only 
create one thread instead of many.
-------------- next part --------------
diff --git a/dlls/rpcrt4/rpc_server.c b/dlls/rpcrt4/rpc_server.c
index 9e02e24..24b1446 100644
--- a/dlls/rpcrt4/rpc_server.c
+++ b/dlls/rpcrt4/rpc_server.c
@@ -500,10 +500,6 @@ static RPC_STATUS RPCRT4_use_protseq(Rpc
   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 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpW
 
 /***********************************************************************
  *             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 @@ static RPC_STATUS alloc_serverprotoseq(U
   (*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 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpE
        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 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpE
        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;
 


More information about the wine-patches mailing list