rpcrt4: Wait for all active connections to be released before quiting server thread.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2017-05-31 17:30:40 +02:00 committed by Alexandre Julliard
parent 10a6b33a93
commit e98c7a59c2
3 changed files with 39 additions and 0 deletions

View File

@ -63,6 +63,7 @@ typedef struct _RpcConnection
{ {
LONG ref; LONG ref;
BOOL server; BOOL server;
HANDLE wait_release;
LPSTR NetworkAddr; LPSTR NetworkAddr;
LPSTR Endpoint; LPSTR Endpoint;
LPWSTR NetworkOptions; LPWSTR NetworkOptions;
@ -176,6 +177,8 @@ RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection,
const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *InterfaceId) DECLSPEC_HIDDEN; const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *InterfaceId) DECLSPEC_HIDDEN;
RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection) DECLSPEC_HIDDEN; RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection) DECLSPEC_HIDDEN;
void rpcrt4_conn_release_and_wait(RpcConnection *connection) DECLSPEC_HIDDEN;
static inline const char *rpcrt4_conn_get_name(const RpcConnection *Connection) static inline const char *rpcrt4_conn_get_name(const RpcConnection *Connection)
{ {
return Connection->ops->name; return Connection->ops->name;

View File

@ -675,20 +675,38 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
set_ready_event = TRUE; set_ready_event = TRUE;
} }
TRACE("closing connections\n");
EnterCriticalSection(&cps->cs); EnterCriticalSection(&cps->cs);
LIST_FOR_EACH_ENTRY(conn, &cps->listeners, RpcConnection, protseq_entry) LIST_FOR_EACH_ENTRY(conn, &cps->listeners, RpcConnection, protseq_entry)
RPCRT4_CloseConnection(conn); RPCRT4_CloseConnection(conn);
LIST_FOR_EACH_ENTRY(conn, &cps->connections, RpcConnection, protseq_entry) LIST_FOR_EACH_ENTRY(conn, &cps->connections, RpcConnection, protseq_entry)
{
RPCRT4_GrabConnection(conn);
rpcrt4_conn_close_read(conn); rpcrt4_conn_close_read(conn);
}
LeaveCriticalSection(&cps->cs); LeaveCriticalSection(&cps->cs);
if (res == 0 && !std_listen) if (res == 0 && !std_listen)
SetEvent(cps->server_ready_event); SetEvent(cps->server_ready_event);
TRACE("waiting for active connections to close\n");
EnterCriticalSection(&cps->cs);
while (!list_empty(&cps->connections))
{
conn = LIST_ENTRY(list_head(&cps->connections), RpcConnection, protseq_entry);
LeaveCriticalSection(&cps->cs);
rpcrt4_conn_release_and_wait(conn);
EnterCriticalSection(&cps->cs);
}
LeaveCriticalSection(&cps->cs);
EnterCriticalSection(&listen_cs); EnterCriticalSection(&listen_cs);
CloseHandle(cps->server_thread); CloseHandle(cps->server_thread);
cps->server_thread = NULL; cps->server_thread = NULL;
LeaveCriticalSection(&listen_cs); LeaveCriticalSection(&listen_cs);
TRACE("done\n");
return 0; return 0;
} }

View File

@ -3357,6 +3357,22 @@ static RpcConnection *rpcrt4_spawn_connection(RpcConnection *old_connection)
return connection; return connection;
} }
void rpcrt4_conn_release_and_wait(RpcConnection *connection)
{
HANDLE event = NULL;
if (connection->ref > 1)
event = connection->wait_release = CreateEventW(NULL, TRUE, FALSE, NULL);
RPCRT4_ReleaseConnection(connection);
if(event)
{
WaitForSingleObject(event, INFINITE);
CloseHandle(event);
}
}
RpcConnection *RPCRT4_GrabConnection( RpcConnection *conn ) RpcConnection *RPCRT4_GrabConnection( RpcConnection *conn )
{ {
InterlockedIncrement( &conn->ref ); InterlockedIncrement( &conn->ref );
@ -3387,6 +3403,8 @@ RPC_STATUS RPCRT4_ReleaseConnection(RpcConnection* Connection)
LeaveCriticalSection(&Connection->protseq->cs); LeaveCriticalSection(&Connection->protseq->cs);
} }
if (Connection->wait_release) SetEvent(Connection->wait_release);
HeapFree(GetProcessHeap(), 0, Connection); HeapFree(GetProcessHeap(), 0, Connection);
return RPC_S_OK; return RPC_S_OK;
} }