libfreerdp-core: improve async-transport mode

This commit is contained in:
Marc-André Moreau 2013-04-30 17:16:38 -04:00
parent 3b71f172dc
commit e88b59c32c
7 changed files with 87 additions and 18 deletions

View File

@ -106,9 +106,9 @@ void xf_sw_end_paint(rdpContext* context)
xfi = ((xfContext*) context)->xfi;
gdi = context->gdi;
if (xfi->remote_app != TRUE)
if (!xfi->remote_app)
{
if (xfi->complex_regions != TRUE)
if (!xfi->complex_regions)
{
if (gdi->primary->hdc->hwnd->invalid->null)
return;
@ -183,7 +183,7 @@ void xf_sw_desktop_resize(rdpContext* context)
xf_lock_x11(xfi, TRUE);
if (xfi->fullscreen != TRUE)
if (!xfi->fullscreen)
{
rdpGdi* gdi = context->gdi;
gdi_resize(gdi, xfi->width, xfi->height);
@ -293,7 +293,7 @@ void xf_hw_desktop_resize(rdpContext* context)
xf_lock_x11(xfi, TRUE);
if (xfi->fullscreen != TRUE)
if (!xfi->fullscreen)
{
xfi->width = settings->DesktopWidth;
xfi->height = settings->DesktopHeight;

View File

@ -134,6 +134,8 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, UINT16 port)
if (tcp->sockfd < 0)
return FALSE;
SetEventFileDescriptor(tcp->event, tcp->sockfd);
tcp_get_ip_address(tcp);
tcp_get_mac_address(tcp);
@ -248,6 +250,15 @@ BOOL tcp_set_keep_alive_mode(rdpTcp* tcp)
return TRUE;
}
HANDLE tcp_get_event_handle(rdpTcp* tcp)
{
#ifndef _WIN32
return tcp->event;
#else
return (HANDLE) tcp->wsa_event;
#endif
}
rdpTcp* tcp_new(rdpSettings* settings)
{
rdpTcp* tcp;
@ -260,6 +271,7 @@ rdpTcp* tcp_new(rdpSettings* settings)
tcp->sockfd = -1;
tcp->settings = settings;
tcp->event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, tcp->sockfd);
}
return tcp;
@ -267,8 +279,9 @@ rdpTcp* tcp_new(rdpSettings* settings)
void tcp_free(rdpTcp* tcp)
{
if (tcp != NULL)
if (tcp)
{
CloseHandle(tcp->event);
free(tcp);
}
}

View File

@ -26,6 +26,8 @@
#include <freerdp/types.h>
#include <freerdp/settings.h>
#include <winpr/crt.h>
#include <winpr/synch.h>
#include <winpr/stream.h>
#ifndef MSG_NOSIGNAL
@ -43,6 +45,7 @@ struct rdp_tcp
#ifdef _WIN32
WSAEVENT wsa_event;
#endif
HANDLE event;
};
BOOL tcp_connect(rdpTcp* tcp, const char* hostname, UINT16 port);
@ -53,6 +56,7 @@ int tcp_wait_read(rdpTcp* tcp);
int tcp_wait_write(rdpTcp* tcp);
BOOL tcp_set_blocking_mode(rdpTcp* tcp, BOOL blocking);
BOOL tcp_set_keep_alive_mode(rdpTcp* tcp);
HANDLE tcp_get_event_handle(rdpTcp* tcp);
rdpTcp* tcp_new(rdpSettings* settings);
void tcp_free(rdpTcp* tcp);

View File

@ -568,6 +568,7 @@ int transport_write(rdpTransport* transport, wStream* s)
return status;
}
void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount)
{
void* pfd;
@ -612,6 +613,30 @@ void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount)
}
}
void transport_get_read_handles(rdpTransport* transport, HANDLE* events, DWORD* count)
{
events[*count] = tcp_get_event_handle(transport->TcpIn);
(*count)++;
if (transport->SplitInputOutput)
{
events[*count] = tcp_get_event_handle(transport->TcpOut);
(*count)++;
}
if (transport->ReceiveEvent)
{
events[*count] = transport->ReceiveEvent;
(*count)++;
}
if (transport->GatewayEvent)
{
events[*count] = transport->GatewayEvent;
(*count)++;
}
}
int transport_check_fds(rdpTransport** ptransport)
{
int pos;
@ -763,22 +788,26 @@ static void* transport_client_thread(void* arg)
{
DWORD status;
DWORD nCount;
HANDLE events[3];
HANDLE ReadEvent;
HANDLE events[32];
freerdp* instance;
rdpTransport* transport;
transport = (rdpTransport*) arg;
instance = (freerdp*) transport->settings->instance;
ReadEvent = CreateFileDescriptorEvent(NULL, TRUE, FALSE, transport->TcpIn->sockfd);
/**
* Ugly temporary hack to start thread after connection
*/
nCount = 0;
events[nCount++] = transport->stopEvent;
events[nCount++] = ReadEvent;
Sleep(2000);
while (1)
{
nCount = 0;
events[nCount++] = transport->stopEvent;
transport_get_read_handles(transport, (HANDLE*) &events, &nCount);
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
@ -786,15 +815,10 @@ static void* transport_client_thread(void* arg)
break;
}
if (WaitForSingleObject(ReadEvent, 0) == WAIT_OBJECT_0)
{
if (!freerdp_check_fds(instance))
break;
}
if (!freerdp_check_fds(instance))
break;
}
CloseHandle(ReadEvent);
return NULL;
}

View File

@ -92,6 +92,7 @@ int transport_write(rdpTransport* transport, wStream* s);
void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount);
int transport_check_fds(rdpTransport** ptransport);
BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking);
void transport_get_read_handles(rdpTransport* transport, HANDLE* events, DWORD* count);
wStream* transport_receive_pool_take(rdpTransport* transport);
int transport_receive_pool_return(rdpTransport* transport, wStream* pdu);

View File

@ -273,6 +273,8 @@ WINPR_API HANDLE CreateWaitObjectEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,
#endif
WINPR_API int GetEventFileDescriptor(HANDLE hEvent);
WINPR_API int SetEventFileDescriptor(HANDLE hEvent, int FileDescriptor);
WINPR_API void* GetEventWaitObject(HANDLE hEvent);
#ifdef __cplusplus

View File

@ -273,6 +273,31 @@ int GetEventFileDescriptor(HANDLE hEvent)
#endif
}
/*
* Set inner file descriptor for usage with select()
* This file descriptor is not usable on Windows
*/
int SetEventFileDescriptor(HANDLE hEvent, int FileDescriptor)
{
#ifndef _WIN32
ULONG Type;
PVOID Object;
WINPR_EVENT* event;
if (!winpr_Handle_GetInfo(hEvent, &Type, &Object))
return -1;
event = (WINPR_EVENT*) Object;
event->pipe_fd[0] = FileDescriptor;
return 0;
#else
return -1;
#endif
}
/**
* Returns platform-specific wait object as a void pointer
*