libfreerdp-core: started async transport

This commit is contained in:
Marc-André Moreau 2013-03-27 13:03:41 -04:00
parent 690b5147db
commit 1df8049c08
5 changed files with 83 additions and 11 deletions

View File

@ -1210,6 +1210,7 @@ int xfreerdp_run(freerdp* instance)
BOOL async_update;
BOOL async_input;
BOOL async_channels;
BOOL async_transport;
HANDLE update_thread;
HANDLE input_thread;
HANDLE channels_thread;
@ -1245,6 +1246,7 @@ int xfreerdp_run(freerdp* instance)
async_update = settings->AsyncUpdate;
async_input = settings->AsyncInput;
async_channels = settings->AsyncChannels;
async_transport = settings->AsyncTransport;
if (async_update)
{
@ -1266,11 +1268,14 @@ int xfreerdp_run(freerdp* instance)
rcount = 0;
wcount = 0;
if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
if (!async_transport)
{
printf("Failed to get FreeRDP file descriptor\n");
ret = XF_EXIT_CONN_FAILED;
break;
if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
printf("Failed to get FreeRDP file descriptor\n");
ret = XF_EXIT_CONN_FAILED;
break;
}
}
if (!async_channels)
@ -1336,10 +1341,13 @@ int xfreerdp_run(freerdp* instance)
}
}
if (freerdp_check_fds(instance) != TRUE)
if (!async_transport)
{
printf("Failed to check FreeRDP file descriptor\n");
break;
if (freerdp_check_fds(instance) != TRUE)
{
printf("Failed to check FreeRDP file descriptor\n");
break;
}
}
if (!async_channels)

View File

@ -123,6 +123,7 @@ COMMAND_LINE_ARGUMENT_A args[] =
{ "fast-path", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "fast-path input/output" },
{ "async-input", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "asynchronous input" },
{ "async-update", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "asynchronous update" },
{ "async-transport", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "asynchronous transport (unstable)" },
{ "async-channels", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "asynchronous channels (unstable)" },
{ "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1, NULL, "print version" },
{ "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "print help" },
@ -1511,6 +1512,10 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
{
settings->AsyncChannels = arg->Value ? TRUE : FALSE;
}
CommandLineSwitchCase(arg, "async-transport")
{
settings->AsyncTransport = arg->Value ? TRUE : FALSE;
}
CommandLineSwitchDefault(arg)
{

View File

@ -944,8 +944,9 @@ struct rdp_settings
ALIGN64 BOOL AsyncInput; /* 1544 */
ALIGN64 BOOL AsyncUpdate; /* 1545 */
ALIGN64 BOOL AsyncChannels; /* 1546 */
ALIGN64 BOOL ToggleFullscreen; /* 1547 */
UINT64 padding1600[1600 - 1548]; /* 1548 */
ALIGN64 BOOL AsyncTransport; /* 1547 */
ALIGN64 BOOL ToggleFullscreen; /* 1548 */
UINT64 padding1600[1600 - 1549]; /* 1549 */
/* Miscellaneous */
ALIGN64 BOOL SoftwareGdi; /* 1601 */

View File

@ -48,6 +48,8 @@
#define BUFFER_SIZE 16384
static void* transport_client_thread(void* arg);
wStream* transport_recv_stream_init(rdpTransport* transport, int size)
{
wStream* s = transport->ReceiveStream;
@ -118,6 +120,7 @@ BOOL transport_connect_tls(rdpTransport* transport)
connectErrorCode = TLSCONNECTERROR;
tls_free(transport->TlsIn);
if (transport->TlsIn == transport->TlsOut)
transport->TlsIn = transport->TlsOut = NULL;
else
@ -203,6 +206,16 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por
BOOL status = FALSE;
rdpSettings* settings = transport->settings;
transport->async = transport->settings->AsyncTransport;
if (transport->async)
{
transport->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
transport->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) transport_client_thread, transport, 0, NULL);
}
if (transport->settings->GatewayUsageMethod)
{
transport->layer = TRANSPORT_LAYER_TSG;
@ -736,6 +749,47 @@ BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking)
return status;
}
static void* transport_client_thread(void* arg)
{
DWORD status;
DWORD nCount;
HANDLE events[3];
HANDLE ReadEvent;
freerdp* instance;
rdpTransport* transport;
transport = (rdpTransport*) arg;
instance = (freerdp*) transport->settings->instance;
ReadEvent = CreateFileDescriptorEvent(NULL, TRUE, FALSE, transport->TcpIn->sockfd);
nCount = 0;
events[nCount++] = transport->stopEvent;
events[nCount++] = ReadEvent;
while (1)
{
printf("transport_client_thread\n");
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
{
break;
}
if (WaitForSingleObject(ReadEvent, 0) == WAIT_OBJECT_0)
{
if (!freerdp_check_fds(instance))
break;
}
}
CloseHandle(ReadEvent);
return NULL;
}
wStream* transport_receive_buffer_pool_new()
{
wStream* pdu = NULL;

View File

@ -36,6 +36,9 @@ typedef struct rdp_transport rdpTransport;
#include "gateway/tsg.h"
#include <winpr/sspi.h>
#include <winpr/synch.h>
#include <winpr/thread.h>
#include <winpr/stream.h>
#include <winpr/collections.h>
#include <freerdp/crypto/tls.h>
@ -44,8 +47,6 @@ typedef struct rdp_transport rdpTransport;
#include <freerdp/types.h>
#include <freerdp/settings.h>
#include <winpr/stream.h>
typedef int (*TransportRecv) (rdpTransport* transport, wStream* stream, void* extra);
struct rdp_transport
@ -68,6 +69,9 @@ struct rdp_transport
BOOL blocking;
BOOL SplitInputOutput;
wObjectPool* ReceivePool;
HANDLE stopEvent;
HANDLE thread;
BOOL async;
};
wStream* transport_recv_stream_init(rdpTransport* transport, int size);