Module: wine Branch: master Commit: 2f6e643d567d2d16f0334cf42597d6027fa893a4 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2f6e643d567d2d16f0334cf425...
Author: Robert Shearman rob@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 */