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);
|
||||
WaitForSingleObject(audin->thread, INFINITE);
|
||||
CloseHandle(audin->thread);
|
||||
CloseHandle(audin->stopEvent);
|
||||
audin->thread = NULL;
|
||||
audin->stopEvent = NULL;
|
||||
}
|
||||
|
||||
if (audin->audin_channel)
|
||||
|
@ -631,8 +631,9 @@ FREERDP_API int freerdp_channels_send_event(rdpChannels* channels, wMessage* eve
|
||||
/**
|
||||
* 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* event;
|
||||
rdpChannel* channel;
|
||||
@ -642,7 +643,10 @@ static void freerdp_channels_process_sync(rdpChannels* channels, freerdp* instan
|
||||
while (MessageQueue_Peek(channels->MsgPipe->Out, &message, TRUE))
|
||||
{
|
||||
if (message.id == WMQ_QUIT)
|
||||
{
|
||||
rc = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
freerdp_channels_process_sync(channels, instance);
|
||||
return freerdp_channels_process_sync(channels, instance);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -782,4 +788,7 @@ void freerdp_channels_close(rdpChannels* channels, freerdp* instance)
|
||||
if (pChannelClientData->pChannelInitEventProc)
|
||||
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)
|
||||
{
|
||||
DRIVE_DEVICE* disk = (DRIVE_DEVICE*) arg;
|
||||
HANDLE hdl[] = {disk->irpEvent, disk->stopEvent};
|
||||
|
||||
while (1)
|
||||
{
|
||||
WaitForSingleObject(disk->irpEvent, INFINITE);
|
||||
|
||||
if (WaitForSingleObject(disk->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
DWORD rc = WaitForMultipleObjects(2, hdl, FALSE, INFINITE);
|
||||
if (rc == WAIT_OBJECT_0 + 1)
|
||||
break;
|
||||
|
||||
ResetEvent(disk->irpEvent);
|
||||
drive_process_irp_list(disk);
|
||||
}
|
||||
ExitThread(0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -664,8 +665,10 @@ static void drive_free(DEVICE* device)
|
||||
DRIVE_DEVICE* disk = (DRIVE_DEVICE*) device;
|
||||
|
||||
SetEvent(disk->stopEvent);
|
||||
WaitForSingleObject(disk->thread, INFINITE);
|
||||
CloseHandle(disk->thread);
|
||||
CloseHandle(disk->irpEvent);
|
||||
CloseHandle(disk->stopEvent);
|
||||
|
||||
while ((irp = (IRP*) InterlockedPopEntrySList(disk->pIrpList)) != NULL)
|
||||
irp->Discard(irp);
|
||||
|
@ -200,6 +200,8 @@ static void* printer_thread_func(void* arg)
|
||||
printer_process_irp(printer_dev, irp);
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -219,11 +221,14 @@ static void printer_free(DEVICE* device)
|
||||
|
||||
SetEvent(printer_dev->stopEvent);
|
||||
WaitForSingleObject(printer_dev->thread, INFINITE);
|
||||
CloseHandle(printer_dev->thread);
|
||||
|
||||
while ((irp = (IRP*) InterlockedPopEntrySList(printer_dev->pIrpList)) != NULL)
|
||||
irp->Discard(irp);
|
||||
|
||||
CloseHandle(printer_dev->thread);
|
||||
CloseHandle(printer_dev->stopEvent);
|
||||
CloseHandle(printer_dev->event);
|
||||
|
||||
_aligned_free(printer_dev->pIrpList);
|
||||
|
||||
if (printer_dev->printer)
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -97,6 +98,7 @@ struct _RDPEI_PLUGIN
|
||||
RDPINPUT_CONTACT_POINT* contactPoints;
|
||||
|
||||
HANDLE event;
|
||||
HANDLE stopEvent;
|
||||
HANDLE thread;
|
||||
|
||||
CRITICAL_SECTION lock;
|
||||
@ -156,10 +158,16 @@ static void* rdpei_schedule_thread(void* arg)
|
||||
DWORD status;
|
||||
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) arg;
|
||||
RdpeiClientContext* context = (RdpeiClientContext*) rdpei->iface.pInterface;
|
||||
HANDLE hdl[] = {rdpei->event, rdpei->stopEvent};
|
||||
|
||||
assert(NULL != rdpei);
|
||||
assert(NULL != context);
|
||||
|
||||
while (1)
|
||||
{
|
||||
status = WaitForSingleObject(rdpei->event, 20);
|
||||
status = WaitForMultipleObjects(2, hdl, FALSE, 20);
|
||||
if (status == WAIT_OBJECT_0 + 1)
|
||||
break;
|
||||
|
||||
EnterCriticalSection(&rdpei->lock);
|
||||
|
||||
@ -174,6 +182,8 @@ static void* rdpei_schedule_thread(void* arg)
|
||||
LeaveCriticalSection(&rdpei->lock);
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -218,13 +228,6 @@ int rdpei_send_cs_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback)
|
||||
|
||||
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);
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
@ -488,6 +491,12 @@ static int rdpei_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -497,6 +506,22 @@ static int rdpei_plugin_terminated(IWTSPlugin* pPlugin)
|
||||
|
||||
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);
|
||||
|
||||
return 0;
|
||||
|
@ -541,6 +541,9 @@ void rdpsnd_server_context_free(rdpsnd_server_context* context)
|
||||
SetEvent(rdpsnd->StopEvent);
|
||||
WaitForSingleObject(rdpsnd->thread, INFINITE);
|
||||
|
||||
CloseHandle(rdpsnd->StopEvent);
|
||||
CloseHandle(rdpsnd->thread);
|
||||
|
||||
if (rdpsnd->rdpsnd_channel)
|
||||
WTSVirtualChannelClose(rdpsnd->rdpsnd_channel);
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -346,6 +347,7 @@ void* serial_thread_mfunc(void* arg)
|
||||
{
|
||||
SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg;
|
||||
|
||||
assert(NULL != serial);
|
||||
while(1)
|
||||
{
|
||||
int sl;
|
||||
@ -366,6 +368,7 @@ void* serial_thread_mfunc(void* arg)
|
||||
}
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -376,6 +379,7 @@ static void* serial_thread_func(void* arg)
|
||||
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);
|
||||
@ -401,6 +405,7 @@ static void* serial_thread_func(void* arg)
|
||||
serial_check_fds(serial);
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -112,13 +112,16 @@ struct _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);
|
||||
|
||||
CloseHandle(irpWorker->thread);
|
||||
|
||||
free(irpWorker);
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* smartcard_thread_func(void* arg)
|
||||
|
@ -569,7 +569,10 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
|
||||
rdpChannels* channels;
|
||||
|
||||
instance = (freerdp*) lpParam;
|
||||
assert(NULL != instance);
|
||||
|
||||
wfc = (wfContext*) instance->context;
|
||||
assert(NULL != wfc);
|
||||
|
||||
ZeroMemory(rfds, sizeof(rfds));
|
||||
ZeroMemory(wfds, sizeof(wfds));
|
||||
@ -690,13 +693,13 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
wfc->mainThreadId = 0;
|
||||
|
||||
freerdp_channels_close(channels, instance);
|
||||
freerdp_disconnect(instance);
|
||||
|
||||
printf("Main thread exited.\n");
|
||||
|
||||
ExitThread(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -708,6 +711,7 @@ DWORD WINAPI wf_keyboard_thread(LPVOID lpParam)
|
||||
HHOOK hook_handle;
|
||||
|
||||
wfc = (wfContext*) lpParam;
|
||||
assert(NULL != wfc);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
wfc->keyboardThreadId = 0;
|
||||
printf("Keyboard thread exited.\n");
|
||||
|
||||
ExitThread(0);
|
||||
return (DWORD) NULL;
|
||||
}
|
||||
|
||||
@ -1078,12 +1082,27 @@ int wfreerdp_client_stop(rdpContext* context)
|
||||
{
|
||||
wfContext* wfc = (wfContext*) context;
|
||||
|
||||
if (wfc->mainThreadId)
|
||||
if (wfc->thread)
|
||||
{
|
||||
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);
|
||||
|
||||
WaitForSingleObject(wfc->keyboardThread, INFINITE);
|
||||
CloseHandle(wfc->keyboardThread);
|
||||
|
||||
wfc->keyboardThread = NULL;
|
||||
wfc->keyboardThreadId = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -773,12 +773,12 @@ BOOL xf_pre_connect(freerdp* instance)
|
||||
if (settings->Username == NULL)
|
||||
{
|
||||
fprintf(stderr, "--authonly, but no -u username. Please provide one.\n");
|
||||
exit(1);
|
||||
return FALSE;
|
||||
}
|
||||
if (settings->Password == NULL)
|
||||
{
|
||||
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__);
|
||||
/* Avoid XWindows initialization and configuration below. */
|
||||
@ -1224,6 +1224,8 @@ void* xf_update_thread(void* arg)
|
||||
wMessageQueue* queue;
|
||||
freerdp* instance = (freerdp*) arg;
|
||||
|
||||
assert( NULL != instance);
|
||||
|
||||
status = 1;
|
||||
queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||
|
||||
@ -1241,6 +1243,7 @@ void* xf_update_thread(void* arg)
|
||||
break;
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1253,9 +1256,12 @@ void* xf_input_thread(void* arg)
|
||||
int pending_status = 1;
|
||||
int process_status = 1;
|
||||
freerdp* instance = (freerdp*) arg;
|
||||
assert(NULL != instance);
|
||||
|
||||
xfc = (xfContext*) instance->context;
|
||||
assert(NULL != xfc);
|
||||
|
||||
queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||
event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds);
|
||||
|
||||
while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
|
||||
@ -1288,9 +1294,8 @@ void* xf_input_thread(void* arg)
|
||||
break;
|
||||
}
|
||||
|
||||
queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||
MessageQueue_PostQuit(queue, 0);
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1301,8 +1306,10 @@ void* xf_channels_thread(void* arg)
|
||||
HANDLE event;
|
||||
rdpChannels* channels;
|
||||
freerdp* instance = (freerdp*) arg;
|
||||
assert(NULL != instance);
|
||||
|
||||
xfc = (xfContext*) instance->context;
|
||||
assert(NULL != xfc);
|
||||
|
||||
channels = instance->context->channels;
|
||||
event = freerdp_channels_get_event_handle(instance);
|
||||
@ -1310,9 +1317,13 @@ void* xf_channels_thread(void* arg)
|
||||
while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
|
||||
{
|
||||
status = freerdp_channels_process_pending_messages(instance);
|
||||
if (!status)
|
||||
break;
|
||||
|
||||
xf_process_channel_event(channels, instance);
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1356,6 +1367,7 @@ void* xf_thread(void* param)
|
||||
input_event = NULL;
|
||||
|
||||
instance = (freerdp*) param;
|
||||
assert(NULL != instance);
|
||||
|
||||
ZeroMemory(rfds, sizeof(rfds));
|
||||
ZeroMemory(wfds, sizeof(wfds));
|
||||
@ -1364,6 +1376,7 @@ void* xf_thread(void* param)
|
||||
status = freerdp_connect(instance);
|
||||
|
||||
xfc = (xfContext*) instance->context;
|
||||
assert(NULL != xfc);
|
||||
|
||||
/* Connection succeeded. --authonly ? */
|
||||
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)
|
||||
{
|
||||
wMessageQueue* update_queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||
@ -1541,6 +1558,20 @@ void* xf_thread(void* param)
|
||||
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");
|
||||
|
||||
if (fin)
|
||||
@ -1577,7 +1608,6 @@ void* xf_thread(void* param)
|
||||
if (!exit_code)
|
||||
exit_code = freerdp_error_info(instance);
|
||||
|
||||
freerdp_channels_close(channels, instance);
|
||||
freerdp_channels_free(channels);
|
||||
freerdp_disconnect(instance);
|
||||
gdi_free(instance);
|
||||
@ -1713,7 +1743,8 @@ static int xfreerdp_client_start(rdpContext* context)
|
||||
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;
|
||||
}
|
||||
@ -1722,6 +1753,7 @@ static int xfreerdp_client_stop(rdpContext* context)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
assert(NULL != context);
|
||||
if (context->settings->AsyncInput)
|
||||
{
|
||||
wMessageQueue* queue;
|
||||
@ -1735,8 +1767,11 @@ static int xfreerdp_client_stop(rdpContext* context)
|
||||
xfc->disconnect = TRUE;
|
||||
}
|
||||
|
||||
WaitForSingleObject(xfc->thread, INFINITE);
|
||||
if (xfc->thread)
|
||||
{
|
||||
CloseHandle(xfc->thread);
|
||||
xfc->thread = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -85,6 +86,14 @@ BOOL transport_disconnect(rdpTransport* transport)
|
||||
status &= tcp_disconnect(transport->TcpIn);
|
||||
}
|
||||
|
||||
if (transport->async)
|
||||
{
|
||||
SetEvent(transport->stopEvent);
|
||||
WaitForSingleObject(transport->thread, INFINITE);
|
||||
|
||||
CloseHandle(transport->thread);
|
||||
CloseHandle(transport->stopEvent);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -793,8 +802,14 @@ static void* transport_client_thread(void* arg)
|
||||
rdpTransport* transport;
|
||||
|
||||
transport = (rdpTransport*) arg;
|
||||
assert(NULL != transport);
|
||||
assert(NULL != transport->settings);
|
||||
|
||||
instance = (freerdp*) transport->settings->instance;
|
||||
assert(NULL != instance);
|
||||
|
||||
context = instance->context;
|
||||
assert(NULL != instance->context);
|
||||
|
||||
while (1)
|
||||
{
|
||||
@ -803,25 +818,20 @@ static void* transport_client_thread(void* arg)
|
||||
events[nCount] = transport->connectedEvent;
|
||||
|
||||
status = WaitForMultipleObjects(nCount + 1, events, FALSE, INFINITE);
|
||||
|
||||
if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
if (status == WAIT_OBJECT_0)
|
||||
break;
|
||||
}
|
||||
|
||||
transport_get_read_handles(transport, (HANDLE*) &events, &nCount);
|
||||
|
||||
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
|
||||
|
||||
if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
if (status == WAIT_OBJECT_0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!freerdp_check_fds(instance))
|
||||
break;
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -185,6 +186,8 @@ static void* svc_plugin_thread_func(void* arg)
|
||||
|
||||
DEBUG_SVC("in");
|
||||
|
||||
assert(NULL != plugin);
|
||||
|
||||
IFCALL(plugin->connect_callback, plugin);
|
||||
|
||||
while (1)
|
||||
@ -212,6 +215,8 @@ static void* svc_plugin_thread_func(void* arg)
|
||||
|
||||
DEBUG_SVC("out");
|
||||
|
||||
ExitThread(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -92,7 +93,7 @@ void* xf_server_thread(void* param)
|
||||
}
|
||||
}
|
||||
|
||||
listener->Close(listener);
|
||||
ExitThread(0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -114,9 +115,13 @@ int freerdp_server_global_uninit()
|
||||
|
||||
int freerdp_server_start(xfServer* server)
|
||||
{
|
||||
assert(NULL != server);
|
||||
|
||||
server->thread = NULL;
|
||||
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;
|
||||
@ -124,6 +129,17 @@ int freerdp_server_start(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;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -175,6 +176,17 @@ int xf_xshm_init(xfInfo* xfi)
|
||||
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()
|
||||
{
|
||||
int i;
|
||||
@ -313,6 +325,11 @@ void xf_peer_context_free(freerdp_peer* client, xfPeerContext* context)
|
||||
{
|
||||
if (context)
|
||||
{
|
||||
xf_info_free(context->info);
|
||||
|
||||
CloseHandle(context->updateReadyEvent);
|
||||
CloseHandle(context->updateSentEvent);
|
||||
|
||||
Stream_Free(context->s, TRUE);
|
||||
rfx_context_free(context->rfx_context);
|
||||
}
|
||||
@ -508,6 +525,8 @@ static void* xf_peer_main_loop(void* arg)
|
||||
struct timeval timeout;
|
||||
freerdp_peer* client = (freerdp_peer*) arg;
|
||||
|
||||
assert(NULL != client);
|
||||
|
||||
ZeroMemory(rfds, sizeof(rfds));
|
||||
ZeroMemory(&timeout, sizeof(struct timeval));
|
||||
|
||||
@ -598,6 +617,8 @@ static void* xf_peer_main_loop(void* arg)
|
||||
freerdp_peer_context_free(client);
|
||||
freerdp_peer_free(client);
|
||||
|
||||
ExitThread(0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user