Rob Shearman : rpcrt4: Free the resources associated with server protocol sequences on DLL unload .
Alexandre Julliard
julliard at winehq.org
Mon Mar 23 12:34:53 CDT 2009
Module: wine
Branch: master
Commit: 5e1d10d423f1823d4b3052e8b7684299c3e2dc78
URL: http://source.winehq.org/git/wine.git/?a=commit;h=5e1d10d423f1823d4b3052e8b7684299c3e2dc78
Author: Rob Shearman <robertshearman at gmail.com>
Date: Fri Mar 20 16:10:42 2009 +0000
rpcrt4: Free the resources associated with server protocol sequences on DLL unload.
---
dlls/rpcrt4/rpc_server.c | 58 +++++++++++++++++++++++++++++++-------------
dlls/rpcrt4/rpc_server.h | 2 +
dlls/rpcrt4/rpcrt4_main.c | 2 +
3 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/dlls/rpcrt4/rpc_server.c b/dlls/rpcrt4/rpc_server.c
index 565f26e..07434da 100644
--- a/dlls/rpcrt4/rpc_server.c
+++ b/dlls/rpcrt4/rpc_server.c
@@ -449,27 +449,23 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
/* start waiting */
res = cps->ops->wait_for_new_connection(cps, count, objs);
- if (res == -1)
- break;
- else if (res == 0)
+
+ if (res == -1 || (res == 0 && !std_listen))
{
- if (!std_listen)
- {
+ /* cleanup */
+ cps->ops->free_wait_array(cps, objs);
+ EnterCriticalSection(&cps->cs);
+ for (conn = cps->conn; conn; conn = conn->Next)
+ RPCRT4_CloseConnection(conn);
+ LeaveCriticalSection(&cps->cs);
+
+ if (res == 0 && !std_listen)
SetEvent(cps->server_ready_event);
- break;
- }
- set_ready_event = TRUE;
+ break;
}
+ else if (res == 0)
+ set_ready_event = TRUE;
}
- cps->ops->free_wait_array(cps, objs);
- EnterCriticalSection(&cps->cs);
- /* close connections */
- conn = cps->conn;
- while (conn) {
- RPCRT4_CloseConnection(conn);
- conn = conn->Next;
- }
- LeaveCriticalSection(&cps->cs);
return 0;
}
@@ -711,6 +707,17 @@ static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, char *Protseq, RpcServerPr
return RPC_S_OK;
}
+/* must be called with server_cs held */
+static void destroy_serverprotoseq(RpcServerProtseq *ps)
+{
+ RPCRT4_strfree(ps->Protseq);
+ DeleteCriticalSection(&ps->cs);
+ CloseHandle(ps->mgr_mutex);
+ CloseHandle(ps->server_ready_event);
+ list_remove(&ps->entry);
+ HeapFree(GetProcessHeap(), 0, ps);
+}
+
/* 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)
{
@@ -798,6 +805,23 @@ RPC_STATUS WINAPI RpcServerUseProtseqW(RPC_WSTR Protseq, unsigned int MaxCalls,
return RpcServerUseProtseqEpW(Protseq, MaxCalls, NULL, SecurityDescriptor);
}
+void RPCRT4_destroy_all_protseqs(void)
+{
+ RpcServerProtseq *cps, *cursor2;
+
+ if (listen_count != 0)
+ std_listen = FALSE;
+
+ EnterCriticalSection(&server_cs);
+ LIST_FOR_EACH_ENTRY_SAFE(cps, cursor2, &protseqs, RpcServerProtseq, entry)
+ {
+ if (listen_count != 0)
+ RPCRT4_sync_with_server_thread(cps);
+ destroy_serverprotoseq(cps);
+ }
+ LeaveCriticalSection(&server_cs);
+}
+
/***********************************************************************
* RpcServerRegisterIf (RPCRT4.@)
*/
diff --git a/dlls/rpcrt4/rpc_server.h b/dlls/rpcrt4/rpc_server.h
index ffd5b01..0498616 100644
--- a/dlls/rpcrt4/rpc_server.h
+++ b/dlls/rpcrt4/rpc_server.h
@@ -79,4 +79,6 @@ typedef struct _RpcServerInterface
void RPCRT4_new_client(RpcConnection* conn);
const struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq);
+void RPCRT4_destroy_all_protseqs(void);
+
#endif /* __WINE_RPC_SERVER_H */
diff --git a/dlls/rpcrt4/rpcrt4_main.c b/dlls/rpcrt4/rpcrt4_main.c
index 7380b7a..67059e7 100644
--- a/dlls/rpcrt4/rpcrt4_main.c
+++ b/dlls/rpcrt4/rpcrt4_main.c
@@ -52,6 +52,7 @@
#include "rpcproxy.h"
#include "rpc_binding.h"
+#include "rpc_server.h"
#include "wine/debug.h"
@@ -125,6 +126,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
break;
case DLL_PROCESS_DETACH:
+ RPCRT4_destroy_all_protseqs();
break;
}
More information about the wine-cvs
mailing list