- serial: terminates IRP threads more gracefully and avoiding warning messages.
This commit is contained in:
parent
b889ad7125
commit
1aeca8fbc7
@ -50,6 +50,8 @@
|
|||||||
#include <winpr/thread.h>
|
#include <winpr/thread.h>
|
||||||
#include <winpr/wlog.h>
|
#include <winpr/wlog.h>
|
||||||
|
|
||||||
|
#include <winpr/wlog.h>
|
||||||
|
|
||||||
#include <freerdp/freerdp.h>
|
#include <freerdp/freerdp.h>
|
||||||
#include <freerdp/utils/list.h>
|
#include <freerdp/utils/list.h>
|
||||||
#include <freerdp/channels/rdpdr.h>
|
#include <freerdp/channels/rdpdr.h>
|
||||||
@ -696,6 +698,35 @@ static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void terminate_pending_irp_threads(SERIAL_DEVICE *serial)
|
||||||
|
{
|
||||||
|
ULONG_PTR *ids;
|
||||||
|
int i, nbIds;
|
||||||
|
|
||||||
|
nbIds = ListDictionary_GetKeys(serial->IrpThreads, &ids);
|
||||||
|
|
||||||
|
DEBUG_SVC("Terminating %d IRP thread(s)", nbIds);
|
||||||
|
|
||||||
|
for (i=0; i<nbIds; i++)
|
||||||
|
{
|
||||||
|
HANDLE irpThread;
|
||||||
|
ULONG_PTR id = ids[i];
|
||||||
|
|
||||||
|
irpThread = ListDictionary_GetItemValue(serial->IrpThreads, (void*)id);
|
||||||
|
|
||||||
|
TerminateThread(irpThread, 0);
|
||||||
|
|
||||||
|
WaitForSingleObject(irpThread, INFINITE);
|
||||||
|
|
||||||
|
CloseHandle(irpThread);
|
||||||
|
|
||||||
|
DEBUG_SVC("IRP thread terminated, CompletionId %d", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
ListDictionary_Clear(serial->IrpThreads);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void* serial_thread_func(void* arg)
|
static void* serial_thread_func(void* arg)
|
||||||
{
|
{
|
||||||
IRP* irp;
|
IRP* irp;
|
||||||
@ -711,7 +742,10 @@ static void* serial_thread_func(void* arg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (message.id == WMQ_QUIT)
|
if (message.id == WMQ_QUIT)
|
||||||
|
{
|
||||||
|
terminate_pending_irp_threads(serial);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
irp = (IRP*) message.wParam;
|
irp = (IRP*) message.wParam;
|
||||||
|
|
||||||
@ -748,7 +782,7 @@ static void serial_free(DEVICE* device)
|
|||||||
WLog_Print(serial->log, WLOG_DEBUG, "freeing");
|
WLog_Print(serial->log, WLOG_DEBUG, "freeing");
|
||||||
|
|
||||||
MessageQueue_PostQuit(serial->MainIrpQueue, 0);
|
MessageQueue_PostQuit(serial->MainIrpQueue, 0);
|
||||||
WaitForSingleObject(serial->MainThread, INFINITE); /* FIXME: might likely block on a pending Write or ioctl */
|
WaitForSingleObject(serial->MainThread, INFINITE);
|
||||||
CloseHandle(serial->MainThread);
|
CloseHandle(serial->MainThread);
|
||||||
|
|
||||||
if (serial->hComm)
|
if (serial->hComm)
|
||||||
|
@ -74,7 +74,8 @@ typedef struct winpr_comm WINPR_COMM;
|
|||||||
void _comm_setRemoteSerialDriver(HANDLE hComm, REMOTE_SERIAL_DRIVER_ID);
|
void _comm_setRemoteSerialDriver(HANDLE hComm, REMOTE_SERIAL_DRIVER_ID);
|
||||||
|
|
||||||
/* TMP: TODO: move all specific defines and types here? at least SERIAL_EV_* */
|
/* TMP: TODO: move all specific defines and types here? at least SERIAL_EV_* */
|
||||||
#define SERIAL_EV_FREERDP_STOP 0x8000 /* bit unused by SERIAL_EV_* */
|
#define SERIAL_EV_FREERDP_STOP 0x4000 /* bit unused by SERIAL_EV_* */
|
||||||
|
#define SERIAL_EV_FREERDP_CLOSING 0x8000 /* bit unused by SERIAL_EV_* */
|
||||||
|
|
||||||
|
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
@ -1016,6 +1016,11 @@ static BOOL _set_wait_mask(WINPR_COMM *pComm, const ULONG *pWaitMask)
|
|||||||
/* NB: ensure to leave the critical section before to return */
|
/* NB: ensure to leave the critical section before to return */
|
||||||
EnterCriticalSection(&pComm->EventsLock);
|
EnterCriticalSection(&pComm->EventsLock);
|
||||||
|
|
||||||
|
if (pComm->PendingEvents |= SERIAL_EV_FREERDP_CLOSING)
|
||||||
|
{
|
||||||
|
return TRUE; /* returns without complaining */
|
||||||
|
}
|
||||||
|
|
||||||
if (*pWaitMask == 0)
|
if (*pWaitMask == 0)
|
||||||
{
|
{
|
||||||
/* clearing pending events */
|
/* clearing pending events */
|
||||||
@ -1165,6 +1170,11 @@ static BOOL _get_commstatus(WINPR_COMM *pComm, SERIAL_STATUS *pCommstatus)
|
|||||||
/* NB: ensure to leave the critical section before to return */
|
/* NB: ensure to leave the critical section before to return */
|
||||||
EnterCriticalSection(&pComm->EventsLock);
|
EnterCriticalSection(&pComm->EventsLock);
|
||||||
|
|
||||||
|
if (pComm->PendingEvents & SERIAL_EV_FREERDP_CLOSING)
|
||||||
|
{
|
||||||
|
return TRUE; /* returns without complaining */
|
||||||
|
}
|
||||||
|
|
||||||
ZeroMemory(pCommstatus, sizeof(SERIAL_STATUS));
|
ZeroMemory(pCommstatus, sizeof(SERIAL_STATUS));
|
||||||
|
|
||||||
ZeroMemory(¤tCounters, sizeof(struct serial_icounter_struct));
|
ZeroMemory(¤tCounters, sizeof(struct serial_icounter_struct));
|
||||||
@ -1341,6 +1351,11 @@ static BOOL _wait_on_mask(WINPR_COMM *pComm, ULONG *pOutputMask)
|
|||||||
|
|
||||||
/* NB: ensure to leave the critical section before to return */
|
/* NB: ensure to leave the critical section before to return */
|
||||||
EnterCriticalSection(&pComm->EventsLock);
|
EnterCriticalSection(&pComm->EventsLock);
|
||||||
|
|
||||||
|
if (pComm->PendingEvents & SERIAL_EV_FREERDP_CLOSING)
|
||||||
|
{
|
||||||
|
return TRUE; /* returns without complaining */
|
||||||
|
}
|
||||||
|
|
||||||
if (pComm->PendingEvents & SERIAL_EV_FREERDP_STOP)
|
if (pComm->PendingEvents & SERIAL_EV_FREERDP_STOP)
|
||||||
{
|
{
|
||||||
|
@ -203,19 +203,19 @@ BOOL CloseHandle(HANDLE hObject)
|
|||||||
|
|
||||||
comm = (WINPR_COMM*) Object;
|
comm = (WINPR_COMM*) Object;
|
||||||
|
|
||||||
if (comm->fd > 0)
|
|
||||||
close(comm->fd);
|
|
||||||
|
|
||||||
/* NOTE: This is up to the caller of CloseHandle() to
|
/* NOTE: This is up to the caller of CloseHandle() to
|
||||||
* ensure there is no pending request. Sending
|
* ensure there is no pending request. Sending
|
||||||
* SERIAL_EV_FREERDP_STOP anyway. Remove this code if
|
* SERIAL_EV_FREERDP_STOP anyway. Remove this code if
|
||||||
* you think otherwise. */
|
* you think otherwise. */
|
||||||
EnterCriticalSection(&comm->EventsLock);
|
EnterCriticalSection(&comm->EventsLock);
|
||||||
comm->PendingEvents |= SERIAL_EV_FREERDP_STOP;
|
comm->PendingEvents |= SERIAL_EV_FREERDP_CLOSING;
|
||||||
LeaveCriticalSection(&comm->EventsLock);
|
LeaveCriticalSection(&comm->EventsLock);
|
||||||
|
|
||||||
DeleteCriticalSection(&comm->EventsLock);
|
DeleteCriticalSection(&comm->EventsLock);
|
||||||
|
|
||||||
|
if (comm->fd > 0)
|
||||||
|
close(comm->fd);
|
||||||
|
|
||||||
free(comm);
|
free(comm);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
Loading…
Reference in New Issue
Block a user