Robert Shearman : rpcrt4: Add a critical section to protect the connection list in each

Alexandre Julliard julliard at wine.codeweavers.com
Mon Oct 16 13:58:17 CDT 2006


Module: wine
Branch: master
Commit: 2f6e643d567d2d16f0334cf42597d6027fa893a4
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2f6e643d567d2d16f0334cf42597d6027fa893a4

Author: Robert Shearman <rob at codeweavers.com>
Date:   Mon Oct 16 17:01:27 2006 +0100

rpcrt4: Add a critical section to protect the connection list in each
protseq to avoid taking the process-wide server_cs in the hot path for
each protocol.

---

 dlls/rpcrt4/rpc_server.c |   21 +++++++++++++++------
 dlls/rpcrt4/rpc_server.h |   14 ++++++++------
 2 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/dlls/rpcrt4/rpc_server.c b/dlls/rpcrt4/rpc_server.c
index da71ab6..54e270b 100644
--- a/dlls/rpcrt4/rpc_server.c
+++ b/dlls/rpcrt4/rpc_server.c
@@ -374,6 +374,8 @@ static void *rpcrt4_protseq_np_get_wait_
     RpcConnection* conn;
     RpcServerProtseq_np *npps = CONTAINING_RECORD(protseq, RpcServerProtseq_np, common);
 
+    EnterCriticalSection(&protseq->cs);
+
     /* open and count connections */
     *count = 1;
     conn = protseq->conn;
@@ -392,6 +394,7 @@ static void *rpcrt4_protseq_np_get_wait_
     if (!objs)
     {
         ERR("couldn't allocate objs\n");
+        LeaveCriticalSection(&protseq->cs);
         return NULL;
     }
     
@@ -403,6 +406,7 @@ static void *rpcrt4_protseq_np_get_wait_
             (*count)++;
         conn = conn->Next;
     }
+    LeaveCriticalSection(&protseq->cs);
     return objs;
 }
 
@@ -434,7 +438,7 @@ static int rpcrt4_protseq_np_wait_for_ne
     {
         b_handle = objs[res - WAIT_OBJECT_0];
         /* find which connection got a RPC */
-        EnterCriticalSection(&server_cs);
+        EnterCriticalSection(&protseq->cs);
         conn = protseq->conn;
         while (conn) {
             if (b_handle == rpcrt4_conn_get_wait_object(conn)) break;
@@ -445,7 +449,7 @@ static int rpcrt4_protseq_np_wait_for_ne
             RPCRT4_SpawnConnection(&cconn, conn);
         else
             ERR("failed to locate connection for handle %p\n", b_handle);
-        LeaveCriticalSection(&server_cs);
+        LeaveCriticalSection(&protseq->cs);
         if (cconn)
         {
             RPCRT4_new_client(cconn);
@@ -504,9 +508,7 @@ static DWORD CALLBACK RPCRT4_server_thre
   TRACE("(the_arg == ^%p)\n", the_arg);
 
   for (;;) {
-    EnterCriticalSection(&server_cs);
     objs = cps->ops->get_wait_array(cps, objs, &count);
-    LeaveCriticalSection(&server_cs);
 
     if (set_ready_event)
     {
@@ -530,14 +532,14 @@ static DWORD CALLBACK RPCRT4_server_thre
     }
   }
   cps->ops->free_wait_array(cps, objs);
-  EnterCriticalSection(&server_cs);
+  EnterCriticalSection(&cps->cs);
   /* close connections */
   conn = cps->conn;
   while (conn) {
     RPCRT4_CloseConnection(conn);
     conn = conn->Next;
   }
-  LeaveCriticalSection(&server_cs);
+  LeaveCriticalSection(&cps->cs);
   return 0;
 }
 
@@ -600,6 +602,7 @@ static RPC_STATUS RPCRT4_start_listen(BO
 
   if (std_listen)
   {
+    EnterCriticalSection(&server_cs);
     LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry)
     {
       status = RPCRT4_start_listen_protseq(cps, TRUE);
@@ -610,6 +613,7 @@ static RPC_STATUS RPCRT4_start_listen(BO
        * returning */
       RPCRT4_sync_with_server_thread(cps);
     }
+    LeaveCriticalSection(&server_cs);
   }
 
   return status;
@@ -678,11 +682,13 @@ RPC_STATUS WINAPI RpcServerInqBindings( 
   /* count connections */
   count = 0;
   LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) {
+    EnterCriticalSection(&ps->cs);
     conn = ps->conn;
     while (conn) {
       count++;
       conn = conn->Next;
     }
+    LeaveCriticalSection(&ps->cs);
   }
   if (count) {
     /* export bindings */
@@ -692,6 +698,7 @@ RPC_STATUS WINAPI RpcServerInqBindings( 
     (*BindingVector)->Count = count;
     count = 0;
     LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) {
+      EnterCriticalSection(&ps->cs);
       conn = ps->conn;
       while (conn) {
        RPCRT4_MakeBinding((RpcBinding**)&(*BindingVector)->BindingH[count],
@@ -699,6 +706,7 @@ RPC_STATUS WINAPI RpcServerInqBindings( 
        count++;
        conn = conn->Next;
       }
+      LeaveCriticalSection(&ps->cs);
     }
     status = RPC_S_OK;
   } else {
@@ -763,6 +771,7 @@ static RpcServerProtseq *alloc_serverpro
   ps->ops = ops;
   ps->MaxCalls = 0;
   ps->conn = NULL;
+  InitializeCriticalSection(&ps->cs);
   ps->is_listening = FALSE;
   ps->mgr_mutex = NULL;
   ps->server_ready_event = NULL;
diff --git a/dlls/rpcrt4/rpc_server.h b/dlls/rpcrt4/rpc_server.h
index b2ad8f8..a93bcd1 100644
--- a/dlls/rpcrt4/rpc_server.h
+++ b/dlls/rpcrt4/rpc_server.h
@@ -28,15 +28,17 @@ struct protseq_ops;
 
 typedef struct _RpcServerProtseq
 {
-  const struct protseq_ops *ops;
-  struct list entry;
-  LPSTR Protseq;
-  LPSTR Endpoint;
+  const struct protseq_ops *ops; /* RO */
+  struct list entry; /* CS ::server_cs */
+  LPSTR Protseq; /* RO */
+  LPSTR Endpoint; /* RO */
   UINT MaxCalls;
-  RpcConnection* conn;
+  /* list of listening connections */
+  RpcConnection* conn; /* CS cs */
+  CRITICAL_SECTION cs;
 
   /* is the server currently listening? */
-  BOOL is_listening;
+  BOOL is_listening; /* CS ::listen_cs */
   /* mutex for ensuring only one thread can change state at a time */
   HANDLE mgr_mutex;
   /* set when server thread has finished opening connections */




More information about the wine-cvs mailing list