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

View File

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

View File

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

View File

@ -568,6 +568,7 @@ int transport_write(rdpTransport* transport, wStream* s)
return status; return status;
} }
void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount) void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount)
{ {
void* pfd; 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 transport_check_fds(rdpTransport** ptransport)
{ {
int pos; int pos;
@ -763,22 +788,26 @@ static void* transport_client_thread(void* arg)
{ {
DWORD status; DWORD status;
DWORD nCount; DWORD nCount;
HANDLE events[3]; HANDLE events[32];
HANDLE ReadEvent;
freerdp* instance; freerdp* instance;
rdpTransport* transport; rdpTransport* transport;
transport = (rdpTransport*) arg; transport = (rdpTransport*) arg;
instance = (freerdp*) transport->settings->instance; instance = (freerdp*) transport->settings->instance;
ReadEvent = CreateFileDescriptorEvent(NULL, TRUE, FALSE, transport->TcpIn->sockfd); /**
* Ugly temporary hack to start thread after connection
*/
nCount = 0; Sleep(2000);
events[nCount++] = transport->stopEvent;
events[nCount++] = ReadEvent;
while (1) while (1)
{ {
nCount = 0;
events[nCount++] = transport->stopEvent;
transport_get_read_handles(transport, (HANDLE*) &events, &nCount);
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0) if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
@ -786,14 +815,9 @@ static void* transport_client_thread(void* arg)
break; break;
} }
if (WaitForSingleObject(ReadEvent, 0) == WAIT_OBJECT_0)
{
if (!freerdp_check_fds(instance)) if (!freerdp_check_fds(instance))
break; break;
} }
}
CloseHandle(ReadEvent);
return NULL; 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); void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount);
int transport_check_fds(rdpTransport** ptransport); int transport_check_fds(rdpTransport** ptransport);
BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking); 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); wStream* transport_receive_pool_take(rdpTransport* transport);
int transport_receive_pool_return(rdpTransport* transport, wStream* pdu); int transport_receive_pool_return(rdpTransport* transport, wStream* pdu);

View File

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

View File

@ -273,6 +273,31 @@ int GetEventFileDescriptor(HANDLE hEvent)
#endif #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 * Returns platform-specific wait object as a void pointer
* *