Ejemplo n.º 1
0
DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events,
                                DWORD count)
{
	DWORD nCount = 0;
	nCount += transport_get_event_handles(context->rdp->transport, events, count);

	if (nCount == 0)
		return 0;

	if (events && (nCount < count + 2))
	{
		events[nCount++] = freerdp_channels_get_event_handle(context->instance);
		events[nCount++] = getChannelErrorEventHandle(context);
		events[nCount++] = context->abortEvent;
	}
	else
		return 0;

	if (context->settings->AsyncInput)
	{
		if (nCount >= count)
			return 0;

		events[nCount++] = freerdp_get_message_queue_event_handle(
		                       context->instance, FREERDP_INPUT_MESSAGE_QUEUE);
	}

	return nCount;
}
Ejemplo n.º 2
0
static void* jni_input_thread(void* arg)
{
	HANDLE event[3];
	wMessageQueue* queue;
	freerdp* instance = (freerdp*) arg;
	androidContext *aCtx = (androidContext*)instance->context;
	
	assert(NULL != instance);
	assert(NULL != aCtx);
														  
	DEBUG_ANDROID("input_thread Start.");

	if (!(queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE)))
		goto fail_get_message_queue;

	if (!(event[0] = CreateFileDescriptorEvent(NULL, FALSE, FALSE,
				aCtx->event_queue->pipe_fd[0], WINPR_FD_READ)))
		goto fail_create_event_0;

	if (!(event[1] = CreateFileDescriptorEvent(NULL, FALSE, FALSE,
				aCtx->event_queue->pipe_fd[1], WINPR_FD_READ)))
		goto fail_create_event_1;

	if (!(event[2] = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE)))
		goto fail_get_message_queue_event;
			
	do
	{
		DWORD rc = WaitForMultipleObjects(3, event, FALSE, INFINITE);
		if ((rc < WAIT_OBJECT_0) || (rc > WAIT_OBJECT_0 + 2))
			continue;
	
		if (rc == WAIT_OBJECT_0 + 2)
		{
			wMessage msg;

			MessageQueue_Peek(queue, &msg, FALSE);
			if (msg.id == WMQ_QUIT)
				break;
		}
		if (android_check_fds(instance) != TRUE)
			break;
	}
	while(1);

	DEBUG_ANDROID("input_thread Quit.");

fail_get_message_queue_event:
	CloseHandle(event[1]);
fail_create_event_1:
	CloseHandle(event[0]);
fail_create_event_0:
	MessageQueue_PostQuit(queue, 0);
fail_get_message_queue:

	ExitThread(0);
	return NULL;
}
Ejemplo n.º 3
0
static void* jni_input_thread(void* arg)
{
	HANDLE event[2];
	wMessageQueue* queue;
	freerdp* instance = (freerdp*) arg;
	WLog_DBG(TAG, "input_thread Start.");

	if (!(queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE)))
		goto disconnect;

	if (!(event[0] = android_get_handle(instance)))
		goto disconnect;

	if (!(event[1] = freerdp_get_message_queue_event_handle(instance,
	                 FREERDP_INPUT_MESSAGE_QUEUE)))
		goto disconnect;

	do
	{
		DWORD rc = WaitForMultipleObjects(2, event, FALSE, INFINITE);

		if ((rc < WAIT_OBJECT_0) || (rc > WAIT_OBJECT_0 + 1))
			continue;

		if (rc == WAIT_OBJECT_0 + 1)
		{
			wMessage msg;
			MessageQueue_Peek(queue, &msg, FALSE);

			if (msg.id == WMQ_QUIT)
				break;
		}

		if (android_check_handle(instance) != TRUE)
			break;
	}
	while (1);

	WLog_DBG(TAG, "input_thread Quit.");
disconnect:
	MessageQueue_PostQuit(queue, 0);
	ExitThread(0);
	return NULL;
}
Ejemplo n.º 4
0
static int android_freerdp_run(freerdp* instance)
{
	int i;
	int fds;
	int max_fds;
	int rcount;
	int wcount;
	int fd_input_event;
	HANDLE input_event = NULL;
	void* rfds[32];
	void* wfds[32];
	fd_set rfds_set;
	fd_set wfds_set;
	int select_status;
	struct timeval timeout;

	const rdpSettings* settings = instance->context->settings;

	HANDLE input_thread = NULL;
	HANDLE channels_thread = NULL;
	
	BOOL async_input = settings->AsyncInput;
	BOOL async_channels = settings->AsyncChannels;
	BOOL async_transport = settings->AsyncTransport;

	DEBUG_ANDROID("AsyncUpdate=%d", settings->AsyncUpdate);
	DEBUG_ANDROID("AsyncInput=%d", settings->AsyncInput);
	DEBUG_ANDROID("AsyncChannels=%d", settings->AsyncChannels);
	DEBUG_ANDROID("AsyncTransport=%d", settings->AsyncTransport);

	memset(rfds, 0, sizeof(rfds));
	memset(wfds, 0, sizeof(wfds));

	if (!freerdp_connect(instance))
	{
		freerdp_callback("OnConnectionFailure", "(I)V", instance);
		return 0;
	}

	if (async_input)
	{
		if (!(input_thread = CreateThread(NULL, 0,
				(LPTHREAD_START_ROUTINE) jni_input_thread, instance, 0, NULL)))
		{
			DEBUG_ANDROID("Failed to create async input thread\n");
			goto disconnect;
		}
	}
	      
	if (async_channels)
	{
		if (!(channels_thread = CreateThread(NULL, 0,
				(LPTHREAD_START_ROUTINE) jni_channels_thread, instance, 0, NULL)))
		{
			DEBUG_ANDROID("Failed to create async channels thread\n");
			goto disconnect;
		}
	}

	((androidContext*)instance->context)->is_connected = TRUE;
	while (!freerdp_shall_disconnect(instance))
	{
		rcount = 0;
		wcount = 0;

		if (!async_transport)
		{
			if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
			{
				DEBUG_ANDROID("Failed to get FreeRDP file descriptor\n");
				break;
			}
		}

		if (!async_channels)
		{
			if (freerdp_channels_get_fds(instance->context->channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
			{
				DEBUG_ANDROID("Failed to get channel manager file descriptor\n");
				break;
			}
		}

		if (!async_input)
		{
			if (android_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
			{
				DEBUG_ANDROID("Failed to get android file descriptor\n");
				break;
			}
		}
		else
		{
			input_event = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
			fd_input_event = GetEventFileDescriptor(input_event);
			rfds[rcount++] = (void*) (long) fd_input_event;
		}

		max_fds = 0;
		FD_ZERO(&rfds_set);
		FD_ZERO(&wfds_set);

		for (i = 0; i < rcount; i++)
		{
			fds = (int)(long)(rfds[i]);

			if (fds > max_fds)
				max_fds = fds;

			FD_SET(fds, &rfds_set);
		}

		if (max_fds == 0)
			break;

		timeout.tv_sec = 1;
		timeout.tv_usec = 0;

		select_status = select(max_fds + 1, &rfds_set, NULL, NULL, &timeout);

		if (select_status == 0)
			continue;
		else if (select_status == -1)
		{
			/* these are not really errors */
			if (!((errno == EAGAIN) ||
				(errno == EWOULDBLOCK) ||
				(errno == EINPROGRESS) ||
				(errno == EINTR))) /* signal occurred */
			{
				DEBUG_ANDROID("android_run: select failed\n");
				break;
			}
		}
		
		if (freerdp_shall_disconnect(instance))
			break;

		if (!async_transport)
		{
			if (freerdp_check_fds(instance) != TRUE)
			{
				DEBUG_ANDROID("Failed to check FreeRDP file descriptor\n");
				break;
			}
		}

		if (!async_input)
		{
			if (android_check_fds(instance) != TRUE)
			{
				DEBUG_ANDROID("Failed to check android file descriptor\n");
				break;
			}
		}
		else if (input_event)
		{
			if (WaitForSingleObject(input_event, 0) == WAIT_OBJECT_0)
			{
				if (!freerdp_message_queue_process_pending_messages(instance,
							FREERDP_INPUT_MESSAGE_QUEUE))
				{
					DEBUG_ANDROID("User Disconnect");
					break;
				}
			}
		}

		if (!async_channels)
		{
			if (freerdp_channels_check_fds(instance->context->channels, instance) != TRUE)
			{
				DEBUG_ANDROID("Failed to check channel manager file descriptor\n");
				break;
			}
		}
	}

disconnect:
	DEBUG_ANDROID("Prepare shutdown...");

	// issue another OnDisconnecting here in case the disconnect was initiated by the server and not our client
	freerdp_callback("OnDisconnecting", "(I)V", instance);
	
	DEBUG_ANDROID("Close channels...");
	freerdp_channels_disconnect(instance->context->channels, instance);

	DEBUG_ANDROID("Cleanup threads...");

	if (async_channels && channels_thread)
	{
		WaitForSingleObject(channels_thread, INFINITE);
		CloseHandle(channels_thread);
	}
 
	if (async_input && input_thread)
	{
		wMessageQueue* input_queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE);
		if (input_queue)
		{
			if (MessageQueue_PostQuit(input_queue, 0))
				WaitForSingleObject(input_thread, INFINITE);
		}
		CloseHandle(input_thread);
	}

	DEBUG_ANDROID("run Disconnecting...");
	freerdp_disconnect(instance);
	freerdp_callback("OnDisconnected", "(I)V", instance);

	DEBUG_ANDROID("run Quit.");

	return 0;
}