Exemple #1
0
static void pbrpc_main_loop(pbRPCContext* context)
{
	int status;
	DWORD nCount;
	HANDLE events[32];
	rdsServer* server = g_Server;

	pbrpc_connect(context);

	while (context->isConnected)
	{
		nCount = 0;
		events[nCount++] = context->stopEvent;
		events[nCount++] = Queue_Event(context->writeQueue);
		events[nCount++] = context->hPipe;

		status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);

		if (status == WAIT_FAILED)
		{
			break;
		}

		if (WaitForSingleObject(context->stopEvent, 0) == WAIT_OBJECT_0)
		{
			break;
		}

		if (WaitForSingleObject(context->hPipe, 0) == WAIT_OBJECT_0)
		{
			status = pbrpc_process_message_in(server);

			if (status < 0)
			{
				fprintf(stderr, "Transport problem reconnecting..\n");
				pbrpc_reconnect(context);
				continue;
			}
		}

		if (WaitForSingleObject(Queue_Event(context->writeQueue), 0) == WAIT_OBJECT_0)
		{
			FDSAPI_MSG_PACKET* msg = NULL;

			while ((msg = Queue_Dequeue(context->writeQueue)))
			{
				status = pbrpc_process_message_out(server, msg);
				pbrpc_message_free(msg, FALSE);
			}

			if (status < 0)
			{
				fprintf(stderr, "Transport problem reconnecting..\n");
				pbrpc_reconnect(context);
				continue;
			}
		}
	}
}
Exemple #2
0
static void* rpc_client_thread(void* arg)
{
	rdpRpc* rpc;
	DWORD status;
	DWORD nCount;
	HANDLE events[3];
	HANDLE ReadEvent;
	int fd;
	rpc = (rdpRpc*) arg;
	fd = BIO_get_fd(rpc->TlsOut->bio, NULL);
	ReadEvent = CreateFileDescriptorEvent(NULL, TRUE, FALSE, fd);
	nCount = 0;
	events[nCount++] = rpc->client->StopEvent;
	events[nCount++] = Queue_Event(rpc->client->SendQueue);
	events[nCount++] = ReadEvent;

	/* Do a first free run in case some bytes were set from the HTTP headers.
	 * We also have to do it because most of the time the underlying socket has notified,
	 * and the ssl layer has eaten all bytes, so we won't be notified any more even if the
	 * bytes are buffered locally
	 */
	if (rpc_client_on_read_event(rpc) < 0)
	{
		WLog_ERR(TAG, "an error occured when treating first packet");
		goto out;
	}

	while (rpc->transport->layer != TRANSPORT_LAYER_CLOSED)
	{
		status = WaitForMultipleObjects(nCount, events, FALSE, 100);

		if (status == WAIT_TIMEOUT)
			continue;

		if (WaitForSingleObject(rpc->client->StopEvent, 0) == WAIT_OBJECT_0)
			break;

		if (WaitForSingleObject(ReadEvent, 0) == WAIT_OBJECT_0)
		{
			if (rpc_client_on_read_event(rpc) < 0)
				break;
		}

		if (WaitForSingleObject(Queue_Event(rpc->client->SendQueue), 0) == WAIT_OBJECT_0)
		{
			rpc_send_dequeue_pdu(rpc);
		}
	}

out:
	CloseHandle(ReadEvent);
	return NULL;
}
Exemple #3
0
RPC_PDU* rpc_recv_dequeue_pdu(rdpRpc* rpc)
{
	RPC_PDU* pdu;
	DWORD dwMilliseconds;
	DWORD result;
	dwMilliseconds = rpc->client->SynchronousReceive ? SYNCHRONOUS_TIMEOUT * 4 : 0;
	result = WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds);

	if (result == WAIT_TIMEOUT)
	{
		WLog_ERR(TAG, "timed out waiting for receive event");
		return NULL;
	}

	if (result != WAIT_OBJECT_0)
		return NULL;

	pdu = (RPC_PDU*)Queue_Dequeue(rpc->client->ReceiveQueue);
#ifdef WITH_DEBUG_TSG

	if (pdu)
	{
		WLog_DBG(TAG, "Receiving PDU (length: %d, CallId: %d)", pdu->s->length, pdu->CallId);
		winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(pdu->s), Stream_Length(pdu->s));
	}
	else
	{
		WLog_DBG(TAG, "Receiving a NULL PDU");
	}

#endif
	return pdu;
}
Exemple #4
0
static void* serial_thread_func(void* arg)
{
	IRP* irp;
	DWORD status;
	SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg;
	HANDLE ev[] = {serial->stopEvent, Queue_Event(serial->queue)};

	while (1)
	{
		status = WaitForMultipleObjects(2, ev, FALSE, 1);

		if (WAIT_OBJECT_0 == status)
			break;

		serial->nfds = 1;
		FD_ZERO(&serial->read_fds);
		FD_ZERO(&serial->write_fds);

		serial->tv.tv_sec = 0;
		serial->tv.tv_usec = 0;
		serial->select_timeout = 0;

		if (status == WAIT_OBJECT_0 + 1)
		{
			if ((irp = (IRP*) Queue_Dequeue(serial->queue)))
				serial_process_irp(serial, irp);
			continue;
		}

		serial_check_fds(serial);
	}

	return NULL;
}
Exemple #5
0
RPC_PDU* rpc_recv_dequeue_pdu(rdpRpc* rpc)
{
	RPC_PDU* pdu;
	DWORD dwMilliseconds;

	pdu = NULL;
	dwMilliseconds = rpc->client->SynchronousReceive ? INFINITE : 0;

	if (WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds) == WAIT_OBJECT_0)
	{
		pdu = (RPC_PDU*) Queue_Dequeue(rpc->client->ReceiveQueue);

#ifdef WITH_DEBUG_TSG
		if (pdu)
		{
			fprintf(stderr, "Receiving PDU (length: %d, CallId: %d)\n", pdu->s->length, pdu->CallId);
			winpr_HexDump(Stream_Buffer(pdu->s), Stream_Length(pdu->s));
			fprintf(stderr, "\n");
		}
#endif

		return pdu;
	}

	return pdu;
}
Exemple #6
0
RPC_PDU* rpc_client_receive_pool_take(rdpRpc* rpc)
{
	RPC_PDU* pdu = NULL;

	if (WaitForSingleObject(Queue_Event(rpc->client->ReceivePool), 0) == WAIT_OBJECT_0)
		pdu = Queue_Dequeue(rpc->client->ReceivePool);

	if (!pdu)
	{
		pdu = (RPC_PDU*)malloc(sizeof(RPC_PDU));

		if (!pdu)
			return NULL;

		pdu->s = Stream_New(NULL, rpc->max_recv_frag);

		if (!pdu->s)
		{
			free(pdu);
			return NULL;
		}
	}

	pdu->CallId = 0;
	pdu->Flags = 0;
	Stream_Length(pdu->s) = 0;
	Stream_SetPosition(pdu->s, 0);
	return pdu;
}
Exemple #7
0
static void* tsmf_stream_ack_func(void *arg)
{
	HANDLE hdl[2];
	TSMF_STREAM* stream = (TSMF_STREAM*) arg;
	DEBUG_TSMF("in %d", stream->stream_id);

	hdl[0] = stream->stopEvent;
	hdl[1] = Queue_Event(stream->sample_ack_list);

	while (1)
	{
		DWORD ev = WaitForMultipleObjects(2, hdl, FALSE, INFINITE);

		if (ev == WAIT_OBJECT_0)
			break;

		if (!stream->decoder)
			continue;

		if (stream->decoder->SetAckFunc)
			continue;

		if (tsmf_stream_process_ack(stream, FALSE))
			break;
	}

	DEBUG_TSMF("out %d", stream->stream_id);
	ExitThread(0);
	return NULL;
}
Exemple #8
0
BOOL tsg_set_blocking_mode(rdpTsg* tsg, BOOL blocking)
{
	tsg->rpc->client->SynchronousSend = TRUE;
	tsg->rpc->client->SynchronousReceive = blocking;

	tsg->transport->GatewayEvent = Queue_Event(tsg->rpc->client->ReceiveQueue);

	return TRUE;
}
Exemple #9
0
static void* rpc_client_thread(void* arg)
{
	rdpRpc* rpc;
	DWORD status;
	DWORD nCount;
	HANDLE events[3];
	HANDLE ReadEvent;

	rpc = (rdpRpc*) arg;

	ReadEvent = CreateFileDescriptorEvent(NULL, TRUE, FALSE, rpc->TlsOut->sockfd);

	nCount = 0;
	events[nCount++] = rpc->client->StopEvent;
	events[nCount++] = Queue_Event(rpc->client->SendQueue);
	events[nCount++] = ReadEvent;

	while (1)
	{
		status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);

		if (WaitForSingleObject(rpc->client->StopEvent, 0) == WAIT_OBJECT_0)
		{
			break;
		}

		if (WaitForSingleObject(ReadEvent, 0) == WAIT_OBJECT_0)
		{
			if (rpc_client_on_read_event(rpc) < 0)
				break;
		}

		if (WaitForSingleObject(Queue_Event(rpc->client->SendQueue), 0) == WAIT_OBJECT_0)
		{
			rpc_send_dequeue_pdu(rpc);
		}
	}

	CloseHandle(ReadEvent);

	rpc_client_free(rpc);

	return NULL;
}
Exemple #10
0
wStream* rpc_client_fragment_pool_take(rdpRpc* rpc)
{
	wStream* fragment = NULL;

	if (WaitForSingleObject(Queue_Event(rpc->client->FragmentPool), 0) == WAIT_OBJECT_0)
		fragment = Queue_Dequeue(rpc->client->FragmentPool);

	if (!fragment)
		fragment = Stream_New(NULL, rpc->max_recv_frag);

	return fragment;
}
Exemple #11
0
RPC_PDU* rpc_recv_peek_pdu(rdpRpc* rpc)
{
	DWORD dwMilliseconds;
	DWORD result;
	dwMilliseconds = rpc->client->SynchronousReceive ? SYNCHRONOUS_TIMEOUT : 0;
	result = WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds);

	if (result != WAIT_OBJECT_0)
		return NULL;

	return (RPC_PDU*)Queue_Peek(rpc->client->ReceiveQueue);
}
Exemple #12
0
static void* update_thread(void* arg)
{
	rdpUpdate* update;

	update = (rdpUpdate*) arg;

	while (WaitForSingleObject(Queue_Event(update->queue), INFINITE) == WAIT_OBJECT_0)
	{

	}

	return NULL;
}
Exemple #13
0
STREAM* transport_receive_pool_take(rdpTransport* transport)
{
	STREAM* pdu = NULL;

	if (WaitForSingleObject(Queue_Event(transport->ReceivePool), 0) == WAIT_OBJECT_0)
		pdu = Queue_Dequeue(transport->ReceivePool);

	if (!pdu)
		pdu = stream_new(BUFFER_SIZE);

	pdu->p = pdu->data;

	return pdu;
}
Exemple #14
0
static void* tsmf_stream_playback_func(void *arg)
{
	HANDLE hdl[2];
	TSMF_SAMPLE* sample;
	TSMF_STREAM* stream = (TSMF_STREAM *) arg;
	TSMF_PRESENTATION* presentation = stream->presentation;

	DEBUG_TSMF("in %d", stream->stream_id);

	if (stream->major_type == TSMF_MAJOR_TYPE_AUDIO &&
			stream->sample_rate && stream->channels && stream->bits_per_sample)
	{
		if (stream->decoder)
		{
			if (stream->decoder->GetDecodedData)
			{
				stream->audio = tsmf_load_audio_device(
					presentation->audio_name && presentation->audio_name[0] ? presentation->audio_name : NULL,
					presentation->audio_device && presentation->audio_device[0] ? presentation->audio_device : NULL);

				if (stream->audio)
				{
					stream->audio->SetFormat(stream->audio, stream->sample_rate, stream->channels, stream->bits_per_sample);
				}
			}
		}
	}

	hdl[0] = stream->stopEvent;
	hdl[1] = Queue_Event(stream->sample_list);

	while (!(WaitForMultipleObjects(2, hdl, FALSE, INFINITE) == WAIT_OBJECT_0))
	{
		sample = tsmf_stream_pop_sample(stream, 0);

		if (sample)
			tsmf_sample_playback(sample);
	}

	if (stream->audio)
	{
		stream->audio->Free(stream->audio);
		stream->audio = NULL;
	}

	DEBUG_TSMF("out %d", stream->stream_id);
	ExitThread(0);
	return NULL;
}
Exemple #15
0
RPC_PDU* rpc_recv_peek_pdu(rdpRpc* rpc)
{
	RPC_PDU* pdu;
	DWORD dwMilliseconds;

	pdu = NULL;
	dwMilliseconds = rpc->client->SynchronousReceive ? INFINITE : 0;

	if (WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds) == WAIT_OBJECT_0)
	{
		pdu = (RPC_PDU*) Queue_Peek(rpc->client->ReceiveQueue);
		return pdu;
	}

	return pdu;
}
Exemple #16
0
RFX_TILE* rfx_tile_pool_take(RFX_CONTEXT* context)
{
	RFX_TILE* tile = NULL;

	if (WaitForSingleObject(Queue_Event(context->priv->TilePool), 0) == WAIT_OBJECT_0)
		tile = Queue_Dequeue(context->priv->TilePool);

	if (!tile)
	{
		tile = (RFX_TILE*) malloc(sizeof(RFX_TILE));

		tile->x = tile->y = 0;
		tile->data = (BYTE*) malloc(4096 * 4); /* 64x64 * 4 */
	}

	return tile;
}
Exemple #17
0
static void* tsmf_stream_ack_func(void *arg)
{
	HANDLE hdl[2];
	TSMF_STREAM* stream = (TSMF_STREAM*) arg;
	UINT error = CHANNEL_RC_OK;
	DEBUG_TSMF("in %d", stream->stream_id);

	hdl[0] = stream->stopEvent;
	hdl[1] = Queue_Event(stream->sample_ack_list);

	while (1)
	{
		DWORD ev = WaitForMultipleObjects(2, hdl, FALSE, INFINITE);

        if (ev == WAIT_FAILED)
        {
            error = GetLastError();
            WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error);
            break;
        }

		if (ev == WAIT_OBJECT_0)
			break;

		if (!stream->decoder)
			continue;

		if (stream->decoder->SetAckFunc)
			continue;

		if (tsmf_stream_process_ack(stream, FALSE))
		{
			error = ERROR_INTERNAL_ERROR;
			WLog_ERR(TAG, "tsmf_stream_process_ack failed!");
			break;
		}

	}

	if (error && stream->rdpcontext)
		setChannelError(stream->rdpcontext, error, "tsmf_stream_ack_func reported an error");

	DEBUG_TSMF("out %d", stream->stream_id);
	ExitThread(0);
	return NULL;
}
Exemple #18
0
static void* serial_thread_func(void* arg)
{
	IRP* irp;
	DWORD status;
	SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg;

	while (1)
	{
		if (WaitForSingleObject(serial->stopEvent, 0) == WAIT_OBJECT_0)
			break;

		if (WaitForSingleObject(Queue_Event(serial->queue), 10) == WAIT_OBJECT_0)
			break;

		serial->nfds = 1;
		FD_ZERO(&serial->read_fds);
		FD_ZERO(&serial->write_fds);

		serial->tv.tv_sec = 1;
		serial->tv.tv_usec = 0;
		serial->select_timeout = 0;

		irp = (IRP*) Queue_Dequeue(serial->queue);

		if (irp)
			serial_process_irp(serial, irp);

		status = WaitForSingleObject(serial->in_event, 0);

		if ((status == WAIT_OBJECT_0) || (status == WAIT_TIMEOUT))
		{
			if (serial_check_fds(serial))
				ResetEvent(serial->in_event);
		}
	}

	return NULL;
}
Exemple #19
0
static void* thread_pool_work_func(void* arg)
{
	DWORD status;
	PTP_POOL pool;
	PTP_WORK work;
	HANDLE events[2];
	PTP_CALLBACK_INSTANCE callbackInstance;

	pool = (PTP_POOL) arg;

	events[0] = pool->TerminateEvent;
	events[1] = Queue_Event(pool->PendingQueue);

	while (1)
	{
		status = WaitForMultipleObjects(2, events, FALSE, INFINITE);

		if (status == WAIT_OBJECT_0)
			break;

		if (status != (WAIT_OBJECT_0 + 1))
			break;

		callbackInstance = (PTP_CALLBACK_INSTANCE) Queue_Dequeue(pool->PendingQueue);

		if (callbackInstance)
		{
			work = callbackInstance->Work;
			work->WorkCallback(callbackInstance, work->CallbackParameter, work);
			CountdownEvent_Signal(pool->WorkComplete, 1);
			free(callbackInstance);
		}
	}

	ExitThread(0);
	return NULL;
}
Exemple #20
0
static void* serial_thread_func(void* arg)
{
	IRP* irp;
	DWORD status;
	SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg;
	HANDLE ev[] = {serial->stopEvent, Queue_Event(serial->queue), serial->newEvent};

	assert(NULL != serial);
	while (1)
	{
		status = WaitForMultipleObjects(3, ev, FALSE, INFINITE);
	
		if (WAIT_OBJECT_0 == status)
			break;
		else if (status == WAIT_OBJECT_0 + 1)
		{
			FD_ZERO(&serial->read_fds);
			FD_ZERO(&serial->write_fds);

			serial->tv.tv_sec = 0;
			serial->tv.tv_usec = 0;
			serial->select_timeout = 0;

			if ((irp = (IRP*) Queue_Dequeue(serial->queue)))
				serial_process_irp(serial, irp);
		}
		else if (status == WAIT_OBJECT_0 + 2)
			ResetEvent(serial->newEvent);

		if(serial->tty)
			serial_check_fds(serial);
	}

	ExitThread(0);
	return NULL;
}
Exemple #21
0
static void* smartcard_thread_func(void* arg)
{
	IRP* irp;
	DWORD nCount;
	DWORD status;
	HANDLE hEvents[2];
	wMessage message;
	SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) arg;
	UINT error = CHANNEL_RC_OK;

	nCount = 0;
	hEvents[nCount++] = MessageQueue_Event(smartcard->IrpQueue);
	hEvents[nCount++] = Queue_Event(smartcard->CompletedIrpQueue);

	while (1)
	{
		status = WaitForMultipleObjects(nCount, hEvents, FALSE, INFINITE);

		if (status == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error);
			break;
		}

		status = WaitForSingleObject(MessageQueue_Event(smartcard->IrpQueue), 0);

		if (status == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
			break;
		}

		if (status == WAIT_OBJECT_0)
		{
			if (!MessageQueue_Peek(smartcard->IrpQueue, &message, TRUE))
			{
				WLog_ERR(TAG, "MessageQueue_Peek failed!");
				error = ERROR_INTERNAL_ERROR;
				break;
			}


			if (message.id == WMQ_QUIT)
			{
				while (1)
				{
					status = WaitForSingleObject(Queue_Event(smartcard->CompletedIrpQueue), 0);

					if (status == WAIT_FAILED)
					{
						error = GetLastError();
						WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
						goto out;
					}

					if (status == WAIT_TIMEOUT)
						break;

					irp = (IRP*) Queue_Dequeue(smartcard->CompletedIrpQueue);

					if (irp)
					{
						if (irp->thread)
						{
							status = WaitForSingleObject(irp->thread, INFINITE);

							if (status == WAIT_FAILED)
							{
								error = GetLastError();
								WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
								goto out;
							}

							CloseHandle(irp->thread);
							irp->thread = NULL;
						}

						if ((error = smartcard_complete_irp(smartcard, irp)))
						{
							WLog_ERR(TAG, "smartcard_complete_irp failed with error %lu!", error);
							goto out;
						}
					}
				}

				break;
			}

			irp = (IRP*) message.wParam;

			if (irp)
			{
				if ((error = smartcard_process_irp(smartcard, irp)))
				{
					WLog_ERR(TAG, "smartcard_process_irp failed with error %lu!", error);
					goto out;
				}
			}
		}

		status = WaitForSingleObject(Queue_Event(smartcard->CompletedIrpQueue), 0);

		if (status == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
			break;
		}

		if (status == WAIT_OBJECT_0)
		{

			irp = (IRP*) Queue_Dequeue(smartcard->CompletedIrpQueue);

			if (irp)
			{
				if (irp->thread)
				{
					status = WaitForSingleObject(irp->thread, INFINITE);

					if (status == WAIT_FAILED)
					{
						error = GetLastError();
						WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
						break;
					}

					CloseHandle(irp->thread);
					irp->thread = NULL;
				}

				if ((error = smartcard_complete_irp(smartcard, irp)))
				{
					if (error == CHANNEL_RC_NOT_CONNECTED)
					{
						error = CHANNEL_RC_OK;
						goto out;
					}
					WLog_ERR(TAG, "smartcard_complete_irp failed with error %lu!", error);
					goto out;
				}
			}
		}
	}
out:
	if (error && smartcard->rdpcontext)
		setChannelError(smartcard->rdpcontext, error, "smartcard_thread_func reported an error");

	ExitThread((DWORD)error);
	return NULL;
}
Exemple #22
0
static void* smartcard_thread_func(void* arg)
{
	IRP* irp;
	DWORD nCount;
	DWORD status;
	HANDLE hEvents[2];
	wMessage message;
	SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) arg;

	nCount = 0;
	hEvents[nCount++] = MessageQueue_Event(smartcard->IrpQueue);
	hEvents[nCount++] = Queue_Event(smartcard->CompletedIrpQueue);

	while (1)
	{
		status = WaitForMultipleObjects(nCount, hEvents, FALSE, INFINITE);

		if (WaitForSingleObject(MessageQueue_Event(smartcard->IrpQueue), 0) == WAIT_OBJECT_0)
		{
			if (!MessageQueue_Peek(smartcard->IrpQueue, &message, TRUE))
				break;

			if (message.id == WMQ_QUIT)
			{
				while (WaitForSingleObject(Queue_Event(smartcard->CompletedIrpQueue), 0) == WAIT_OBJECT_0)
				{
					irp = (IRP*) Queue_Dequeue(smartcard->CompletedIrpQueue);

					if (irp)
					{
						if (irp->thread)
						{
							WaitForSingleObject(irp->thread, INFINITE);
							CloseHandle(irp->thread);
							irp->thread = NULL;
						}

						smartcard_complete_irp(smartcard, irp);
					}
				}

				break;
			}

			irp = (IRP*) message.wParam;

			if (irp)
			{
				smartcard_process_irp(smartcard, irp);
			}
		}

		if (WaitForSingleObject(Queue_Event(smartcard->CompletedIrpQueue), 0) == WAIT_OBJECT_0)
		{
			irp = (IRP*) Queue_Dequeue(smartcard->CompletedIrpQueue);

			if (irp)
			{
				if (irp->thread)
				{
					WaitForSingleObject(irp->thread, INFINITE);
					CloseHandle(irp->thread);
					irp->thread = NULL;
				}

				smartcard_complete_irp(smartcard, irp);
			}
		}
	}

	ExitThread(0);
	return NULL;
}
Exemple #23
0
static void* tsmf_stream_ack_func(void *arg)
{
	HANDLE hdl[2];
	TSMF_STREAM* stream = (TSMF_STREAM*) arg;
	UINT error = CHANNEL_RC_OK;
	DEBUG_TSMF("in %d", stream->stream_id);

	hdl[0] = stream->stopEvent;
	hdl[1] = Queue_Event(stream->sample_ack_list);

	while (1)
	{
		DWORD ev = WaitForMultipleObjects(2, hdl, FALSE, 1000);

		if (ev == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error);
			break;
		}

		if (stream->decoder)
			if (stream->decoder->BufferLevel)
				stream->currentBufferLevel = stream->decoder->BufferLevel(stream->decoder);

		if (stream->eos)
		{
			while ((stream->currentBufferLevel > 0) || !(tsmf_stream_process_ack(stream, TRUE)))
			{
				DEBUG_TSMF("END OF STREAM PROCESSING!");
				if (stream->decoder->BufferLevel)
					stream->currentBufferLevel = stream->decoder->BufferLevel(stream->decoder);
				else
					stream->currentBufferLevel = 1;

				USleep(1000);
			}

			tsmf_send_eos_response(stream->eos_channel_callback, stream->eos_message_id);
			stream->eos = 0;

			if (stream->delayed_stop)
			{
				DEBUG_TSMF("Finishing delayed stream stop, now that eos has processed.");
				tsmf_stream_flush(stream);

				if (stream->decoder->Control)
					stream->decoder->Control(stream->decoder, Control_Stop, NULL);
			}
		}

		/* Stream stopped force all of the acks to happen */
		if (ev == WAIT_OBJECT_0)
		{
			DEBUG_TSMF("ack: Stream stopped!");
			while(1)
			{
				if (tsmf_stream_process_ack(stream, TRUE))
					break;
				USleep(1000);
			}
			break;
		}

		if (tsmf_stream_process_ack(stream, FALSE))
			continue;

		if (stream->currentBufferLevel > stream->minBufferLevel)
			USleep(1000);
	}

	if (error && stream->rdpcontext)
		setChannelError(stream->rdpcontext, error, "tsmf_stream_ack_func reported an error");

	DEBUG_TSMF("out %d", stream->stream_id);
	ExitThread(0);
	return NULL;
}
Exemple #24
0
static void* tsmf_stream_playback_func(void *arg)
{
	HANDLE hdl[2];
	TSMF_SAMPLE* sample = NULL;
	TSMF_STREAM* stream = (TSMF_STREAM *) arg;
	TSMF_PRESENTATION* presentation = stream->presentation;
	UINT error = CHANNEL_RC_OK;
	DWORD status;

	DEBUG_TSMF("in %d", stream->stream_id);

	if (stream->major_type == TSMF_MAJOR_TYPE_AUDIO &&
			stream->sample_rate && stream->channels && stream->bits_per_sample)
	{
		if (stream->decoder)
		{
			if (stream->decoder->GetDecodedData)
			{
				stream->audio = tsmf_load_audio_device(
					presentation->audio_name && presentation->audio_name[0] ? presentation->audio_name : NULL,
					presentation->audio_device && presentation->audio_device[0] ? presentation->audio_device : NULL);

				if (stream->audio)
				{
					stream->audio->SetFormat(stream->audio, stream->sample_rate, stream->channels, stream->bits_per_sample);
				}
			}
		}
	}

	hdl[0] = stream->stopEvent;
	hdl[1] = Queue_Event(stream->sample_list);

	while (1)
	{
		status = WaitForMultipleObjects(2, hdl, FALSE, 1000);

		if (status == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error);
			break;
		}

		status = WaitForSingleObject(stream->stopEvent, 0);

		if (status == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
			break;
		}

		if (status == WAIT_OBJECT_0)
			break;

		if (stream->decoder)
			if (stream->decoder->BufferLevel)
				stream->currentBufferLevel = stream->decoder->BufferLevel(stream->decoder);

		sample = tsmf_stream_pop_sample(stream, 0);

		if (sample && !tsmf_sample_playback(sample))
		{
			WLog_ERR(TAG, "error playing sample");
			error = ERROR_INTERNAL_ERROR;
			break;
		}

		if (stream->currentBufferLevel > stream->minBufferLevel)
			USleep(1000);
	}


	if (stream->audio)
	{
		stream->audio->Free(stream->audio);
		stream->audio = NULL;
	}

	if (error && stream->rdpcontext)
		setChannelError(stream->rdpcontext, error, "tsmf_stream_playback_func reported an error");

	DEBUG_TSMF("out %d", stream->stream_id);
	ExitThread(0);
	return NULL;
}