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:
parent
10a6b33a93
commit
e98c7a59c2
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue