rpcrt4: Free the resources associated with server protocol sequences on DLL unload.

This commit is contained in:
Rob Shearman 2009-03-20 16:10:42 +00:00 committed by Alexandre Julliard
parent d38cc9acbc
commit 5e1d10d423
3 changed files with 45 additions and 17 deletions

View File

@ -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 (!std_listen)
if (res == -1 || (res == 0 && !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;
}
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.@)
*/

View File

@ -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 */

View File

@ -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;
}