Merge pull request #1460 from akallabeth/thread_handle_fixes

Thread handle fixes
This commit is contained in:
Marc-André Moreau 2013-09-16 13:40:32 -07:00
commit 336e47e82f
14 changed files with 201 additions and 40 deletions

View File

@ -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)

View File

@ -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);
} }

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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;
} }

View File

@ -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)

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }