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.
Robert Shearman
rob at codeweavers.com
Mon Oct 16 11:01:27 CDT 2006
---
dlls/rpcrt4/rpc_server.c | 21 +++++++++++++++------
dlls/rpcrt4/rpc_server.h | 14 ++++++++------
2 files changed, 23 insertions(+), 12 deletions(-)
-------------- next part --------------
diff --git a/dlls/rpcrt4/rpc_server.c b/dlls/rpcrt4/rpc_server.c
index 065ac89..5390678 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-patches
mailing list