Merge pull request #1853 from zhangzl2013/async

wfreerdp: add async input, update, transport and channels' events
This commit is contained in:
Marc-André Moreau 2014-05-21 11:01:53 -04:00
commit 422a279682
1 changed files with 185 additions and 18 deletions

View File

@ -621,6 +621,96 @@ static BOOL wf_auto_reconnect(freerdp* instance)
return FALSE;
}
void* wf_input_thread(void* arg)
{
int status;
wMessage message;
wMessageQueue* queue;
freerdp* instance = (freerdp*) arg;
assert( NULL != instance);
status = 1;
queue = freerdp_get_message_queue(instance,
FREERDP_INPUT_MESSAGE_QUEUE);
while (MessageQueue_Wait(queue))
{
while (MessageQueue_Peek(queue, &message, TRUE))
{
status = freerdp_message_queue_process_message(instance,
FREERDP_INPUT_MESSAGE_QUEUE, &message);
if (!status)
break;
}
if (!status)
break;
}
ExitThread(0);
return NULL;
}
void* wf_update_thread(void* arg)
{
int status;
wMessage message;
wMessageQueue* queue;
freerdp* instance = (freerdp*) arg;
assert( NULL != instance);
status = 1;
queue = freerdp_get_message_queue(instance,
FREERDP_UPDATE_MESSAGE_QUEUE);
while (MessageQueue_Wait(queue))
{
while (MessageQueue_Peek(queue, &message, TRUE))
{
status = freerdp_message_queue_process_message(instance,
FREERDP_UPDATE_MESSAGE_QUEUE, &message);
if (!status)
break;
}
if (!status)
break;
}
ExitThread(0);
return NULL;
}
void* wf_channels_thread(void* arg)
{
int status;
HANDLE event;
rdpChannels* channels;
freerdp* instance = (freerdp*) arg;
assert(NULL != instance);
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);
if (!status)
break;
wf_process_channel_event(channels, instance);
}
ExitThread(0);
return NULL;
}
DWORD WINAPI wf_client_thread(LPVOID lpParam)
{
MSG msg;
@ -638,6 +728,15 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
wfContext* wfc;
freerdp* instance;
rdpChannels* channels;
rdpSettings* settings;
BOOL async_update;
BOOL async_input;
BOOL async_channels;
BOOL async_transport;
HANDLE update_thread;
HANDLE input_thread;
HANDLE channels_thread;
instance = (freerdp*) lpParam;
assert(NULL != instance);
@ -652,28 +751,59 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
return 0;
channels = instance->context->channels;
settings = instance->context->settings;
async_update = settings->AsyncUpdate;
async_input = settings->AsyncInput;
async_channels = settings->AsyncChannels;
async_transport = settings->AsyncTransport;
if (async_update)
{
update_thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) wf_update_thread,
instance, 0, NULL);
}
if (async_input)
{
input_thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) wf_input_thread,
instance, 0, NULL);
}
if (async_channels)
{
channels_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) wf_channels_thread, instance, 0, NULL);
}
while (1)
{
rcount = 0;
wcount = 0;
if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
if (!async_transport)
{
fprintf(stderr, "Failed to get FreeRDP file descriptor\n");
break;
if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
fprintf(stderr, "Failed to get FreeRDP file descriptor\n");
break;
}
}
if (wf_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
fprintf(stderr, "Failed to get wfreerdp file descriptor\n");
break;
}
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
fprintf(stderr, "Failed to get channel manager file descriptor\n");
break;
}
if (!async_channels)
{
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
fprintf(stderr, "Failed to get channel manager file descriptor\n");
break;
}
}
fds_count = 0;
/* setup read fds */
for (index = 0; index < rcount; index++)
@ -689,7 +819,7 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
if (fds_count == 0)
{
fprintf(stderr, "wfreerdp_run: fds_count is zero\n");
break;
//break;
}
/* do the wait */
@ -699,13 +829,16 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
break;
}
if (freerdp_check_fds(instance) != TRUE)
if (!async_transport)
{
if (wf_auto_reconnect(instance))
continue;
if (freerdp_check_fds(instance) != TRUE)
{
if (wf_auto_reconnect(instance))
continue;
fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
break;
fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
break;
}
}
if (freerdp_shall_disconnect(instance))
{
@ -716,12 +849,17 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
fprintf(stderr, "Failed to check wfreerdp file descriptor\n");
break;
}
if (freerdp_channels_check_fds(channels, instance) != TRUE)
if (!async_channels)
{
fprintf(stderr, "Failed to check channel manager file descriptor\n");
break;
if (freerdp_channels_check_fds(channels, instance) != TRUE)
{
fprintf(stderr, "Failed to check channel manager file descriptor\n");
break;
}
wf_process_channel_event(channels, instance);
}
wf_process_channel_event(channels, instance);
quit_msg = FALSE;
@ -768,6 +906,35 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
/* cleanup */
freerdp_channels_close(channels, instance);
if (async_update)
{
wMessageQueue* update_queue;
update_queue = freerdp_get_message_queue(instance,
FREERDP_UPDATE_MESSAGE_QUEUE);
MessageQueue_PostQuit(update_queue, 0);
WaitForSingleObject(update_thread, INFINITE);
CloseHandle(update_thread);
}
if (async_input)
{
wMessageQueue* input_queue;
input_queue = freerdp_get_message_queue(instance,
FREERDP_INPUT_MESSAGE_QUEUE);
MessageQueue_PostQuit(input_queue, 0);
WaitForSingleObject(input_thread, INFINITE);
CloseHandle(input_thread);
}
if (async_channels)
{
WaitForSingleObject(channels_thread, INFINITE);
CloseHandle(channels_thread);
}
freerdp_disconnect(instance);
printf("Main thread exited.\n");