Added timeout on blocking send, receive operations
This commit is contained in:
parent
44e7d2f36c
commit
ad4d5c1ce7
@ -25,6 +25,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <freerdp/utils/tcp.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
#include <winpr/synch.h>
|
||||
@ -37,6 +39,8 @@
|
||||
|
||||
#include "../rdp.h"
|
||||
|
||||
#define SYNCHRONOUS_TIMEOUT 5000
|
||||
|
||||
wStream* rpc_client_fragment_pool_take(rdpRpc* rpc)
|
||||
{
|
||||
wStream* fragment = NULL;
|
||||
@ -360,6 +364,7 @@ void rpc_client_call_free(RpcClientCall* clientCall)
|
||||
int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
RPC_PDU* pdu;
|
||||
int status;
|
||||
|
||||
pdu = (RPC_PDU*) malloc(sizeof(RPC_PDU));
|
||||
pdu->s = Stream_New(buffer, length);
|
||||
@ -368,7 +373,13 @@ int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
|
||||
if (rpc->client->SynchronousSend)
|
||||
{
|
||||
WaitForSingleObject(rpc->client->PduSentEvent, INFINITE);
|
||||
status = WaitForSingleObject(rpc->client->PduSentEvent, SYNCHRONOUS_TIMEOUT);
|
||||
if (status == WAIT_TIMEOUT)
|
||||
{
|
||||
fprintf(stderr, "rpc_send_enqueue_pdu: timed out waiting for pdu sent event\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ResetEvent(rpc->client->PduSentEvent);
|
||||
}
|
||||
|
||||
@ -425,9 +436,16 @@ RPC_PDU* rpc_recv_dequeue_pdu(rdpRpc* rpc)
|
||||
DWORD dwMilliseconds;
|
||||
|
||||
pdu = NULL;
|
||||
dwMilliseconds = rpc->client->SynchronousReceive ? INFINITE : 0;
|
||||
dwMilliseconds = rpc->client->SynchronousReceive ? SYNCHRONOUS_TIMEOUT : 0;
|
||||
|
||||
if (WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds) == WAIT_OBJECT_0)
|
||||
DWORD result = WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds);
|
||||
if (result == WAIT_TIMEOUT)
|
||||
{
|
||||
fprintf(stderr, "rpc_recv_dequeue_pdu: timed out waiting for receive event\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (result == WAIT_OBJECT_0)
|
||||
{
|
||||
pdu = (RPC_PDU*) Queue_Dequeue(rpc->client->ReceiveQueue);
|
||||
|
||||
@ -450,11 +468,18 @@ RPC_PDU* rpc_recv_peek_pdu(rdpRpc* rpc)
|
||||
{
|
||||
RPC_PDU* pdu;
|
||||
DWORD dwMilliseconds;
|
||||
DWORD result;
|
||||
|
||||
pdu = NULL;
|
||||
dwMilliseconds = rpc->client->SynchronousReceive ? INFINITE : 0;
|
||||
dwMilliseconds = rpc->client->SynchronousReceive ? SYNCHRONOUS_TIMEOUT : 0;
|
||||
|
||||
if (WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds) == WAIT_OBJECT_0)
|
||||
result = WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds);
|
||||
if (result == WAIT_TIMEOUT)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (result == WAIT_OBJECT_0)
|
||||
{
|
||||
pdu = (RPC_PDU*) Queue_Peek(rpc->client->ReceiveQueue);
|
||||
return pdu;
|
||||
|
@ -1486,6 +1486,12 @@ int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
|
||||
|
||||
rpc = tsg->rpc;
|
||||
|
||||
if (rpc->transport->layer == TRANSPORT_LAYER_CLOSED)
|
||||
{
|
||||
fprintf(stderr, "tsg_read error: connection lost\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tsg->PendingPdu)
|
||||
{
|
||||
CopyLength = (length < tsg->BytesAvailable) ? length : tsg->BytesAvailable;
|
||||
|
@ -553,7 +553,11 @@ int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes)
|
||||
return status;
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
/* A read error indicates that the peer has dropped the connection */
|
||||
transport->layer = TRANSPORT_LAYER_CLOSED;
|
||||
return status;
|
||||
}
|
||||
|
||||
read += status;
|
||||
|
||||
@ -1032,14 +1036,20 @@ static void* transport_client_thread(void* arg)
|
||||
|
||||
transport_get_read_handles(transport, (HANDLE*) &handles, &nCount);
|
||||
|
||||
status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
|
||||
|
||||
status = WaitForMultipleObjects(nCount, handles, FALSE, 100);
|
||||
if (transport->layer == TRANSPORT_LAYER_CLOSED)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (status != WAIT_TIMEOUT)
|
||||
{
|
||||
if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
break;
|
||||
|
||||
if (!freerdp_check_fds(instance))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WLog_Print(transport->log, WLOG_DEBUG, "Terminating transport thread");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user