From 7467f599b936bef3524a246e4ce1f949dffd648c Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 31 May 2021 10:08:50 +0200 Subject: [PATCH 1/3] Stop rdpei thread before cleaning up listener --- channels/rdpei/client/rdpei_main.c | 35 ++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/channels/rdpei/client/rdpei_main.c b/channels/rdpei/client/rdpei_main.c index f9fe6fa67..9621900a7 100644 --- a/channels/rdpei/client/rdpei_main.c +++ b/channels/rdpei/client/rdpei_main.c @@ -368,6 +368,9 @@ static UINT rdpei_send_pen_frame(RdpeiClientContext* context, RDPINPUT_PEN_FRAME return ERROR_INTERNAL_ERROR; callback = rdpei->listener_callback->channel_callback; + /* Just ignore the event if the channel is not connected */ + if (!callback) + return CHANNEL_RC_OK; if (!rdpei->previousPenFrameTime && !rdpei->currentPenFrameTime) { @@ -872,6 +875,15 @@ static UINT rdpei_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, static UINT rdpei_on_close(IWTSVirtualChannelCallback* pChannelCallback) { RDPEI_CHANNEL_CALLBACK* callback = (RDPEI_CHANNEL_CALLBACK*)pChannelCallback; + if (callback) + { + RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*)callback->plugin; + if (rdpei && rdpei->listener_callback) + { + if (rdpei->listener_callback->channel_callback == callback) + rdpei->listener_callback->channel_callback = NULL; + } + } free(callback); return CHANNEL_RC_OK; } @@ -922,11 +934,9 @@ static UINT rdpei_plugin_terminated(IWTSPlugin* pPlugin) if (!pPlugin) return ERROR_INVALID_PARAMETER; - if (rdpei && rdpei->listener_callback) + if (rdpei) { - IWTSVirtualChannelManager* mgr = rdpei->listener_callback->channel_mgr; - if (mgr) - IFCALL(mgr->DestroyListener, mgr, rdpei->listener); + IWTSVirtualChannelManager* mgr = NULL; rdpei->initialized = FALSE; if (rdpei->event) @@ -939,6 +949,12 @@ static UINT rdpei_plugin_terminated(IWTSPlugin* pPlugin) } if (rdpei->event) CloseHandle(rdpei->event); + + if (rdpei->listener_callback) + mgr = rdpei->listener_callback->channel_mgr; + + if (mgr) + IFCALL(mgr->DestroyListener, mgr, rdpei->listener); } DeleteCriticalSection(&rdpei->lock); free(rdpei->listener_callback); @@ -1026,11 +1042,16 @@ static UINT32 rdpei_get_features(RdpeiClientContext* context) */ UINT rdpei_send_frame(RdpeiClientContext* context, RDPINPUT_TOUCH_FRAME* frame) { - UINT64 currentTime; + UINT64 currentTime = GetTickCount64(); RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*)context->handle; - RDPEI_CHANNEL_CALLBACK* callback = rdpei->listener_callback->channel_callback; + RDPEI_CHANNEL_CALLBACK* callback; UINT error; - currentTime = GetTickCount64(); + + callback = rdpei->listener_callback->channel_callback; + + /* Just ignore the event if the channel is not connected */ + if (!callback) + return CHANNEL_RC_OK; if (!rdpei->previousFrameTime && !rdpei->currentFrameTime) { From d4b326786053ebd338caa9b0ac169bafb53b24d9 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 31 May 2021 12:26:30 +0200 Subject: [PATCH 2/3] Make TestSynchBarrier verbose --- winpr/libwinpr/synch/test/TestSynchBarrier.c | 33 +++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/winpr/libwinpr/synch/test/TestSynchBarrier.c b/winpr/libwinpr/synch/test/TestSynchBarrier.c index d5f7edf68..bcca908dc 100644 --- a/winpr/libwinpr/synch/test/TestSynchBarrier.c +++ b/winpr/libwinpr/synch/test/TestSynchBarrier.c @@ -182,6 +182,10 @@ int TestSynchBarrier(int argc, char* argv[]) DWORD dwMaxThreads; DWORD dwMinThreads; DWORD dwNumLoops = 200; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + GetNativeSystemInfo(&sysinfo); printf("%s: Number of processors: %" PRIu32 "\n", __FUNCTION__, sysinfo.dwNumberOfProcessors); dwMinThreads = sysinfo.dwNumberOfProcessors; @@ -193,7 +197,8 @@ int TestSynchBarrier(int argc, char* argv[]) /* Test invalid parameters */ if (InitializeSynchronizationBarrier(&gBarrier, 0, -1)) { - printf( + fprintf( + stderr, "%s: InitializeSynchronizationBarrier unecpectedly succeeded with lTotalThreads = 0\n", __FUNCTION__); return -1; @@ -201,7 +206,8 @@ int TestSynchBarrier(int argc, char* argv[]) if (InitializeSynchronizationBarrier(&gBarrier, -1, -1)) { - printf( + fprintf( + stderr, "%s: InitializeSynchronizationBarrier unecpectedly succeeded with lTotalThreads = -1\n", __FUNCTION__); return -1; @@ -209,23 +215,42 @@ int TestSynchBarrier(int argc, char* argv[]) if (InitializeSynchronizationBarrier(&gBarrier, 1, -2)) { - printf("%s: InitializeSynchronizationBarrier unecpectedly succeeded with lSpinCount = -2\n", - __FUNCTION__); + fprintf( + stderr, + "%s: InitializeSynchronizationBarrier unecpectedly succeeded with lSpinCount = -2\n", + __FUNCTION__); return -1; } /* Functional tests */ if (!TestSynchBarrierWithFlags(0, dwMaxThreads, dwNumLoops)) + { + fprintf(stderr, + "%s: TestSynchBarrierWithFlags(0) unecpectedly succeeded with lTotalThreads = -1\n", + __FUNCTION__); return -1; + } if (!TestSynchBarrierWithFlags(SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY, dwMinThreads, dwNumLoops)) + { + fprintf(stderr, + "%s: TestSynchBarrierWithFlags(SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY) " + "unecpectedly succeeded with lTotalThreads = -1\n", + __FUNCTION__); return -1; + } if (!TestSynchBarrierWithFlags(SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY, dwMaxThreads, dwNumLoops)) + { + fprintf(stderr, + "%s: TestSynchBarrierWithFlags(SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY) " + "unecpectedly succeeded with lTotalThreads = -1\n", + __FUNCTION__); return -1; + } printf("%s: Test successfully completed\n", __FUNCTION__); return 0; From a2930c04c3bace08e52d3c6ec9f38529e2980858 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 31 May 2021 12:29:16 +0200 Subject: [PATCH 3/3] Fixed random sleep time for test_synch_barrier_thread --- winpr/libwinpr/synch/test/TestSynchBarrier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winpr/libwinpr/synch/test/TestSynchBarrier.c b/winpr/libwinpr/synch/test/TestSynchBarrier.c index bcca908dc..b864b4412 100644 --- a/winpr/libwinpr/synch/test/TestSynchBarrier.c +++ b/winpr/libwinpr/synch/test/TestSynchBarrier.c @@ -44,7 +44,7 @@ static DWORD WINAPI test_synch_barrier_thread(LPVOID lpParam) for (i = 0; i < p->loops && gErrorCount == 0; i++) { /* simulate different execution times before the barrier */ - Sleep(rand() % MAX_SLEEP_MS); + Sleep(1 + abs((rand() % MAX_SLEEP_MS))); status = EnterSynchronizationBarrier(&gBarrier, p->flags); // printf("Thread #%03u status: %s\n", tnum, status ? "TRUE" : "FALSE");