Merge pull request #1460 from akallabeth/thread_handle_fixes
Thread handle fixes
This commit is contained in:
commit
336e47e82f
@ -419,7 +419,9 @@ static BOOL audin_server_close(audin_server_context* context)
|
|||||||
SetEvent(audin->stopEvent);
|
SetEvent(audin->stopEvent);
|
||||||
WaitForSingleObject(audin->thread, INFINITE);
|
WaitForSingleObject(audin->thread, INFINITE);
|
||||||
CloseHandle(audin->thread);
|
CloseHandle(audin->thread);
|
||||||
|
CloseHandle(audin->stopEvent);
|
||||||
audin->thread = NULL;
|
audin->thread = NULL;
|
||||||
|
audin->stopEvent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audin->audin_channel)
|
if (audin->audin_channel)
|
||||||
|
@ -631,8 +631,9 @@ FREERDP_API int freerdp_channels_send_event(rdpChannels* channels, wMessage* eve
|
|||||||
/**
|
/**
|
||||||
* called only from main thread
|
* called only from main thread
|
||||||
*/
|
*/
|
||||||
static void freerdp_channels_process_sync(rdpChannels* channels, freerdp* instance)
|
static int freerdp_channels_process_sync(rdpChannels* channels, freerdp* instance)
|
||||||
{
|
{
|
||||||
|
int rc = TRUE;
|
||||||
wMessage message;
|
wMessage message;
|
||||||
wMessage* event;
|
wMessage* event;
|
||||||
rdpChannel* channel;
|
rdpChannel* channel;
|
||||||
@ -642,7 +643,10 @@ static void freerdp_channels_process_sync(rdpChannels* channels, freerdp* instan
|
|||||||
while (MessageQueue_Peek(channels->MsgPipe->Out, &message, TRUE))
|
while (MessageQueue_Peek(channels->MsgPipe->Out, &message, TRUE))
|
||||||
{
|
{
|
||||||
if (message.id == WMQ_QUIT)
|
if (message.id == WMQ_QUIT)
|
||||||
|
{
|
||||||
|
rc = FALSE;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (message.id == 0)
|
if (message.id == 0)
|
||||||
{
|
{
|
||||||
@ -677,6 +681,8 @@ static void freerdp_channels_process_sync(rdpChannels* channels, freerdp* instan
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -730,7 +736,7 @@ int freerdp_channels_process_pending_messages(freerdp* instance)
|
|||||||
|
|
||||||
if (WaitForSingleObject(MessageQueue_Event(channels->MsgPipe->Out), 0) == WAIT_OBJECT_0)
|
if (WaitForSingleObject(MessageQueue_Event(channels->MsgPipe->Out), 0) == WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
freerdp_channels_process_sync(channels, instance);
|
return freerdp_channels_process_sync(channels, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -782,4 +788,7 @@ void freerdp_channels_close(rdpChannels* channels, freerdp* instance)
|
|||||||
if (pChannelClientData->pChannelInitEventProc)
|
if (pChannelClientData->pChannelInitEventProc)
|
||||||
pChannelClientData->pChannelInitEventProc(pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0);
|
pChannelClientData->pChannelInitEventProc(pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Emit a quit signal to the internal message pipe. */
|
||||||
|
MessagePipe_PostQuit(channels->MsgPipe, 0);
|
||||||
}
|
}
|
||||||
|
@ -633,17 +633,18 @@ static void drive_process_irp_list(DRIVE_DEVICE* disk)
|
|||||||
static void* drive_thread_func(void* arg)
|
static void* drive_thread_func(void* arg)
|
||||||
{
|
{
|
||||||
DRIVE_DEVICE* disk = (DRIVE_DEVICE*) arg;
|
DRIVE_DEVICE* disk = (DRIVE_DEVICE*) arg;
|
||||||
|
HANDLE hdl[] = {disk->irpEvent, disk->stopEvent};
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
WaitForSingleObject(disk->irpEvent, INFINITE);
|
DWORD rc = WaitForMultipleObjects(2, hdl, FALSE, INFINITE);
|
||||||
|
if (rc == WAIT_OBJECT_0 + 1)
|
||||||
if (WaitForSingleObject(disk->stopEvent, 0) == WAIT_OBJECT_0)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ResetEvent(disk->irpEvent);
|
ResetEvent(disk->irpEvent);
|
||||||
drive_process_irp_list(disk);
|
drive_process_irp_list(disk);
|
||||||
}
|
}
|
||||||
|
ExitThread(0);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -664,8 +665,10 @@ static void drive_free(DEVICE* device)
|
|||||||
DRIVE_DEVICE* disk = (DRIVE_DEVICE*) device;
|
DRIVE_DEVICE* disk = (DRIVE_DEVICE*) device;
|
||||||
|
|
||||||
SetEvent(disk->stopEvent);
|
SetEvent(disk->stopEvent);
|
||||||
|
WaitForSingleObject(disk->thread, INFINITE);
|
||||||
CloseHandle(disk->thread);
|
CloseHandle(disk->thread);
|
||||||
CloseHandle(disk->irpEvent);
|
CloseHandle(disk->irpEvent);
|
||||||
|
CloseHandle(disk->stopEvent);
|
||||||
|
|
||||||
while ((irp = (IRP*) InterlockedPopEntrySList(disk->pIrpList)) != NULL)
|
while ((irp = (IRP*) InterlockedPopEntrySList(disk->pIrpList)) != NULL)
|
||||||
irp->Discard(irp);
|
irp->Discard(irp);
|
||||||
|
@ -200,6 +200,8 @@ static void* printer_thread_func(void* arg)
|
|||||||
printer_process_irp(printer_dev, irp);
|
printer_process_irp(printer_dev, irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExitThread(0);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,11 +221,14 @@ static void printer_free(DEVICE* device)
|
|||||||
|
|
||||||
SetEvent(printer_dev->stopEvent);
|
SetEvent(printer_dev->stopEvent);
|
||||||
WaitForSingleObject(printer_dev->thread, INFINITE);
|
WaitForSingleObject(printer_dev->thread, INFINITE);
|
||||||
CloseHandle(printer_dev->thread);
|
|
||||||
|
|
||||||
while ((irp = (IRP*) InterlockedPopEntrySList(printer_dev->pIrpList)) != NULL)
|
while ((irp = (IRP*) InterlockedPopEntrySList(printer_dev->pIrpList)) != NULL)
|
||||||
irp->Discard(irp);
|
irp->Discard(irp);
|
||||||
|
|
||||||
|
CloseHandle(printer_dev->thread);
|
||||||
|
CloseHandle(printer_dev->stopEvent);
|
||||||
|
CloseHandle(printer_dev->event);
|
||||||
|
|
||||||
_aligned_free(printer_dev->pIrpList);
|
_aligned_free(printer_dev->pIrpList);
|
||||||
|
|
||||||
if (printer_dev->printer)
|
if (printer_dev->printer)
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -97,6 +98,7 @@ struct _RDPEI_PLUGIN
|
|||||||
RDPINPUT_CONTACT_POINT* contactPoints;
|
RDPINPUT_CONTACT_POINT* contactPoints;
|
||||||
|
|
||||||
HANDLE event;
|
HANDLE event;
|
||||||
|
HANDLE stopEvent;
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
|
|
||||||
CRITICAL_SECTION lock;
|
CRITICAL_SECTION lock;
|
||||||
@ -156,10 +158,16 @@ static void* rdpei_schedule_thread(void* arg)
|
|||||||
DWORD status;
|
DWORD status;
|
||||||
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) arg;
|
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) arg;
|
||||||
RdpeiClientContext* context = (RdpeiClientContext*) rdpei->iface.pInterface;
|
RdpeiClientContext* context = (RdpeiClientContext*) rdpei->iface.pInterface;
|
||||||
|
HANDLE hdl[] = {rdpei->event, rdpei->stopEvent};
|
||||||
|
|
||||||
|
assert(NULL != rdpei);
|
||||||
|
assert(NULL != context);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
status = WaitForSingleObject(rdpei->event, 20);
|
status = WaitForMultipleObjects(2, hdl, FALSE, 20);
|
||||||
|
if (status == WAIT_OBJECT_0 + 1)
|
||||||
|
break;
|
||||||
|
|
||||||
EnterCriticalSection(&rdpei->lock);
|
EnterCriticalSection(&rdpei->lock);
|
||||||
|
|
||||||
@ -174,6 +182,8 @@ static void* rdpei_schedule_thread(void* arg)
|
|||||||
LeaveCriticalSection(&rdpei->lock);
|
LeaveCriticalSection(&rdpei->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExitThread(0);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,13 +228,6 @@ int rdpei_send_cs_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback)
|
|||||||
|
|
||||||
Stream_SealLength(s);
|
Stream_SealLength(s);
|
||||||
|
|
||||||
if (!rdpei->thread)
|
|
||||||
{
|
|
||||||
InitializeCriticalSection(&rdpei->lock);
|
|
||||||
rdpei->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
||||||
rdpei->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpei_schedule_thread, (void*) rdpei, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
status = rdpei_send_pdu(callback, s, EVENTID_CS_READY, pduLength);
|
status = rdpei_send_pdu(callback, s, EVENTID_CS_READY, pduLength);
|
||||||
Stream_Free(s, TRUE);
|
Stream_Free(s, TRUE);
|
||||||
|
|
||||||
@ -488,6 +491,12 @@ static int rdpei_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage
|
|||||||
|
|
||||||
rdpei->listener->pInterface = rdpei->iface.pInterface;
|
rdpei->listener->pInterface = rdpei->iface.pInterface;
|
||||||
|
|
||||||
|
InitializeCriticalSection(&rdpei->lock);
|
||||||
|
rdpei->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
rdpei->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
rdpei->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
|
||||||
|
rdpei_schedule_thread, (void*) rdpei, 0, NULL);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,6 +506,22 @@ static int rdpei_plugin_terminated(IWTSPlugin* pPlugin)
|
|||||||
|
|
||||||
DEBUG_DVC("");
|
DEBUG_DVC("");
|
||||||
|
|
||||||
|
assert(NULL != pPlugin);
|
||||||
|
|
||||||
|
SetEvent(rdpei->stopEvent);
|
||||||
|
EnterCriticalSection(&rdpei->lock);
|
||||||
|
|
||||||
|
WaitForSingleObject(rdpei->thread, INFINITE);
|
||||||
|
|
||||||
|
CloseHandle(rdpei->stopEvent);
|
||||||
|
CloseHandle(rdpei->event);
|
||||||
|
CloseHandle(rdpei->thread);
|
||||||
|
|
||||||
|
DeleteCriticalSection(&rdpei->lock);
|
||||||
|
|
||||||
|
if (rdpei->listener_callback)
|
||||||
|
free(rdpei->listener_callback);
|
||||||
|
|
||||||
free(rdpei);
|
free(rdpei);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -541,6 +541,9 @@ void rdpsnd_server_context_free(rdpsnd_server_context* context)
|
|||||||
SetEvent(rdpsnd->StopEvent);
|
SetEvent(rdpsnd->StopEvent);
|
||||||
WaitForSingleObject(rdpsnd->thread, INFINITE);
|
WaitForSingleObject(rdpsnd->thread, INFINITE);
|
||||||
|
|
||||||
|
CloseHandle(rdpsnd->StopEvent);
|
||||||
|
CloseHandle(rdpsnd->thread);
|
||||||
|
|
||||||
if (rdpsnd->rdpsnd_channel)
|
if (rdpsnd->rdpsnd_channel)
|
||||||
WTSVirtualChannelClose(rdpsnd->rdpsnd_channel);
|
WTSVirtualChannelClose(rdpsnd->rdpsnd_channel);
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -346,6 +347,7 @@ void* serial_thread_mfunc(void* arg)
|
|||||||
{
|
{
|
||||||
SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg;
|
SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg;
|
||||||
|
|
||||||
|
assert(NULL != serial);
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
int sl;
|
int sl;
|
||||||
@ -366,6 +368,7 @@ void* serial_thread_mfunc(void* arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExitThread(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,6 +379,7 @@ static void* serial_thread_func(void* arg)
|
|||||||
SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg;
|
SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg;
|
||||||
HANDLE ev[] = {serial->stopEvent, Queue_Event(serial->queue), serial->newEvent};
|
HANDLE ev[] = {serial->stopEvent, Queue_Event(serial->queue), serial->newEvent};
|
||||||
|
|
||||||
|
assert(NULL != serial);
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
status = WaitForMultipleObjects(3, ev, FALSE, INFINITE);
|
status = WaitForMultipleObjects(3, ev, FALSE, INFINITE);
|
||||||
@ -401,6 +405,7 @@ static void* serial_thread_func(void* arg)
|
|||||||
serial_check_fds(serial);
|
serial_check_fds(serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExitThread(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,13 +112,16 @@ struct _SMARTCARD_IRP_WORKER
|
|||||||
};
|
};
|
||||||
typedef struct _SMARTCARD_IRP_WORKER SMARTCARD_IRP_WORKER;
|
typedef struct _SMARTCARD_IRP_WORKER SMARTCARD_IRP_WORKER;
|
||||||
|
|
||||||
static void smartcard_process_irp_thread_func(SMARTCARD_IRP_WORKER* irpWorker)
|
static void *smartcard_process_irp_thread_func(SMARTCARD_IRP_WORKER* irpWorker)
|
||||||
{
|
{
|
||||||
smartcard_process_irp(irpWorker->smartcard, irpWorker->irp);
|
smartcard_process_irp(irpWorker->smartcard, irpWorker->irp);
|
||||||
|
|
||||||
CloseHandle(irpWorker->thread);
|
CloseHandle(irpWorker->thread);
|
||||||
|
|
||||||
free(irpWorker);
|
free(irpWorker);
|
||||||
|
|
||||||
|
ExitThread(0);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* smartcard_thread_func(void* arg)
|
static void* smartcard_thread_func(void* arg)
|
||||||
|
@ -569,7 +569,10 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
|
|||||||
rdpChannels* channels;
|
rdpChannels* channels;
|
||||||
|
|
||||||
instance = (freerdp*) lpParam;
|
instance = (freerdp*) lpParam;
|
||||||
|
assert(NULL != instance);
|
||||||
|
|
||||||
wfc = (wfContext*) instance->context;
|
wfc = (wfContext*) instance->context;
|
||||||
|
assert(NULL != wfc);
|
||||||
|
|
||||||
ZeroMemory(rfds, sizeof(rfds));
|
ZeroMemory(rfds, sizeof(rfds));
|
||||||
ZeroMemory(wfds, sizeof(wfds));
|
ZeroMemory(wfds, sizeof(wfds));
|
||||||
@ -690,13 +693,13 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
wfc->mainThreadId = 0;
|
|
||||||
|
|
||||||
freerdp_channels_close(channels, instance);
|
freerdp_channels_close(channels, instance);
|
||||||
freerdp_disconnect(instance);
|
freerdp_disconnect(instance);
|
||||||
|
|
||||||
printf("Main thread exited.\n");
|
printf("Main thread exited.\n");
|
||||||
|
|
||||||
|
ExitThread(0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,6 +711,7 @@ DWORD WINAPI wf_keyboard_thread(LPVOID lpParam)
|
|||||||
HHOOK hook_handle;
|
HHOOK hook_handle;
|
||||||
|
|
||||||
wfc = (wfContext*) lpParam;
|
wfc = (wfContext*) lpParam;
|
||||||
|
assert(NULL != wfc);
|
||||||
|
|
||||||
hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, wf_ll_kbd_proc, wfc->hInstance, 0);
|
hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, wf_ll_kbd_proc, wfc->hInstance, 0);
|
||||||
|
|
||||||
@ -734,9 +738,9 @@ DWORD WINAPI wf_keyboard_thread(LPVOID lpParam)
|
|||||||
fprintf(stderr, "failed to install keyboard hook\n");
|
fprintf(stderr, "failed to install keyboard hook\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
wfc->keyboardThreadId = 0;
|
|
||||||
printf("Keyboard thread exited.\n");
|
printf("Keyboard thread exited.\n");
|
||||||
|
|
||||||
|
ExitThread(0);
|
||||||
return (DWORD) NULL;
|
return (DWORD) NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1078,12 +1082,27 @@ int wfreerdp_client_stop(rdpContext* context)
|
|||||||
{
|
{
|
||||||
wfContext* wfc = (wfContext*) context;
|
wfContext* wfc = (wfContext*) context;
|
||||||
|
|
||||||
if (wfc->mainThreadId)
|
if (wfc->thread)
|
||||||
|
{
|
||||||
PostThreadMessage(wfc->mainThreadId, WM_QUIT, 0, 0);
|
PostThreadMessage(wfc->mainThreadId, WM_QUIT, 0, 0);
|
||||||
|
|
||||||
if (wfc->keyboardThreadId)
|
WaitForSingleObject(wfc->thread, INFINITE);
|
||||||
|
CloseHandle(wfc->thread);
|
||||||
|
wfc->thread = NULL;
|
||||||
|
wfc->mainThreadId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wfc->keyboardThread)
|
||||||
|
{
|
||||||
PostThreadMessage(wfc->keyboardThreadId, WM_QUIT, 0, 0);
|
PostThreadMessage(wfc->keyboardThreadId, WM_QUIT, 0, 0);
|
||||||
|
|
||||||
|
WaitForSingleObject(wfc->keyboardThread, INFINITE);
|
||||||
|
CloseHandle(wfc->keyboardThread);
|
||||||
|
|
||||||
|
wfc->keyboardThread = NULL;
|
||||||
|
wfc->keyboardThreadId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -773,12 +773,12 @@ BOOL xf_pre_connect(freerdp* instance)
|
|||||||
if (settings->Username == NULL)
|
if (settings->Username == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "--authonly, but no -u username. Please provide one.\n");
|
fprintf(stderr, "--authonly, but no -u username. Please provide one.\n");
|
||||||
exit(1);
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (settings->Password == NULL)
|
if (settings->Password == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "--authonly, but no -p password. Please provide one.\n");
|
fprintf(stderr, "--authonly, but no -p password. Please provide one.\n");
|
||||||
exit(1);
|
return FALSE;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "%s:%d: Authentication only. Don't connect to X.\n", __FILE__, __LINE__);
|
fprintf(stderr, "%s:%d: Authentication only. Don't connect to X.\n", __FILE__, __LINE__);
|
||||||
/* Avoid XWindows initialization and configuration below. */
|
/* Avoid XWindows initialization and configuration below. */
|
||||||
@ -1224,6 +1224,8 @@ void* xf_update_thread(void* arg)
|
|||||||
wMessageQueue* queue;
|
wMessageQueue* queue;
|
||||||
freerdp* instance = (freerdp*) arg;
|
freerdp* instance = (freerdp*) arg;
|
||||||
|
|
||||||
|
assert( NULL != instance);
|
||||||
|
|
||||||
status = 1;
|
status = 1;
|
||||||
queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||||
|
|
||||||
@ -1241,6 +1243,7 @@ void* xf_update_thread(void* arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExitThread(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1253,9 +1256,12 @@ void* xf_input_thread(void* arg)
|
|||||||
int pending_status = 1;
|
int pending_status = 1;
|
||||||
int process_status = 1;
|
int process_status = 1;
|
||||||
freerdp* instance = (freerdp*) arg;
|
freerdp* instance = (freerdp*) arg;
|
||||||
|
assert(NULL != instance);
|
||||||
|
|
||||||
xfc = (xfContext*) instance->context;
|
xfc = (xfContext*) instance->context;
|
||||||
|
assert(NULL != xfc);
|
||||||
|
|
||||||
|
queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||||
event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds);
|
event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds);
|
||||||
|
|
||||||
while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
|
while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
|
||||||
@ -1288,9 +1294,8 @@ void* xf_input_thread(void* arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
|
||||||
MessageQueue_PostQuit(queue, 0);
|
MessageQueue_PostQuit(queue, 0);
|
||||||
|
ExitThread(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1301,8 +1306,10 @@ void* xf_channels_thread(void* arg)
|
|||||||
HANDLE event;
|
HANDLE event;
|
||||||
rdpChannels* channels;
|
rdpChannels* channels;
|
||||||
freerdp* instance = (freerdp*) arg;
|
freerdp* instance = (freerdp*) arg;
|
||||||
|
assert(NULL != instance);
|
||||||
|
|
||||||
xfc = (xfContext*) instance->context;
|
xfc = (xfContext*) instance->context;
|
||||||
|
assert(NULL != xfc);
|
||||||
|
|
||||||
channels = instance->context->channels;
|
channels = instance->context->channels;
|
||||||
event = freerdp_channels_get_event_handle(instance);
|
event = freerdp_channels_get_event_handle(instance);
|
||||||
@ -1310,9 +1317,13 @@ void* xf_channels_thread(void* arg)
|
|||||||
while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
|
while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
status = freerdp_channels_process_pending_messages(instance);
|
status = freerdp_channels_process_pending_messages(instance);
|
||||||
|
if (!status)
|
||||||
|
break;
|
||||||
|
|
||||||
xf_process_channel_event(channels, instance);
|
xf_process_channel_event(channels, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExitThread(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1356,6 +1367,7 @@ void* xf_thread(void* param)
|
|||||||
input_event = NULL;
|
input_event = NULL;
|
||||||
|
|
||||||
instance = (freerdp*) param;
|
instance = (freerdp*) param;
|
||||||
|
assert(NULL != instance);
|
||||||
|
|
||||||
ZeroMemory(rfds, sizeof(rfds));
|
ZeroMemory(rfds, sizeof(rfds));
|
||||||
ZeroMemory(wfds, sizeof(wfds));
|
ZeroMemory(wfds, sizeof(wfds));
|
||||||
@ -1364,6 +1376,7 @@ void* xf_thread(void* param)
|
|||||||
status = freerdp_connect(instance);
|
status = freerdp_connect(instance);
|
||||||
|
|
||||||
xfc = (xfContext*) instance->context;
|
xfc = (xfContext*) instance->context;
|
||||||
|
assert(NULL != xfc);
|
||||||
|
|
||||||
/* Connection succeeded. --authonly ? */
|
/* Connection succeeded. --authonly ? */
|
||||||
if (instance->settings->AuthenticationOnly)
|
if (instance->settings->AuthenticationOnly)
|
||||||
@ -1533,6 +1546,10 @@ void* xf_thread(void* param)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Close the channels first. This will signal the internal message pipes
|
||||||
|
* that the threads should quit. */
|
||||||
|
freerdp_channels_close(channels, instance);
|
||||||
|
|
||||||
if (async_update)
|
if (async_update)
|
||||||
{
|
{
|
||||||
wMessageQueue* update_queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
wMessageQueue* update_queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||||
@ -1541,6 +1558,20 @@ void* xf_thread(void* param)
|
|||||||
CloseHandle(update_thread);
|
CloseHandle(update_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (async_input)
|
||||||
|
{
|
||||||
|
wMessageQueue* 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);
|
||||||
|
}
|
||||||
|
|
||||||
FILE* fin = fopen("/tmp/tsmf.tid", "rt");
|
FILE* fin = fopen("/tmp/tsmf.tid", "rt");
|
||||||
|
|
||||||
if (fin)
|
if (fin)
|
||||||
@ -1577,7 +1608,6 @@ void* xf_thread(void* param)
|
|||||||
if (!exit_code)
|
if (!exit_code)
|
||||||
exit_code = freerdp_error_info(instance);
|
exit_code = freerdp_error_info(instance);
|
||||||
|
|
||||||
freerdp_channels_close(channels, instance);
|
|
||||||
freerdp_channels_free(channels);
|
freerdp_channels_free(channels);
|
||||||
freerdp_disconnect(instance);
|
freerdp_disconnect(instance);
|
||||||
gdi_free(instance);
|
gdi_free(instance);
|
||||||
@ -1713,7 +1743,8 @@ static int xfreerdp_client_start(rdpContext* context)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfc->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_thread, context->instance, 0, NULL);
|
xfc->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_thread,
|
||||||
|
context->instance, 0, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1722,6 +1753,7 @@ static int xfreerdp_client_stop(rdpContext* context)
|
|||||||
{
|
{
|
||||||
xfContext* xfc = (xfContext*) context;
|
xfContext* xfc = (xfContext*) context;
|
||||||
|
|
||||||
|
assert(NULL != context);
|
||||||
if (context->settings->AsyncInput)
|
if (context->settings->AsyncInput)
|
||||||
{
|
{
|
||||||
wMessageQueue* queue;
|
wMessageQueue* queue;
|
||||||
@ -1735,8 +1767,11 @@ static int xfreerdp_client_stop(rdpContext* context)
|
|||||||
xfc->disconnect = TRUE;
|
xfc->disconnect = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitForSingleObject(xfc->thread, INFINITE);
|
if (xfc->thread)
|
||||||
|
{
|
||||||
CloseHandle(xfc->thread);
|
CloseHandle(xfc->thread);
|
||||||
|
xfc->thread = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -85,6 +86,14 @@ BOOL transport_disconnect(rdpTransport* transport)
|
|||||||
status &= tcp_disconnect(transport->TcpIn);
|
status &= tcp_disconnect(transport->TcpIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (transport->async)
|
||||||
|
{
|
||||||
|
SetEvent(transport->stopEvent);
|
||||||
|
WaitForSingleObject(transport->thread, INFINITE);
|
||||||
|
|
||||||
|
CloseHandle(transport->thread);
|
||||||
|
CloseHandle(transport->stopEvent);
|
||||||
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,8 +802,14 @@ static void* transport_client_thread(void* arg)
|
|||||||
rdpTransport* transport;
|
rdpTransport* transport;
|
||||||
|
|
||||||
transport = (rdpTransport*) arg;
|
transport = (rdpTransport*) arg;
|
||||||
|
assert(NULL != transport);
|
||||||
|
assert(NULL != transport->settings);
|
||||||
|
|
||||||
instance = (freerdp*) transport->settings->instance;
|
instance = (freerdp*) transport->settings->instance;
|
||||||
|
assert(NULL != instance);
|
||||||
|
|
||||||
context = instance->context;
|
context = instance->context;
|
||||||
|
assert(NULL != instance->context);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -803,25 +818,20 @@ static void* transport_client_thread(void* arg)
|
|||||||
events[nCount] = transport->connectedEvent;
|
events[nCount] = transport->connectedEvent;
|
||||||
|
|
||||||
status = WaitForMultipleObjects(nCount + 1, events, FALSE, INFINITE);
|
status = WaitForMultipleObjects(nCount + 1, events, FALSE, INFINITE);
|
||||||
|
if (status == WAIT_OBJECT_0)
|
||||||
if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
transport_get_read_handles(transport, (HANDLE*) &events, &nCount);
|
transport_get_read_handles(transport, (HANDLE*) &events, &nCount);
|
||||||
|
|
||||||
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
|
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
|
||||||
|
if (status == WAIT_OBJECT_0)
|
||||||
if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (!freerdp_check_fds(instance))
|
if (!freerdp_check_fds(instance))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExitThread(0);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -185,6 +186,8 @@ static void* svc_plugin_thread_func(void* arg)
|
|||||||
|
|
||||||
DEBUG_SVC("in");
|
DEBUG_SVC("in");
|
||||||
|
|
||||||
|
assert(NULL != plugin);
|
||||||
|
|
||||||
IFCALL(plugin->connect_callback, plugin);
|
IFCALL(plugin->connect_callback, plugin);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@ -212,6 +215,8 @@ static void* svc_plugin_thread_func(void* arg)
|
|||||||
|
|
||||||
DEBUG_SVC("out");
|
DEBUG_SVC("out");
|
||||||
|
|
||||||
|
ExitThread(0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -92,7 +93,7 @@ void* xf_server_thread(void* param)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
listener->Close(listener);
|
ExitThread(0);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -114,9 +115,13 @@ int freerdp_server_global_uninit()
|
|||||||
|
|
||||||
int freerdp_server_start(xfServer* server)
|
int freerdp_server_start(xfServer* server)
|
||||||
{
|
{
|
||||||
|
assert(NULL != server);
|
||||||
|
|
||||||
|
server->thread = NULL;
|
||||||
if (server->listener->Open(server->listener, NULL, 3389))
|
if (server->listener->Open(server->listener, NULL, 3389))
|
||||||
{
|
{
|
||||||
server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_server_thread, (void*) server, 0, NULL);
|
server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
|
||||||
|
xf_server_thread, (void*) server, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -124,6 +129,17 @@ int freerdp_server_start(xfServer* server)
|
|||||||
|
|
||||||
int freerdp_server_stop(xfServer* server)
|
int freerdp_server_stop(xfServer* server)
|
||||||
{
|
{
|
||||||
|
if (server->thread)
|
||||||
|
{
|
||||||
|
/* ATTENTION: Terminate thread kills a thread, assure
|
||||||
|
* no resources are allocated during thread execution,
|
||||||
|
* as they will not be freed! */
|
||||||
|
TerminateThread(server->thread, 0);
|
||||||
|
WaitForSingleObject(server->thread, INFINITE);
|
||||||
|
CloseHandle(server->thread);
|
||||||
|
|
||||||
|
server->listener->Close(server->listener);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -175,6 +176,17 @@ int xf_xshm_init(xfInfo* xfi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void xf_info_free(xfInfo *info)
|
||||||
|
{
|
||||||
|
assert(NULL != info);
|
||||||
|
|
||||||
|
if (info->display)
|
||||||
|
XCloseDisplay(info->display);
|
||||||
|
|
||||||
|
freerdp_clrconv_free(info->clrconv);
|
||||||
|
free(info);
|
||||||
|
}
|
||||||
|
|
||||||
xfInfo* xf_info_init()
|
xfInfo* xf_info_init()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -313,6 +325,11 @@ void xf_peer_context_free(freerdp_peer* client, xfPeerContext* context)
|
|||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
{
|
{
|
||||||
|
xf_info_free(context->info);
|
||||||
|
|
||||||
|
CloseHandle(context->updateReadyEvent);
|
||||||
|
CloseHandle(context->updateSentEvent);
|
||||||
|
|
||||||
Stream_Free(context->s, TRUE);
|
Stream_Free(context->s, TRUE);
|
||||||
rfx_context_free(context->rfx_context);
|
rfx_context_free(context->rfx_context);
|
||||||
}
|
}
|
||||||
@ -508,6 +525,8 @@ static void* xf_peer_main_loop(void* arg)
|
|||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
freerdp_peer* client = (freerdp_peer*) arg;
|
freerdp_peer* client = (freerdp_peer*) arg;
|
||||||
|
|
||||||
|
assert(NULL != client);
|
||||||
|
|
||||||
ZeroMemory(rfds, sizeof(rfds));
|
ZeroMemory(rfds, sizeof(rfds));
|
||||||
ZeroMemory(&timeout, sizeof(struct timeval));
|
ZeroMemory(&timeout, sizeof(struct timeval));
|
||||||
|
|
||||||
@ -598,6 +617,8 @@ static void* xf_peer_main_loop(void* arg)
|
|||||||
freerdp_peer_context_free(client);
|
freerdp_peer_context_free(client);
|
||||||
freerdp_peer_free(client);
|
freerdp_peer_free(client);
|
||||||
|
|
||||||
|
ExitThread(0);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user