From ab708efc4525933824ae9dc06e651336c43476e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 7 Feb 2013 09:50:15 -0500 Subject: [PATCH] libfreerdp-core: start working on asynchronous channels --- channels/client/channels.c | 26 ++++++++++++++ client/X11/xfreerdp.c | 55 ++++++++++++++++++++++++----- include/freerdp/channels/channels.h | 3 ++ 3 files changed, 75 insertions(+), 9 deletions(-) diff --git a/channels/client/channels.c b/channels/client/channels.c index 87fc6c47d..e6038cf47 100644 --- a/channels/client/channels.c +++ b/channels/client/channels.c @@ -1277,6 +1277,32 @@ BOOL freerdp_channels_get_fds(rdpChannels* channels, freerdp* instance, void** r return TRUE; } +HANDLE freerdp_channels_get_event_handle(freerdp* instance) +{ + HANDLE event = NULL; + rdpChannels* channels; + + channels = instance->context->channels; + event = channels->signal; + + return event; +} + +int freerdp_channels_process_pending_messages(freerdp* instance) +{ + rdpChannels* channels; + + channels = instance->context->channels; + + if (WaitForSingleObject(channels->signal, 0) == WAIT_OBJECT_0) + { + ResetEvent(channels->signal); + freerdp_channels_process_sync(channels, instance); + } + + return TRUE; +} + /** * called only from main thread */ diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index 788399939..c47d56c6d 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -1110,6 +1110,28 @@ void* xf_input_thread(void* arg) return NULL; } +void* xf_channels_thread(void* arg) +{ + int status; + xfInfo* xfi; + HANDLE event; + rdpChannels* channels; + freerdp* instance = (freerdp*) arg; + + xfi = ((xfContext*) instance->context)->xfi; + + channels = instance->context->channels; + event = freerdp_channels_get_event_handle(instance); + + while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0) + { + status = freerdp_channels_process_pending_messages(instance); + xf_process_channel_event(channels, instance); + } + + return NULL; +} + /** Main loop for the rdp connection. * It will be run from the thread's entry point (thread_func()). * It initiates the connection, and will continue to run until the session ends, @@ -1136,8 +1158,10 @@ int xfreerdp_run(freerdp* instance) int select_status; BOOL async_update; BOOL async_input; + BOOL async_channels; HANDLE update_thread; HANDLE input_thread; + HANDLE channels_thread; rdpChannels* channels; rdpSettings* settings; struct timeval timeout; @@ -1184,6 +1208,13 @@ int xfreerdp_run(freerdp* instance) input_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_input_thread, instance, 0, NULL); } + async_channels = FALSE; + + if (async_channels) + { + channels_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_channels_thread, instance, 0, NULL); + } + while (!xfi->disconnect && !freerdp_shall_disconnect(instance)) { rcount = 0; @@ -1196,11 +1227,14 @@ int xfreerdp_run(freerdp* instance) break; } - if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE) + if (!async_channels) { - printf("Failed to get channel manager file descriptor\n"); - ret = XF_EXIT_CONN_FAILED; - break; + if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE) + { + printf("Failed to get channel manager file descriptor\n"); + ret = XF_EXIT_CONN_FAILED; + break; + } } if (!async_input) @@ -1260,13 +1294,16 @@ int xfreerdp_run(freerdp* instance) break; } - if (freerdp_channels_check_fds(channels, instance) != TRUE) + if (!async_channels) { - printf("Failed to check channel manager file descriptor\n"); - break; - } + if (freerdp_channels_check_fds(channels, instance) != TRUE) + { + printf("Failed to check channel manager file descriptor\n"); + break; + } - xf_process_channel_event(channels, instance); + xf_process_channel_event(channels, instance); + } if (!async_input) { diff --git a/include/freerdp/channels/channels.h b/include/freerdp/channels/channels.h index 88442fd68..bd03bc42f 100644 --- a/include/freerdp/channels/channels.h +++ b/include/freerdp/channels/channels.h @@ -48,6 +48,9 @@ FREERDP_API BOOL freerdp_channels_check_fds(rdpChannels* channels, freerdp* inst FREERDP_API RDP_EVENT* freerdp_channels_pop_event(rdpChannels* channels); FREERDP_API void freerdp_channels_close(rdpChannels* channels, freerdp* instance); +FREERDP_API HANDLE freerdp_channels_get_event_handle(freerdp* instance); +FREERDP_API int freerdp_channels_process_pending_messages(freerdp* instance); + #ifdef __cplusplus } #endif