freerdp: add event handle usage instead of file descriptors

This commit is contained in:
Marc-André Moreau 2015-01-29 22:57:58 -05:00
parent ef71181897
commit 3a906caa4a
7 changed files with 67 additions and 161 deletions

View File

@ -506,7 +506,7 @@ BOOL wf_authenticate(freerdp* instance, char** username, char** password, char**
if (status != NO_ERROR)
{
WLog_ERR(TAG, "CredUIPromptForCredentials unexpected status: 0x%08X", status);
WLog_ERR(TAG, "CredUIPromptForCredentials unexpected status: 0x%08X", status);
return FALSE;
}
@ -514,7 +514,7 @@ BOOL wf_authenticate(freerdp* instance, char** username, char** password, char**
ZeroMemory(Domain, sizeof(Domain));
status = CredUIParseUserNameA(UserName, User, sizeof(User), Domain, sizeof(Domain));
//WLog_ERR(TAG, "User: %s Domain: %s Password: %s", User, Domain, Password);
//WLog_ERR(TAG, "User: %s Domain: %s Password: %s", User, Domain, Password);
*username = _strdup(User);
if (strlen(Domain) > 0)
@ -554,21 +554,6 @@ BOOL wf_verify_certificate(freerdp* instance, char* subject, char* issuer, char*
return TRUE;
}
int wf_receive_channel_data(freerdp* instance, UINT16 channelId, BYTE* data, int size, int flags, int total_size)
{
return freerdp_channels_data(instance, channelId, data, size, flags, total_size);
}
BOOL wf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount)
{
return TRUE;
}
BOOL wf_check_fds(freerdp* instance)
{
return TRUE;
}
static BOOL wf_auto_reconnect(freerdp* instance)
{
wfContext* wfc = (wfContext *)instance->context;
@ -581,7 +566,7 @@ static BOOL wf_auto_reconnect(freerdp* instance)
return FALSE;
/* A network disconnect was detected */
WLog_ERR(TAG, "Network disconnect!");
WLog_ERR(TAG, "Network disconnect!");
if (!instance->settings->AutoReconnectionEnabled)
{
@ -607,7 +592,7 @@ static BOOL wf_auto_reconnect(freerdp* instance)
Sleep(5000);
}
WLog_ERR(TAG, "Maximum reconnect retries exceeded");
WLog_ERR(TAG, "Maximum reconnect retries exceeded");
return FALSE;
}
@ -621,8 +606,7 @@ void* wf_input_thread(void* arg)
assert( NULL != instance);
status = 1;
queue = freerdp_get_message_queue(instance,
FREERDP_INPUT_MESSAGE_QUEUE);
queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE);
while (MessageQueue_Wait(queue))
{
@ -644,70 +628,36 @@ void* wf_input_thread(void* arg)
return NULL;
}
void* wf_channels_thread(void* arg)
{
int status;
HANDLE event;
rdpChannels* channels;
freerdp* instance = (freerdp*) arg;
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;
}
ExitThread(0);
return NULL;
}
DWORD WINAPI wf_client_thread(LPVOID lpParam)
{
MSG msg;
int index;
int rcount;
int wcount;
int width;
int height;
BOOL msg_ret;
int quit_msg;
void* rfds[32];
void* wfds[32];
int fds_count;
HANDLE fds[64];
DWORD nCount;
HANDLE handles[64];
wfContext* wfc;
freerdp* instance;
rdpContext* context;
rdpChannels* channels;
rdpSettings* settings;
BOOL async_input;
BOOL async_channels;
BOOL async_transport;
HANDLE input_thread;
HANDLE channels_thread;
instance = (freerdp*) lpParam;
assert(NULL != instance);
context = instance->context;
wfc = (wfContext*) instance->context;
assert(NULL != wfc);
ZeroMemory(rfds, sizeof(rfds));
ZeroMemory(wfds, sizeof(wfds));
if (freerdp_connect(instance) != TRUE)
if (!freerdp_connect(instance))
return 0;
channels = instance->context->channels;
settings = instance->context->settings;
async_input = settings->AsyncInput;
async_channels = settings->AsyncChannels;
async_transport = settings->AsyncTransport;
if (async_input)
@ -717,15 +667,9 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
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;
nCount = 0;
if (freerdp_focus_required(instance))
{
@ -735,80 +679,29 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
if (!async_transport)
{
if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
WLog_ERR(TAG, "Failed to get FreeRDP file descriptor");
break;
}
}
if (wf_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
WLog_ERR(TAG, "Failed to get wfreerdp file descriptor");
break;
nCount += freerdp_get_event_handles(context, &handles[nCount]);
}
if (!async_channels)
if (MsgWaitForMultipleObjects(nCount, handles, FALSE, 1000, QS_ALLINPUT) == WAIT_FAILED)
{
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
WLog_ERR(TAG, "Failed to get channel manager file descriptor");
break;
}
}
fds_count = 0;
/* setup read fds */
for (index = 0; index < rcount; index++)
{
fds[fds_count++] = rfds[index];
}
/* setup write fds */
for (index = 0; index < wcount; index++)
{
fds[fds_count++] = wfds[index];
}
/* exit if nothing to do */
if (fds_count == 0)
{
WLog_ERR(TAG, "wfreerdp_run: fds_count is zero");
//break;
}
/* do the wait */
if (MsgWaitForMultipleObjects(fds_count, fds, FALSE, 1000, QS_ALLINPUT) == WAIT_FAILED)
{
WLog_ERR(TAG, "wfreerdp_run: WaitForMultipleObjects failed: 0x%04X", GetLastError());
WLog_ERR(TAG, "wfreerdp_run: WaitForMultipleObjects failed: 0x%04X", GetLastError());
break;
}
if (!async_transport)
{
if (freerdp_check_fds(instance) != TRUE)
if (!freerdp_check_event_handles(context))
{
if (wf_auto_reconnect(instance))
continue;
WLog_ERR(TAG, "Failed to check FreeRDP file descriptor");
WLog_ERR(TAG, "Failed to check FreeRDP file descriptor");
break;
}
}
if (freerdp_shall_disconnect(instance))
{
break;
}
if (wf_check_fds(instance) != TRUE)
{
WLog_ERR(TAG, "Failed to check wfreerdp file descriptor");
break;
}
if (!async_channels)
{
if (freerdp_channels_check_fds(channels, instance) != TRUE)
{
WLog_ERR(TAG, "Failed to check channel manager file descriptor");
break;
}
}
if (freerdp_shall_disconnect(instance))
break;
quit_msg = FALSE;
@ -833,9 +726,6 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
width = LOWORD(msg.lParam);
height = HIWORD(msg.lParam);
//wfc->client_width = width;
//wfc->client_height = height;
SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
}
@ -851,6 +741,8 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
if (quit_msg)
break;
Sleep(100);
}
/* cleanup */
@ -859,24 +751,16 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
if (async_input)
{
wMessageQueue* input_queue;
input_queue = freerdp_get_message_queue(instance,
FREERDP_INPUT_MESSAGE_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);
WLog_DBG(TAG, "Main thread exited.");
ExitThread(0);
return 0;
}
@ -898,7 +782,7 @@ DWORD WINAPI wf_keyboard_thread(LPVOID lpParam)
{
if (status == -1)
{
WLog_ERR(TAG, "keyboard thread error getting message");
WLog_ERR(TAG, "keyboard thread error getting message");
break;
}
else
@ -912,7 +796,7 @@ DWORD WINAPI wf_keyboard_thread(LPVOID lpParam)
}
else
{
WLog_ERR(TAG, "failed to install keyboard hook");
WLog_ERR(TAG, "failed to install keyboard hook");
}
WLog_DBG(TAG, "Keyboard thread exited.");
@ -1123,7 +1007,6 @@ int wfreerdp_client_new(freerdp* instance, rdpContext* context)
instance->PostConnect = wf_post_connect;
instance->Authenticate = wf_authenticate;
instance->VerifyCertificate = wf_verify_certificate;
instance->ReceiveChannelData = wf_receive_channel_data;
wfc->instance = instance;
wfc->settings = instance->settings;
@ -1134,7 +1017,7 @@ int wfreerdp_client_new(freerdp* instance, rdpContext* context)
void wfreerdp_client_free(freerdp* instance, rdpContext* context)
{
rdpChannels *channels = context->channels;
rdpChannels* channels = context->channels;
if (context->cache)
cache_free(context->cache);

View File

@ -248,6 +248,9 @@ FREERDP_API BOOL freerdp_reconnect(freerdp* instance);
FREERDP_API BOOL freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount);
FREERDP_API BOOL freerdp_check_fds(freerdp* instance);
FREERDP_API DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events);
FREERDP_API BOOL freerdp_check_event_handles(rdpContext* context);
FREERDP_API wMessageQueue* freerdp_get_message_queue(freerdp* instance, DWORD id);
FREERDP_API HANDLE freerdp_get_message_queue_event_handle(freerdp* instance, DWORD id);
FREERDP_API int freerdp_message_queue_process_message(freerdp* instance, DWORD id, wMessage* message);

View File

@ -241,6 +241,16 @@ BOOL freerdp_check_fds(freerdp* instance)
return TRUE;
}
DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events)
{
return transport_get_event_handles(context->rdp->transport, events);
}
BOOL freerdp_check_event_handles(rdpContext* context)
{
return freerdp_check_fds(context->instance);
}
wMessageQueue* freerdp_get_message_queue(freerdp* instance, DWORD id)
{
wMessageQueue* queue = NULL;

View File

@ -866,28 +866,36 @@ void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount)
}
}
void transport_get_read_handles(rdpTransport* transport, HANDLE* events, DWORD* count)
DWORD transport_get_event_handles(rdpTransport* transport, HANDLE* events)
{
events[*count] = freerdp_tcp_get_event_handle(transport->TcpIn);
(*count)++;
DWORD nCount = 0;
if (events)
events[nCount] = freerdp_tcp_get_event_handle(transport->TcpIn);
nCount++;
if (transport->SplitInputOutput)
{
events[*count] = freerdp_tcp_get_event_handle(transport->TcpOut);
(*count)++;
if (events)
events[nCount] = freerdp_tcp_get_event_handle(transport->TcpOut);
nCount++;
}
if (transport->ReceiveEvent)
{
events[*count] = transport->ReceiveEvent;
(*count)++;
if (events)
events[nCount] = transport->ReceiveEvent;
nCount++;
}
if (transport->GatewayEvent)
{
events[*count] = transport->GatewayEvent;
(*count)++;
if (events)
events[nCount] = transport->GatewayEvent;
nCount++;
}
return nCount;
}
BOOL tranport_is_write_blocked(rdpTransport* transport)
@ -1049,7 +1057,8 @@ static void* transport_client_thread(void* arg)
{
nCount = 0;
handles[nCount++] = transport->stopEvent;
transport_get_read_handles(transport, (HANDLE*) &handles, &nCount);
nCount += transport_get_event_handles(transport, &handles[nCount]);
status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
if (transport->layer == TRANSPORT_LAYER_CLOSED)
@ -1058,14 +1067,12 @@ static void* transport_client_thread(void* arg)
rdp_set_error_info(rdp, ERRINFO_PEER_DISCONNECTED);
break;
}
else if (status != WAIT_TIMEOUT)
{
if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
break;
if (!freerdp_check_fds(instance))
{
}
if (!freerdp_check_fds(instance))
{
}
}

View File

@ -98,12 +98,15 @@ BOOL transport_accept_nla(rdpTransport* transport);
void transport_stop(rdpTransport* transport);
int transport_read_pdu(rdpTransport* transport, wStream* s);
int transport_write(rdpTransport* transport, wStream* s);
void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount);
int transport_check_fds(rdpTransport* transport);
DWORD transport_get_event_handles(rdpTransport* transport, HANDLE* events);
BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking);
void transport_set_gateway_enabled(rdpTransport* transport, BOOL GatewayEnabled);
void transport_set_nla_mode(rdpTransport* transport, BOOL NlaMode);
void transport_get_read_handles(rdpTransport* transport, HANDLE* events, DWORD* count);
BOOL tranport_is_write_blocked(rdpTransport* transport);
int tranport_drain_output_buffer(rdpTransport* transport);

View File

@ -187,6 +187,8 @@ WINPR_API BOOL WaitOnAddress(VOID volatile *Address, PVOID CompareAddress, SIZE_
#define WAIT_FAILED ((DWORD) 0xFFFFFFFF)
#define MAXIMUM_WAIT_OBJECTS 64
WINPR_API DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
WINPR_API DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertable);
WINPR_API DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds);

View File

@ -412,8 +412,6 @@ DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertabl
return WAIT_OBJECT_0;
}
#define MAXIMUM_WAIT_OBJECTS 64
DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE *lpHandles, BOOL bWaitAll, DWORD dwMilliseconds)
{
struct timespec starttime;