transport/mfreerdp: fix async transport

- handle WAIT_TIMEOUT result as error in async transport thread
  if an INFINITE timeout was specified in WaitForMultipleObjects
- fix mfreerdp's async transport handling to not use
  freerdp_get_event_handles/freerdp_check_event_handles if async
  transport is activated
This commit is contained in:
Norbert Federa 2015-05-14 21:54:09 +02:00
parent 7220e34b5b
commit 51b697d4c8
2 changed files with 62 additions and 32 deletions

View File

@ -164,14 +164,14 @@ DWORD mac_client_thread(void* param)
@autoreleasepool
{
int status;
HANDLE events[4];
HANDLE events[16];
HANDLE inputEvent;
HANDLE inputThread = NULL;
HANDLE updateEvent;
HANDLE updateThread = NULL;
HANDLE channelsEvent;
DWORD nCount;
DWORD nCountTmp;
DWORD nCountBase;
rdpContext* context = (rdpContext*) param;
mfContext* mfc = (mfContext*) context;
freerdp* instance = context->instance;
@ -202,7 +202,12 @@ DWORD mac_client_thread(void* param)
}
else
{
events[nCount++] = updateEvent = freerdp_get_message_queue_event_handle(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
if (!(updateEvent = freerdp_get_message_queue_event_handle(instance, FREERDP_UPDATE_MESSAGE_QUEUE)))
{
WLog_ERR(TAG, "failed to get update event handle");
goto disconnect;
}
events[nCount++] = updateEvent;
}
if (settings->AsyncInput)
@ -215,20 +220,44 @@ DWORD mac_client_thread(void* param)
}
else
{
events[nCount++] = inputEvent = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
}
events[nCount++] = channelsEvent = freerdp_channels_get_event_handle(instance);
while (1)
{
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
if (WaitForSingleObject(mfc->stopEvent, 0) == WAIT_OBJECT_0)
if (!(inputEvent = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE)))
{
WLog_ERR(TAG, "failed to get input event handle");
goto disconnect;
}
events[nCount++] = inputEvent;
}
nCountBase = nCount;
while (!freerdp_shall_disconnect(instance))
{
nCount = nCountBase;
if (!settings->AsyncTransport)
{
if (!(nCountTmp = freerdp_get_event_handles(context, &events[nCount], 16 - nCount)))
{
WLog_ERR(TAG, "freerdp_get_event_handles failed");
break;
}
nCount += nCountTmp;
}
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
if (status >= (WAIT_OBJECT_0 + nCount))
{
WLog_ERR(TAG, "WaitForMultipleObjects failed (0x%08X)", status);
break;
}
if (status == WAIT_OBJECT_0)
{
/* stop event triggered */
break;
}
if (!settings->AsyncUpdate)
{
if (WaitForSingleObject(updateEvent, 0) == WAIT_OBJECT_0)
@ -236,7 +265,7 @@ DWORD mac_client_thread(void* param)
update_activity_cb(instance);
}
}
if (!settings->AsyncInput)
{
if (WaitForSingleObject(inputEvent, 0) == WAIT_OBJECT_0)
@ -244,13 +273,17 @@ DWORD mac_client_thread(void* param)
input_activity_cb(instance);
}
}
if (WaitForSingleObject(channelsEvent, 0) == WAIT_OBJECT_0)
if (!settings->AsyncTransport)
{
freerdp_channels_process_pending_messages(instance);
if (!freerdp_check_event_handles(context))
{
WLog_ERR(TAG, "freerdp_check_event_handles failed");
break;
}
}
}
disconnect:
freerdp_disconnect(instance);
@ -265,7 +298,7 @@ disconnect:
}
CloseHandle(updateThread);
}
if (settings->AsyncInput && inputThread)
{
wMessageQueue* inputQueue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE);
@ -276,7 +309,7 @@ disconnect:
}
CloseHandle(inputThread);
}
ExitThread(0);
return 0;
}

View File

@ -876,6 +876,7 @@ static void* transport_client_thread(void* arg)
DWORD dwExitCode = 0;
DWORD status;
DWORD nCount;
DWORD nCountTmp;
HANDLE handles[64];
rdpTransport* transport = (rdpTransport*) arg;
rdpContext* context = transport->context;
@ -907,14 +908,14 @@ static void* transport_client_thread(void* arg)
while (1)
{
handles[0] = transport->stopEvent;
nCount = 1; /* transport->stopEvent */
if (!(nCount = freerdp_get_event_handles(context, &handles[1], 63)))
if (!(nCountTmp = freerdp_get_event_handles(context, &handles[nCount], 64 - nCount)))
{
WLog_ERR(TAG, "freerdp_get_event_handles failed");
break;
}
nCount++;
nCount += nCountTmp;
status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
@ -940,13 +941,9 @@ static void* transport_client_thread(void* arg)
else
{
if (status == WAIT_TIMEOUT)
{
/* This happens quite frequently although we've specified an INFINITE timeout
* WaitForMultipleObjects bug ?
*/
continue;
}
WLog_ERR(TAG, "WaitForMultipleObjects failed with status 0x%08X", status);
WLog_ERR(TAG, "WaitForMultipleObjects returned WAIT_TIMEOUT");
else
WLog_ERR(TAG, "WaitForMultipleObjects returned 0x%08X", status);
dwExitCode = 1;
break;
}