From 51268bbcbae302f9d901568aa0f04c8f4c8c724f Mon Sep 17 00:00:00 2001 From: akallabeth Date: Thu, 7 Oct 2021 10:25:09 +0200 Subject: [PATCH] Lock updates during gdi_resize (#7330) --- libfreerdp/core/update.c | 19 ++++++++++++++----- libfreerdp/core/update.h | 3 +++ libfreerdp/gdi/gdi.c | 20 +++++++++++++++++--- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index 1dae486cf..cc65c40bb 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -2991,12 +2991,21 @@ void update_free(rdpUpdate* update) } } +void update_lock(rdpUpdate* update) +{ + WINPR_ASSERT(update); + EnterCriticalSection(&update->mux); +} + +void update_unlock(rdpUpdate* update) +{ + WINPR_ASSERT(update); + LeaveCriticalSection(&update->mux); +} + BOOL update_begin_paint(rdpUpdate* update) { - if (!update) - return FALSE; - - EnterCriticalSection(&update->mux); + update_lock(update); if (!update->BeginPaint) return TRUE; @@ -3014,6 +3023,6 @@ BOOL update_end_paint(rdpUpdate* update) if (update->EndPaint) rc = update->EndPaint(update->context); - LeaveCriticalSection(&update->mux); + update_unlock(update); return rc; } diff --git a/libfreerdp/core/update.h b/libfreerdp/core/update.h index 747a89ba1..263187554 100644 --- a/libfreerdp/core/update.h +++ b/libfreerdp/core/update.h @@ -69,4 +69,7 @@ FREERDP_LOCAL int update_process_messages(rdpUpdate* update); FREERDP_LOCAL BOOL update_begin_paint(rdpUpdate* update); FREERDP_LOCAL BOOL update_end_paint(rdpUpdate* update); +FREERDP_LOCAL void update_lock(rdpUpdate* update); +FREERDP_LOCAL void update_unlock(rdpUpdate* update); + #endif /* FREERDP_LIB_CORE_UPDATE_H */ diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index f9b697255..c75980cf6 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -45,6 +46,7 @@ #include "line.h" #include "gdi.h" #include "../core/graphics.h" +#include "../core/update.h" #define TAG FREERDP_TAG("gdi") @@ -1156,8 +1158,14 @@ static void gdi_register_update_callbacks(rdpUpdate* update) } static BOOL gdi_init_primary(rdpGdi* gdi, UINT32 stride, UINT32 format, BYTE* buffer, - void (*pfree)(void*)) + void (*pfree)(void*), BOOL isLocked) { + WINPR_ASSERT(gdi); + WINPR_ASSERT(gdi->context); + WINPR_ASSERT(gdi->context->update); + if (!isLocked) + update_lock(gdi->context->update); + gdi->primary = (gdiBitmap*)calloc(1, sizeof(gdiBitmap)); if (format > 0) @@ -1210,6 +1218,7 @@ static BOOL gdi_init_primary(rdpGdi* gdi, UINT32 stride, UINT32 format, BYTE* bu if (!gdi->drawing) gdi->drawing = gdi->primary; + update_unlock(gdi->context->update); return TRUE; fail_hwnd: gdi_DeleteObject((HGDIOBJECT)gdi->primary->bitmap); @@ -1219,6 +1228,7 @@ fail_hdc: free(gdi->primary); gdi->primary = NULL; fail_primary: + update_unlock(gdi->context->update); return FALSE; } @@ -1240,6 +1250,10 @@ BOOL gdi_resize_ex(rdpGdi* gdi, UINT32 width, UINT32 height, UINT32 stride, UINT (!buffer || (gdi->primary_buffer == buffer))) return TRUE; + WINPR_ASSERT(gdi->context); + WINPR_ASSERT(gdi->context->update); + update_lock(gdi->context->update); + if (gdi->drawing == gdi->primary) gdi->drawing = NULL; @@ -1248,7 +1262,7 @@ BOOL gdi_resize_ex(rdpGdi* gdi, UINT32 width, UINT32 height, UINT32 stride, UINT gdi_bitmap_free_ex(gdi->primary); gdi->primary = NULL; gdi->primary_buffer = NULL; - return gdi_init_primary(gdi, stride, format, buffer, pfree); + return gdi_init_primary(gdi, stride, format, buffer, pfree, TRUE); } /** @@ -1292,7 +1306,7 @@ BOOL gdi_init_ex(freerdp* instance, UINT32 format, UINT32 stride, BYTE* buffer, gdi->hdc->format = gdi->dstFormat; - if (!gdi_init_primary(gdi, stride, gdi->dstFormat, buffer, pfree)) + if (!gdi_init_primary(gdi, stride, gdi->dstFormat, buffer, pfree, FALSE)) goto fail; if (!(context->cache = cache_new(instance->context)))